chbs-0.1.1/.cargo_vcs_info.json0000644000000001360000000000100117520ustar { "git": { "sha1": "5236e5537be2bf51ae638c2fb145967c6f524f70" }, "path_in_vcs": "" }chbs-0.1.1/.github/FUNDING.yml000064400000000000000000000001610072674642500137450ustar 00000000000000# Funding links github: - timvisee custom: - "https://timvisee.com/donate" patreon: timvisee ko_fi: timvisee chbs-0.1.1/.github/dependabot.yml000064400000000000000000000002210072674642500147550ustar 00000000000000version: 2 updates: - package-ecosystem: cargo directory: "/" schedule: interval: daily time: "04:00" open-pull-requests-limit: 10 chbs-0.1.1/.gitignore000064400000000000000000000000660072674642500125640ustar 00000000000000/target **/*.rs.bk Cargo.lock # Vim files .*.sw[pon] chbs-0.1.1/.gitlab-ci.yml000064400000000000000000000024560072674642500132350ustar 00000000000000image: "rust:slim" stages: - check - build - release # Variable defaults variables: RUST_VERSION: stable # Install the proper Rust compiler version before_script: - | rustup install $RUST_VERSION rustup default $RUST_VERSION - | rustc --version cargo --version # Check on stable, beta and nightly .check-base: &check-base stage: check script: - cargo check --verbose - cargo test --verbose check-stable: <<: *check-base check-beta: <<: *check-base variables: RUST_VERSION: beta check-nightly: <<: *check-base variables: RUST_VERSION: nightly check-old: <<: *check-base variables: RUST_VERSION: "1.42.0" check-macos-stable: tags: - macos only: - master - /^v(\d+\.)*\d+$/ <<: *check-base # Build using Rust stable build: stage: build script: - cargo build --release --verbose # Build using Rust stable on macOS build-macos: stage: build tags: - macos only: - master - /^v(\d+\.)*\d+$/ needs: [] script: - cargo build --release --verbose # Cargo crate release crate: stage: release only: - /^v(\d+\.)*\d+$/ script: - echo "Creating release crate to publish on crates.io..." - echo $CARGO_TOKEN | cargo login - echo "Publishing crate to crates.io..." - cargo publish --verbose chbs-0.1.1/Cargo.lock0000644000000170060000000000100077310ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "bumpalo" version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chbs" version = "0.1.1" dependencies = [ "derive_builder", "getrandom", "rand", "thiserror", ] [[package]] name = "darling" version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f2c43f534ea4b0b049015d00269734195e6d3f0f6635cb692251aca6f9f8b3c" dependencies = [ "darling_core", "darling_macro", ] [[package]] name = "darling_core" version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", "syn", ] [[package]] name = "darling_macro" version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a" dependencies = [ "darling_core", "quote", "syn", ] [[package]] name = "derive_builder" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d13202debe11181040ae9063d739fa32cfcaaebe2275fe387703460ae2365b30" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66e616858f6187ed828df7c64a6d71720d83767a7f19740b2d1b6fe6327b36e5" dependencies = [ "darling", "proc-macro2", "quote", "syn", ] [[package]] name = "derive_builder_macro" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58a94ace95092c5acb1e97a7e846b310cfbd499652f72297da7493f618a98d73" dependencies = [ "derive_builder_core", "syn", ] [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "getrandom" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if", "js-sys", "libc", "wasi", "wasm-bindgen", ] [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "js-sys" version = "0.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" dependencies = [ "wasm-bindgen", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "log" version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] [[package]] name = "ppv-lite86" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" dependencies = [ "proc-macro2", ] [[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core", ] [[package]] name = "rand_chacha" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ "getrandom", ] [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "thiserror" version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "unicode-ident" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" dependencies = [ "cfg-if", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" dependencies = [ "bumpalo", "lazy_static", "log", "proc-macro2", "quote", "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" dependencies = [ "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" dependencies = [ "proc-macro2", "quote", "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" chbs-0.1.1/Cargo.toml0000644000000023540000000000100077540ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "chbs" version = "0.1.1" authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] description = "A crate providing secure passphrase generation based on a wordlist" homepage = "https://gitlab.com/timvisee/chbs" documentation = "https://docs.rs/chbs" readme = "README.md" keywords = [ "correct", "horse", "diceware", "password-generator", "password", ] categories = ["cryptography"] license = "MIT" repository = "https://gitlab.com/timvisee/chbs" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [dependencies.derive_builder] version = "0.10" [dependencies.rand] version = "0.8" [dependencies.thiserror] version = "1.0.31" [target."cfg(target_arch = \"wasm32\")".dependencies.getrandom] version = "0.2" features = ["js"] chbs-0.1.1/Cargo.toml.orig000064400000000000000000000013530072674642500134630ustar 00000000000000[package] name = "chbs" version = "0.1.1" authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] license = "MIT" readme = "README.md" homepage = "https://gitlab.com/timvisee/chbs" repository = "https://gitlab.com/timvisee/chbs" documentation = "https://docs.rs/chbs" description = "A crate providing secure passphrase generation based on a wordlist" keywords = [ "correct", "horse", "diceware", "password-generator", "password", ] categories = [ "cryptography", ] edition = "2018" [dependencies] derive_builder = "0.10" rand = "0.8" thiserror = "1.0.31" [target.'cfg(target_arch = "wasm32")'.dependencies] getrandom = {version = "0.2", features = ["js"]} [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] chbs-0.1.1/LICENSE000064400000000000000000000020370072674642500116010ustar 00000000000000Copyright (c) 2018 Tim Visée Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. chbs-0.1.1/README.md000064400000000000000000000145360072674642500120620ustar 00000000000000[![Build status on GitLab CI][gitlab-ci-master-badge]][gitlab-ci-link] [![Newest release on crates.io][crate-version-badge]][crate-link] [![Documentation][docs-badge]][docs] [![Number of downloads on crates.io][crate-download-badge]][crate-link] [![Project license][crate-license-badge]](LICENSE) [crate-link]: https://crates.io/crates/chbs [crate-download-badge]: https://img.shields.io/crates/d/chbs.svg [crate-version-badge]: https://img.shields.io/crates/v/chbs.svg [crate-license-badge]: https://img.shields.io/crates/l/chbs.svg [docs]: https://docs.rs/chbs [docs-badge]: https://docs.rs/chbs/badge.svg [gitlab-ci-link]: https://gitlab.com/timvisee/chbs/commits/master [gitlab-ci-master-badge]: https://gitlab.com/timvisee/chbs/badges/master/pipeline.svg _Note: this crate is still a work in progress, APIs might change until stabilisation_ # Rust library: Correct Horse Battery Staple A secure, easy to use, configurable and extendable passphrase generation library based on a wordlist, generally known as [diceware]. [![xkcd-img]][xkcd] The name `chbs` is short for the well known "correct horse battery staple" password which originates from the [XKCD][xkcd] comic shown above. * [Features](#features) * [Requirements](#requirements) * [Todo](#todo) * [Concepts](#concepts) * [Examples](#examples) * [Additional notes](#additional-notes) * [License](#license) This library uses cryptographically secure randomization, and may be used for generating secret passphrases[*](#additional-notes). ## Features * Simple and secure passphrase generation * Configurable generation schemes to meet your requirements * Use built-in or custom wordlists * Calculate passphrase entropy * Easy to use abstracted API * Very extendable, to set it up it any way you like ## Requirements * Rust 1.42 or higher (with `std`) ## Todo The following things need to be looked at before stabilization: * Use secure strings? * Additional stylers and configuration options: * Add numbers * Add special characters * Different separators * Generated words (based on character sequences) * Replace characters with similar looking sequences (`a` to `4`, `o` to `()`) ## Concepts As the passphrase generation system in this crate is thoroughly abstracted it is important to understand how the concepts used in this crate work. Here is what is required for passphrase generation: - A `Scheme` defines how a passphrase is generated. Passphrases are only generated through a scheme. - A `Scheme` contains components which represents how the passphrase is built up and styled. Four kinds of components exist, defining the passphrase generation steps. For some kinds one must be defined, for other kinds any number is fine: 1. `WordSetProvider` (`1` required): provides a list of words to use in a passphrase. 2. `WordStyler` (`>=0` required): styles passphrase words, for example, to capitalize. 3. `PhraseBuilder` (`1` required): builds a phrase from a set of passphrase words. 4. `PhraseStyler` (`>=0` required): styles a whole passphrase. Things to understand: - Passphrase generation schemes are commonly created by using a configuration structure. Such as structure will provide various configurable fields, and builds a corresponding scheme based on it for passphrase generation. The usual steps for generating a passphrase: - A configuration structure is built and configured, such as `BasicConfig`. - The configuration struct creates a corresponding passphrase generation scheme. - The scheme is used to generate as many passphrases as needed. - Instead, the `passphrase()` helper method may be used to generate a passphrase with zero configuration for ease of use. See, it isn't too difficult, but allows great extensibility. You probably won't use most of what this crate provides. Take a look at `BasicConfig` to see how to configure your first passphrase generator. Additional good-to-know things: - This crate provides a selection of components for specific tasks, custom components may be built. - This crate provides a `WordList` struct to hold a static wordlist, that may use a built-in wordlist or loads a wordlist from a specified file. - A `WordSampler` may be constructed based on a `WordList` to allow randomized word sampling in an uniform manner. Such a sampler is usually what is used as word provider in a configuration struct. ## Examples Here are some basic examples on how to use this crate. Add `chbs` as dependency in your `Cargo.toml` first: ```toml [dependencies] chbs = "0.0.8" ``` Generate a passphrase with zero configuration using a helper function applying library defaults ([passphrase.rs](examples/passphrase.rs)): ```rust extern crate chbs; use chbs::passphrase; println!("Passphrase: {:?}", passphrase()); ``` Run it using `cargo run --example passphrase`. Generating a passphrase with configuration is recommended, here is a basic example ([`passphrase_config.rs`](examples/passphrase_config.rs)): ```rust extern crate chbs; use chbs::{config::BasicConfig, prelude::*, probability::Probability}; // Build a custom configuration to: let mut config = BasicConfig::default(); config.words = 8; config.separator = "-".into(); config.capitalize_first = Probability::from(0.33); config.capitalize_words = Probability::half(); let mut scheme = config.to_scheme(); println!("Passphrase: {:?}", scheme.generate()); println!("Entropy: {:?}", scheme.entropy().bits()); ``` Run it using `cargo run --example passphrase_config`. Use a word sampler to generate an infinite number of random words based on a wordlist ([sampler.rs](examples/sampler.rs)): ```rust extern crate chbs; use chbs::word::WordList; let words = WordList::default(); let sampler = words.sampler().into_iter(); for word in sampler.take(8) { println!("Sampled word: {:?}", word); } ``` Run it using `cargo run --example sampler`. See all examples in the [`./examples`](./examples) directory. ## Additional notes * This crate is still in development, and should thus be used with care * No warranty is provided for the quality of the passwords or passphrases generated through this library * Entropy calculations may be faulty at this moment ## License This project is released under the MIT license. Check out the [LICENSE](LICENSE) file for more information. [diceware]: https://en.wikipedia.org/wiki/Diceware [xkcd]: https://xkcd.com/936/ [xkcd-img]: https://imgs.xkcd.com/comics/password_strength.png chbs-0.1.1/examples/passphrase.rs000064400000000000000000000013310072674642500151250ustar 00000000000000//! Zero-configuration passphrase generation example //! //! This minimal example shows how the [`passphrase`](passphrase) helper can be used to generate a //! passphrase with zero-configuration. See the documentation of the [`passphrase`](passphrase) //! function for more details and recommendations. //! //! It is recommended to use a configuration structure for generating passphrases to ensure you //! meet your project requirements, see the [`passphrase_config`](examples/passphrase_config.rs) //! example. //! //! Note that this example prints the generated passphrase in the console, //! which might not be desired in most situations. use chbs::passphrase; fn main() { println!("Passphrase: {:?}", passphrase()); } chbs-0.1.1/examples/passphrase_config.rs000064400000000000000000000030610072674642500164540ustar 00000000000000//! Passphrase generation with basic configuration //! //! This example shows how to use the [`BasicConfig`](config::BasicConfig) structure for //! configuring how passphrases should be generated. See the [`BasicConfig`](config::BasicConfig) //! documentation for all available options. //! //! Other configuration structures are available in the [`config`](config) module. //! You may build your own configuration structure with support for converting it into a //! [`Scheme`](scheme::Scheme) by implementing the [`ToScheme`](scheme::ToScheme) trait. //! //! Note that this example prints the generated passphrase in the console, //! which might not be desired in most situations. use chbs::{config::BasicConfig, prelude::*, probability::Probability}; fn main() { // Build a custom configuration to: // - use hyphens as separator // - sometimes capitalizes whole passphrase words // - sometimes capitalizes the first characters of passphrase words // TODO: use the builder instead // let config = BasicConfigBuilder::default() // .separator("-") // .capitalize_first(Probability::from(0.33)) // .capitalize_words(Probability::half()) // .build() // .unwrap(); let mut config = BasicConfig::default(); config.words = 8; config.separator = "-".into(); config.capitalize_first = Probability::from(0.33); config.capitalize_words = Probability::half(); let scheme = config.to_scheme(); println!("Passphrase: {:?}", scheme.generate()); println!("Entropy: {:?}", scheme.entropy().bits()); } chbs-0.1.1/examples/sampler.rs000064400000000000000000000011750072674642500144250ustar 00000000000000//! Sample passphrase words from a wordlist //! //! A minimal example that shows how a word sampler derived from a default wordlist may be used to //! uniformly sample a number of words. //! //! It is not recommended to manually use this logic for forming your own passphrases. The //! abstractions in [`Scheme`](scheme::Scheme) should be used for that possibly with a custom //! [`config`](config). It is however possible. use chbs::word::WordList; fn main() { let words = WordList::default(); let sampler = words.sampler().into_iter(); for word in sampler.take(8) { println!("Sampled word: {:?}", word); } } chbs-0.1.1/res/eff/general_short.txt000064400000000000000000000160140072674642500155220ustar 00000000000000acid acorn acre acts afar affix aged agent agile aging agony ahead aide aids aim ajar alarm alias alibi alien alike alive aloe aloft aloha alone amend amino ample amuse angel anger angle ankle apple april apron aqua area arena argue arise armed armor army aroma array arson art ashen ashes atlas atom attic audio avert avoid awake award awoke axis bacon badge bagel baggy baked baker balmy banjo barge barn bash basil bask batch bath baton bats blade blank blast blaze bleak blend bless blimp blink bloat blob blog blot blunt blurt blush boast boat body boil bok bolt boned boney bonus bony book booth boots boss botch both boxer breed bribe brick bride brim bring brink brisk broad broil broke brook broom brush buck bud buggy bulge bulk bully bunch bunny bunt bush bust busy buzz cable cache cadet cage cake calm cameo canal candy cane canon cape card cargo carol carry carve case cash cause cedar chain chair chant chaos charm chase cheek cheer chef chess chest chew chief chili chill chip chomp chop chow chuck chump chunk churn chute cider cinch city civic civil clad claim clamp clap clash clasp class claw clay clean clear cleat cleft clerk click cling clink clip cloak clock clone cloth cloud clump coach coast coat cod coil coke cola cold colt coma come comic comma cone cope copy coral cork cost cot couch cough cover cozy craft cramp crane crank crate crave crawl crazy creme crepe crept crib cried crisp crook crop cross crowd crown crumb crush crust cub cult cupid cure curl curry curse curve curvy cushy cut cycle dab dad daily dairy daisy dance dandy darn dart dash data date dawn deaf deal dean debit debt debug decaf decal decay deck decor decoy deed delay denim dense dent depth derby desk dial diary dice dig dill dime dimly diner dingy disco dish disk ditch ditzy dizzy dock dodge doing doll dome donor donut dose dot dove down dowry doze drab drama drank draw dress dried drift drill drive drone droop drove drown drum dry duck duct dude dug duke duo dusk dust duty dwarf dwell eagle early earth easel east eaten eats ebay ebony ebook echo edge eel eject elbow elder elf elk elm elope elude elves email emit empty emu enter entry envoy equal erase error erupt essay etch evade even evict evil evoke exact exit fable faced fact fade fall false fancy fang fax feast feed femur fence fend ferry fetal fetch fever fiber fifth fifty film filth final finch fit five flag flaky flame flap flask fled flick fling flint flip flirt float flock flop floss flyer foam foe fog foil folic folk food fool found fox foyer frail frame fray fresh fried frill frisk from front frost froth frown froze fruit gag gains gala game gap gas gave gear gecko geek gem genre gift gig gills given giver glad glass glide gloss glove glow glue goal going golf gong good gooey goofy gore gown grab grain grant grape graph grasp grass grave gravy gray green greet grew grid grief grill grip grit groom grope growl grub grunt guide gulf gulp gummy guru gush gut guy habit half halo halt happy harm hash hasty hatch hate haven hazel hazy heap heat heave hedge hefty help herbs hers hub hug hula hull human humid hump hung hunk hunt hurry hurt hush hut ice icing icon icy igloo image ion iron islam issue item ivory ivy jab jam jaws jazz jeep jelly jet jiffy job jog jolly jolt jot joy judge juice juicy july jumbo jump junky juror jury keep keg kept kick kilt king kite kitty kiwi knee knelt koala kung ladle lady lair lake lance land lapel large lash lasso last latch late lazy left legal lemon lend lens lent level lever lid life lift lilac lily limb limes line lint lion lip list lived liver lunar lunch lung lurch lure lurk lying lyric mace maker malt mama mango manor many map march mardi marry mash match mate math moan mocha moist mold mom moody mop morse most motor motto mount mouse mousy mouth move movie mower mud mug mulch mule mull mumbo mummy mural muse music musky mute nacho nag nail name nanny nap navy near neat neon nerd nest net next niece ninth nutty oak oasis oat ocean oil old olive omen onion only ooze opal open opera opt otter ouch ounce outer oval oven owl ozone pace pagan pager palm panda panic pants panty paper park party pasta patch path patio payer pecan penny pep perch perky perm pest petal petri petty photo plank plant plaza plead plot plow pluck plug plus poach pod poem poet pogo point poise poker polar polio polka polo pond pony poppy pork poser pouch pound pout power prank press print prior prism prize probe prong proof props prude prune pry pug pull pulp pulse puma punch punk pupil puppy purr purse push putt quack quake query quiet quill quilt quit quota quote rabid race rack radar radio raft rage raid rail rake rally ramp ranch range rank rant rash raven reach react ream rebel recap relax relay relic remix repay repel reply rerun reset rhyme rice rich ride rigid rigor rinse riot ripen rise risk ritzy rival river roast robe robin rock rogue roman romp rope rover royal ruby rug ruin rule runny rush rust rut sadly sage said saint salad salon salsa salt same sandy santa satin sauna saved savor sax say scale scam scan scare scarf scary scoff scold scoop scoot scope score scorn scout scowl scrap scrub scuba scuff sect sedan self send sepia serve set seven shack shade shady shaft shaky sham shape share sharp shed sheep sheet shelf shell shine shiny ship shirt shock shop shore shout shove shown showy shred shrug shun shush shut shy sift silk silly silo sip siren sixth size skate skew skid skier skies skip skirt skit sky slab slack slain slam slang slash slate slaw sled sleek sleep sleet slept slice slick slimy sling slip slit slob slot slug slum slurp slush small smash smell smile smirk smog snack snap snare snarl sneak sneer sniff snore snort snout snowy snub snuff speak speed spend spent spew spied spill spiny spoil spoke spoof spool spoon sport spot spout spray spree spur squad squat squid stack staff stage stain stall stamp stand stank stark start stash state stays steam steep stem step stew stick sting stir stock stole stomp stony stood stool stoop stop storm stout stove straw stray strut stuck stud stuff stump stung stunt suds sugar sulk surf sushi swab swan swarm sway swear sweat sweep swell swept swim swing swipe swirl swoop swore syrup tacky taco tag take tall talon tamer tank taper taps tarot tart task taste tasty taunt thank thaw theft theme thigh thing think thong thorn those throb thud thumb thump thus tiara tidal tidy tiger tile tilt tint tiny trace track trade train trait trap trash tray treat tree trek trend trial tribe trick trio trout truce truck trump trunk try tug tulip tummy turf tusk tutor tutu tux tweak tweet twice twine twins twirl twist uncle uncut undo unify union unit untie upon upper urban used user usher utter value vapor vegan venue verse vest veto vice video view viral virus visa visor vixen vocal voice void volt voter vowel wad wafer wager wages wagon wake walk wand wasp watch water wavy wheat whiff whole whoop wick widen widow width wife wifi wilt wimp wind wing wink wipe wired wiry wise wish wispy wok wolf womb wool woozy word work worry wound woven wrath wreck wrist xerox yahoo yam yard year yeast yelp yield yo-yo yodel yoga yoyo yummy zebra zero zesty zippy zone zoom chbs-0.1.1/res/eff/large.txt000064400000000000000000001713000072674642500137600ustar 00000000000000abacus abdomen abdominal abide abiding ability ablaze able abnormal abrasion abrasive abreast abridge abroad abruptly absence absentee absently absinthe absolute absolve abstain abstract absurd accent acclaim acclimate accompany account accuracy accurate accustom acetone achiness aching acid acorn acquaint acquire acre acrobat acronym acting action activate activator active activism activist activity actress acts acutely acuteness aeration aerobics aerosol aerospace afar affair affected affecting affection affidavit affiliate affirm affix afflicted affluent afford affront aflame afloat aflutter afoot afraid afterglow afterlife aftermath aftermost afternoon aged ageless agency agenda agent aggregate aghast agile agility aging agnostic agonize agonizing agony agreeable agreeably agreed agreeing agreement aground ahead ahoy aide aids aim ajar alabaster alarm albatross album alfalfa algebra algorithm alias alibi alienable alienate aliens alike alive alkaline alkalize almanac almighty almost aloe aloft aloha alone alongside aloof alphabet alright although altitude alto aluminum alumni always amaretto amaze amazingly amber ambiance ambiguity ambiguous ambition ambitious ambulance ambush amendable amendment amends amenity amiable amicably amid amigo amino amiss ammonia ammonium amnesty amniotic among amount amperage ample amplifier amplify amply amuck amulet amusable amused amusement amuser amusing anaconda anaerobic anagram anatomist anatomy anchor anchovy ancient android anemia anemic aneurism anew angelfish angelic anger angled angler angles angling angrily angriness anguished angular animal animate animating animation animator anime animosity ankle annex annotate announcer annoying annually annuity anointer another answering antacid antarctic anteater antelope antennae anthem anthill anthology antibody antics antidote antihero antiquely antiques antiquity antirust antitoxic antitrust antiviral antivirus antler antonym antsy anvil anybody anyhow anymore anyone anyplace anything anytime anyway anywhere aorta apache apostle appealing appear appease appeasing appendage appendix appetite appetizer applaud applause apple appliance applicant applied apply appointee appraisal appraiser apprehend approach approval approve apricot april apron aptitude aptly aqua aqueduct arbitrary arbitrate ardently area arena arguable arguably argue arise armadillo armband armchair armed armful armhole arming armless armoire armored armory armrest army aroma arose around arousal arrange array arrest arrival arrive arrogance arrogant arson art ascend ascension ascent ascertain ashamed ashen ashes ashy aside askew asleep asparagus aspect aspirate aspire aspirin astonish astound astride astrology astronaut astronomy astute atlantic atlas atom atonable atop atrium atrocious atrophy attach attain attempt attendant attendee attention attentive attest attic attire attitude attractor attribute atypical auction audacious audacity audible audibly audience audio audition augmented august authentic author autism autistic autograph automaker automated automatic autopilot available avalanche avatar avenge avenging avenue average aversion avert aviation aviator avid avoid await awaken award aware awhile awkward awning awoke awry axis babble babbling babied baboon backache backboard backboned backdrop backed backer backfield backfire backhand backing backlands backlash backless backlight backlit backlog backpack backpedal backrest backroom backshift backside backslid backspace backspin backstab backstage backtalk backtrack backup backward backwash backwater backyard bacon bacteria bacterium badass badge badland badly badness baffle baffling bagel bagful baggage bagged baggie bagginess bagging baggy bagpipe baguette baked bakery bakeshop baking balance balancing balcony balmy balsamic bamboo banana banish banister banjo bankable bankbook banked banker banking banknote bankroll banner bannister banshee banter barbecue barbed barbell barber barcode barge bargraph barista baritone barley barmaid barman barn barometer barrack barracuda barrel barrette barricade barrier barstool bartender barterer bash basically basics basil basin basis basket batboy batch bath baton bats battalion battered battering battery batting battle bauble bazooka blabber bladder blade blah blame blaming blanching blandness blank blaspheme blasphemy blast blatancy blatantly blazer blazing bleach bleak bleep blemish blend bless blighted blimp bling blinked blinker blinking blinks blip blissful blitz blizzard bloated bloating blob blog bloomers blooming blooper blot blouse blubber bluff bluish blunderer blunt blurb blurred blurry blurt blush blustery boaster boastful boasting boat bobbed bobbing bobble bobcat bobsled bobtail bodacious body bogged boggle bogus boil bok bolster bolt bonanza bonded bonding bondless boned bonehead boneless bonelike boney bonfire bonnet bonsai bonus bony boogeyman boogieman book boondocks booted booth bootie booting bootlace bootleg boots boozy borax boring borough borrower borrowing boss botanical botanist botany botch both bottle bottling bottom bounce bouncing bouncy bounding boundless bountiful bovine boxcar boxer boxing boxlike boxy breach breath breeches breeching breeder breeding breeze breezy brethren brewery brewing briar bribe brick bride bridged brigade bright brilliant brim bring brink brisket briskly briskness bristle brittle broadband broadcast broaden broadly broadness broadside broadways broiler broiling broken broker bronchial bronco bronze bronzing brook broom brought browbeat brownnose browse browsing bruising brunch brunette brunt brush brussels brute brutishly bubble bubbling bubbly buccaneer bucked bucket buckle buckshot buckskin bucktooth buckwheat buddhism buddhist budding buddy budget buffalo buffed buffer buffing buffoon buggy bulb bulge bulginess bulgur bulk bulldog bulldozer bullfight bullfrog bullhorn bullion bullish bullpen bullring bullseye bullwhip bully bunch bundle bungee bunion bunkbed bunkhouse bunkmate bunny bunt busboy bush busily busload bust busybody buzz cabana cabbage cabbie cabdriver cable caboose cache cackle cacti cactus caddie caddy cadet cadillac cadmium cage cahoots cake calamari calamity calcium calculate calculus caliber calibrate calm caloric calorie calzone camcorder cameo camera camisole camper campfire camping campsite campus canal canary cancel candied candle candy cane canine canister cannabis canned canning cannon cannot canola canon canopener canopy canteen canyon capable capably capacity cape capillary capital capitol capped capricorn capsize capsule caption captivate captive captivity capture caramel carat caravan carbon cardboard carded cardiac cardigan cardinal cardstock carefully caregiver careless caress caretaker cargo caring carless carload carmaker carnage carnation carnival carnivore carol carpenter carpentry carpool carport carried carrot carrousel carry cartel cartload carton cartoon cartridge cartwheel carve carving carwash cascade case cash casing casino casket cassette casually casualty catacomb catalog catalyst catalyze catapult cataract catatonic catcall catchable catcher catching catchy caterer catering catfight catfish cathedral cathouse catlike catnap catnip catsup cattail cattishly cattle catty catwalk caucasian caucus causal causation cause causing cauterize caution cautious cavalier cavalry caviar cavity cedar celery celestial celibacy celibate celtic cement census ceramics ceremony certainly certainty certified certify cesarean cesspool chafe chaffing chain chair chalice challenge chamber chamomile champion chance change channel chant chaos chaperone chaplain chapped chaps chapter character charbroil charcoal charger charging chariot charity charm charred charter charting chase chasing chaste chastise chastity chatroom chatter chatting chatty cheating cheddar cheek cheer cheese cheesy chef chemicals chemist chemo cherisher cherub chess chest chevron chevy chewable chewer chewing chewy chief chihuahua childcare childhood childish childless childlike chili chill chimp chip chirping chirpy chitchat chivalry chive chloride chlorine choice chokehold choking chomp chooser choosing choosy chop chosen chowder chowtime chrome chubby chuck chug chummy chump chunk churn chute cider cilantro cinch cinema cinnamon circle circling circular circulate circus citable citadel citation citizen citric citrus city civic civil clad claim clambake clammy clamor clamp clamshell clang clanking clapped clapper clapping clarify clarinet clarity clash clasp class clatter clause clavicle claw clay clean clear cleat cleaver cleft clench clergyman clerical clerk clever clicker client climate climatic cling clinic clinking clip clique cloak clobber clock clone cloning closable closure clothes clothing cloud clover clubbed clubbing clubhouse clump clumsily clumsy clunky clustered clutch clutter coach coagulant coastal coaster coasting coastland coastline coat coauthor cobalt cobbler cobweb cocoa coconut cod coeditor coerce coexist coffee cofounder cognition cognitive cogwheel coherence coherent cohesive coil coke cola cold coleslaw coliseum collage collapse collar collected collector collide collie collision colonial colonist colonize colony colossal colt coma come comfort comfy comic coming comma commence commend comment commerce commode commodity commodore common commotion commute commuting compacted compacter compactly compactor companion company compare compel compile comply component composed composer composite compost composure compound compress comprised computer computing comrade concave conceal conceded concept concerned concert conch concierge concise conclude concrete concur condense condiment condition condone conducive conductor conduit cone confess confetti confidant confident confider confiding configure confined confining confirm conflict conform confound confront confused confusing confusion congenial congested congrats congress conical conjoined conjure conjuror connected connector consensus consent console consoling consonant constable constant constrain constrict construct consult consumer consuming contact container contempt contend contented contently contents contest context contort contour contrite control contusion convene convent copartner cope copied copier copilot coping copious copper copy coral cork cornball cornbread corncob cornea corned corner cornfield cornflake cornhusk cornmeal cornstalk corny coronary coroner corporal corporate corral correct corridor corrode corroding corrosive corsage corset cortex cosigner cosmetics cosmic cosmos cosponsor cost cottage cotton couch cough could countable countdown counting countless country county courier covenant cover coveted coveting coyness cozily coziness cozy crabbing crabgrass crablike crabmeat cradle cradling crafter craftily craftsman craftwork crafty cramp cranberry crane cranial cranium crank crate crave craving crawfish crawlers crawling crayfish crayon crazed crazily craziness crazy creamed creamer creamlike crease creasing creatable create creation creative creature credible credibly credit creed creme creole crepe crept crescent crested cresting crestless crevice crewless crewman crewmate crib cricket cried crier crimp crimson cringe cringing crinkle crinkly crisped crisping crisply crispness crispy criteria critter croak crock crook croon crop cross crouch crouton crowbar crowd crown crucial crudely crudeness cruelly cruelness cruelty crumb crummiest crummy crumpet crumpled cruncher crunching crunchy crusader crushable crushed crusher crushing crust crux crying cryptic crystal cubbyhole cube cubical cubicle cucumber cuddle cuddly cufflink culinary culminate culpable culprit cultivate cultural culture cupbearer cupcake cupid cupped cupping curable curator curdle cure curfew curing curled curler curliness curling curly curry curse cursive cursor curtain curtly curtsy curvature curve curvy cushy cusp cussed custard custodian custody customary customer customize customs cut cycle cyclic cycling cyclist cylinder cymbal cytoplasm cytoplast dab dad daffodil dagger daily daintily dainty dairy daisy dallying dance dancing dandelion dander dandruff dandy danger dangle dangling daredevil dares daringly darkened darkening darkish darkness darkroom darling darn dart darwinism dash dastardly data datebook dating daughter daunting dawdler dawn daybed daybreak daycare daydream daylight daylong dayroom daytime dazzler dazzling deacon deafening deafness dealer dealing dealmaker dealt dean debatable debate debating debit debrief debtless debtor debug debunk decade decaf decal decathlon decay deceased deceit deceiver deceiving december decency decent deception deceptive decibel decidable decimal decimeter decipher deck declared decline decode decompose decorated decorator decoy decrease decree dedicate dedicator deduce deduct deed deem deepen deeply deepness deface defacing defame default defeat defection defective defendant defender defense defensive deferral deferred defiance defiant defile defiling define definite deflate deflation deflator deflected deflector defog deforest defraud defrost deftly defuse defy degraded degrading degrease degree dehydrate deity dejected delay delegate delegator delete deletion delicacy delicate delicious delighted delirious delirium deliverer delivery delouse delta deluge delusion deluxe demanding demeaning demeanor demise democracy democrat demote demotion demystify denatured deniable denial denim denote dense density dental dentist denture deny deodorant deodorize departed departure depict deplete depletion deplored deploy deport depose depraved depravity deprecate depress deprive depth deputize deputy derail deranged derby derived desecrate deserve deserving designate designed designer designing deskbound desktop deskwork desolate despair despise despite destiny destitute destruct detached detail detection detective detector detention detergent detest detonate detonator detoxify detract deuce devalue deviancy deviant deviate deviation deviator device devious devotedly devotee devotion devourer devouring devoutly dexterity dexterous diabetes diabetic diabolic diagnoses diagnosis diagram dial diameter diaper diaphragm diary dice dicing dictate dictation dictator difficult diffused diffuser diffusion diffusive dig dilation diligence diligent dill dilute dime diminish dimly dimmed dimmer dimness dimple diner dingbat dinghy dinginess dingo dingy dining dinner diocese dioxide diploma dipped dipper dipping directed direction directive directly directory direness dirtiness disabled disagree disallow disarm disarray disaster disband disbelief disburse discard discern discharge disclose discolor discount discourse discover discuss disdain disengage disfigure disgrace dish disinfect disjoin disk dislike disliking dislocate dislodge disloyal dismantle dismay dismiss dismount disobey disorder disown disparate disparity dispatch dispense dispersal dispersed disperser displace display displease disposal dispose disprove dispute disregard disrupt dissuade distance distant distaste distill distinct distort distract distress district distrust ditch ditto ditzy dividable divided dividend dividers dividing divinely diving divinity divisible divisibly division divisive divorcee dizziness dizzy doable docile dock doctrine document dodge dodgy doily doing dole dollar dollhouse dollop dolly dolphin domain domelike domestic dominion dominoes donated donation donator donor donut doodle doorbell doorframe doorknob doorman doormat doornail doorpost doorstep doorstop doorway doozy dork dormitory dorsal dosage dose dotted doubling douche dove down dowry doze drab dragging dragonfly dragonish dragster drainable drainage drained drainer drainpipe dramatic dramatize drank drapery drastic draw dreaded dreadful dreadlock dreamboat dreamily dreamland dreamless dreamlike dreamt dreamy drearily dreary drench dress drew dribble dried drier drift driller drilling drinkable drinking dripping drippy drivable driven driver driveway driving drizzle drizzly drone drool droop drop-down dropbox dropkick droplet dropout dropper drove drown drowsily drudge drum dry dubbed dubiously duchess duckbill ducking duckling ducktail ducky duct dude duffel dugout duh duke duller dullness duly dumping dumpling dumpster duo dupe duplex duplicate duplicity durable durably duration duress during dusk dust dutiful duty duvet dwarf dweeb dwelled dweller dwelling dwindle dwindling dynamic dynamite dynasty dyslexia dyslexic each eagle earache eardrum earflap earful earlobe early earmark earmuff earphone earpiece earplugs earring earshot earthen earthlike earthling earthly earthworm earthy earwig easeful easel easiest easily easiness easing eastbound eastcoast easter eastward eatable eaten eatery eating eats ebay ebony ebook ecard eccentric echo eclair eclipse ecologist ecology economic economist economy ecosphere ecosystem edge edginess edging edgy edition editor educated education educator eel effective effects efficient effort eggbeater egging eggnog eggplant eggshell egomaniac egotism egotistic either eject elaborate elastic elated elbow eldercare elderly eldest electable election elective elephant elevate elevating elevation elevator eleven elf eligible eligibly eliminate elite elitism elixir elk ellipse elliptic elm elongated elope eloquence eloquent elsewhere elude elusive elves email embargo embark embassy embattled embellish ember embezzle emblaze emblem embody embolism emboss embroider emcee emerald emergency emission emit emote emoticon emotion empathic empathy emperor emphases emphasis emphasize emphatic empirical employed employee employer emporium empower emptier emptiness empty emu enable enactment enamel enchanted enchilada encircle enclose enclosure encode encore encounter encourage encroach encrust encrypt endanger endeared endearing ended ending endless endnote endocrine endorphin endorse endowment endpoint endurable endurance enduring energetic energize energy enforced enforcer engaged engaging engine engorge engraved engraver engraving engross engulf enhance enigmatic enjoyable enjoyably enjoyer enjoying enjoyment enlarged enlarging enlighten enlisted enquirer enrage enrich enroll enslave ensnare ensure entail entangled entering entertain enticing entire entitle entity entomb entourage entrap entree entrench entrust entryway entwine enunciate envelope enviable enviably envious envision envoy envy enzyme epic epidemic epidermal epidermis epidural epilepsy epileptic epilogue epiphany episode equal equate equation equator equinox equipment equity equivocal eradicate erasable erased eraser erasure ergonomic errand errant erratic error erupt escalate escalator escapable escapade escapist escargot eskimo esophagus espionage espresso esquire essay essence essential establish estate esteemed estimate estimator estranged estrogen etching eternal eternity ethanol ether ethically ethics euphemism evacuate evacuee evade evaluate evaluator evaporate evasion evasive even everglade evergreen everybody everyday everyone evict evidence evident evil evoke evolution evolve exact exalted example excavate excavator exceeding exception excess exchange excitable exciting exclaim exclude excluding exclusion exclusive excretion excretory excursion excusable excusably excuse exemplary exemplify exemption exerciser exert exes exfoliate exhale exhaust exhume exile existing exit exodus exonerate exorcism exorcist expand expanse expansion expansive expectant expedited expediter expel expend expenses expensive expert expire expiring explain expletive explicit explode exploit explore exploring exponent exporter exposable expose exposure express expulsion exquisite extended extending extent extenuate exterior external extinct extortion extradite extras extrovert extrude extruding exuberant fable fabric fabulous facebook facecloth facedown faceless facelift faceplate faceted facial facility facing facsimile faction factoid factor factsheet factual faculty fade fading failing falcon fall false falsify fame familiar family famine famished fanatic fancied fanciness fancy fanfare fang fanning fantasize fantastic fantasy fascism fastball faster fasting fastness faucet favorable favorably favored favoring favorite fax feast federal fedora feeble feed feel feisty feline felt-tip feminine feminism feminist feminize femur fence fencing fender ferment fernlike ferocious ferocity ferret ferris ferry fervor fester festival festive festivity fetal fetch fever fiber fiction fiddle fiddling fidelity fidgeting fidgety fifteen fifth fiftieth fifty figment figure figurine filing filled filler filling film filter filth filtrate finale finalist finalize finally finance financial finch fineness finer finicky finished finisher finishing finite finless finlike fiscally fit five flaccid flagman flagpole flagship flagstick flagstone flail flakily flaky flame flammable flanked flanking flannels flap flaring flashback flashbulb flashcard flashily flashing flashy flask flatbed flatfoot flatly flatness flatten flattered flatterer flattery flattop flatware flatworm flavored flavorful flavoring flaxseed fled fleshed fleshy flick flier flight flinch fling flint flip flirt float flock flogging flop floral florist floss flounder flyable flyaway flyer flying flyover flypaper foam foe fog foil folic folk follicle follow fondling fondly fondness fondue font food fool footage football footbath footboard footer footgear foothill foothold footing footless footman footnote footpad footpath footprint footrest footsie footsore footwear footwork fossil foster founder founding fountain fox foyer fraction fracture fragile fragility fragment fragrance fragrant frail frame framing frantic fraternal frayed fraying frays freckled freckles freebase freebee freebie freedom freefall freehand freeing freeload freely freemason freeness freestyle freeware freeway freewill freezable freezing freight french frenzied frenzy frequency frequent fresh fretful fretted friction friday fridge fried friend frighten frightful frigidity frigidly frill fringe frisbee frisk fritter frivolous frolic from front frostbite frosted frostily frosting frostlike frosty froth frown frozen fructose frugality frugally fruit frustrate frying gab gaffe gag gainfully gaining gains gala gallantly galleria gallery galley gallon gallows gallstone galore galvanize gambling game gaming gamma gander gangly gangrene gangway gap garage garbage garden gargle garland garlic garment garnet garnish garter gas gatherer gathering gating gauging gauntlet gauze gave gawk gazing gear gecko geek geiger gem gender generic generous genetics genre gentile gentleman gently gents geography geologic geologist geology geometric geometry geranium gerbil geriatric germicide germinate germless germproof gestate gestation gesture getaway getting getup giant gibberish giblet giddily giddiness giddy gift gigabyte gigahertz gigantic giggle giggling giggly gigolo gilled gills gimmick girdle giveaway given giver giving gizmo gizzard glacial glacier glade gladiator gladly glamorous glamour glance glancing glandular glare glaring glass glaucoma glazing gleaming gleeful glider gliding glimmer glimpse glisten glitch glitter glitzy gloater gloating gloomily gloomy glorified glorifier glorify glorious glory gloss glove glowing glowworm glucose glue gluten glutinous glutton gnarly gnat goal goatskin goes goggles going goldfish goldmine goldsmith golf goliath gonad gondola gone gong good gooey goofball goofiness goofy google goon gopher gore gorged gorgeous gory gosling gossip gothic gotten gout gown grab graceful graceless gracious gradation graded grader gradient grading gradually graduate graffiti grafted grafting grain granddad grandkid grandly grandma grandpa grandson granite granny granola grant granular grape graph grapple grappling grasp grass gratified gratify grating gratitude gratuity gravel graveness graves graveyard gravitate gravity gravy gray grazing greasily greedily greedless greedy green greeter greeting grew greyhound grid grief grievance grieving grievous grill grimace grimacing grime griminess grimy grinch grinning grip gristle grit groggily groggy groin groom groove grooving groovy grope ground grouped grout grove grower growing growl grub grudge grudging grueling gruffly grumble grumbling grumbly grumpily grunge grunt guacamole guidable guidance guide guiding guileless guise gulf gullible gully gulp gumball gumdrop gumminess gumming gummy gurgle gurgling guru gush gusto gusty gutless guts gutter guy guzzler gyration habitable habitant habitat habitual hacked hacker hacking hacksaw had haggler haiku half halogen halt halved halves hamburger hamlet hammock hamper hamster hamstring handbag handball handbook handbrake handcart handclap handclasp handcraft handcuff handed handful handgrip handgun handheld handiness handiwork handlebar handled handler handling handmade handoff handpick handprint handrail handsaw handset handsfree handshake handstand handwash handwork handwoven handwrite handyman hangnail hangout hangover hangup hankering hankie hanky haphazard happening happier happiest happily happiness happy harbor hardcopy hardcore hardcover harddisk hardened hardener hardening hardhat hardhead hardiness hardly hardness hardship hardware hardwired hardwood hardy harmful harmless harmonica harmonics harmonize harmony harness harpist harsh harvest hash hassle haste hastily hastiness hasty hatbox hatchback hatchery hatchet hatching hatchling hate hatless hatred haunt haven hazard hazelnut hazily haziness hazing hazy headache headband headboard headcount headdress headed header headfirst headgear heading headlamp headless headlock headphone headpiece headrest headroom headscarf headset headsman headstand headstone headway headwear heap heat heave heavily heaviness heaving hedge hedging heftiness hefty helium helmet helper helpful helping helpless helpline hemlock hemstitch hence henchman henna herald herbal herbicide herbs heritage hermit heroics heroism herring herself hertz hesitancy hesitant hesitate hexagon hexagram hubcap huddle huddling huff hug hula hulk hull human humble humbling humbly humid humiliate humility humming hummus humongous humorist humorless humorous humpback humped humvee hunchback hundredth hunger hungrily hungry hunk hunter hunting huntress huntsman hurdle hurled hurler hurling hurray hurricane hurried hurry hurt husband hush husked huskiness hut hybrid hydrant hydrated hydration hydrogen hydroxide hyperlink hypertext hyphen hypnoses hypnosis hypnotic hypnotism hypnotist hypnotize hypocrisy hypocrite ibuprofen ice iciness icing icky icon icy idealism idealist idealize ideally idealness identical identify identity ideology idiocy idiom idly igloo ignition ignore iguana illicitly illusion illusive image imaginary imagines imaging imbecile imitate imitation immature immerse immersion imminent immobile immodest immorally immortal immovable immovably immunity immunize impaired impale impart impatient impeach impeding impending imperfect imperial impish implant implement implicate implicit implode implosion implosive imply impolite important importer impose imposing impotence impotency impotent impound imprecise imprint imprison impromptu improper improve improving improvise imprudent impulse impulsive impure impurity iodine iodize ion ipad iphone ipod irate irk iron irregular irrigate irritable irritably irritant irritate islamic islamist isolated isolating isolation isotope issue issuing italicize italics item itinerary itunes ivory ivy jab jackal jacket jackknife jackpot jailbird jailbreak jailer jailhouse jalapeno jam janitor january jargon jarring jasmine jaundice jaunt java jawed jawless jawline jaws jaybird jaywalker jazz jeep jeeringly jellied jelly jersey jester jet jiffy jigsaw jimmy jingle jingling jinx jitters jittery job jockey jockstrap jogger jogging john joining jokester jokingly jolliness jolly jolt jot jovial joyfully joylessly joyous joyride joystick jubilance jubilant judge judgingly judicial judiciary judo juggle juggling jugular juice juiciness juicy jujitsu jukebox july jumble jumbo jump junction juncture june junior juniper junkie junkman junkyard jurist juror jury justice justifier justify justly justness juvenile kabob kangaroo karaoke karate karma kebab keenly keenness keep keg kelp kennel kept kerchief kerosene kettle kick kiln kilobyte kilogram kilometer kilowatt kilt kimono kindle kindling kindly kindness kindred kinetic kinfolk king kinship kinsman kinswoman kissable kisser kissing kitchen kite kitten kitty kiwi kleenex knapsack knee knelt knickers knoll koala kooky kosher krypton kudos kung labored laborer laboring laborious labrador ladder ladies ladle ladybug ladylike lagged lagging lagoon lair lake lance landed landfall landfill landing landlady landless landline landlord landmark landmass landmine landowner landscape landside landslide language lankiness lanky lantern lapdog lapel lapped lapping laptop lard large lark lash lasso last latch late lather latitude latrine latter latticed launch launder laundry laurel lavender lavish laxative lazily laziness lazy lecturer left legacy legal legend legged leggings legible legibly legislate lego legroom legume legwarmer legwork lemon lend length lens lent leotard lesser letdown lethargic lethargy letter lettuce level leverage levers levitate levitator liability liable liberty librarian library licking licorice lid life lifter lifting liftoff ligament likely likeness likewise liking lilac lilly lily limb limeade limelight limes limit limping limpness line lingo linguini linguist lining linked linoleum linseed lint lion lip liquefy liqueur liquid lisp list litigate litigator litmus litter little livable lived lively liver livestock lividly living lizard lubricant lubricate lucid luckily luckiness luckless lucrative ludicrous lugged lukewarm lullaby lumber luminance luminous lumpiness lumping lumpish lunacy lunar lunchbox luncheon lunchroom lunchtime lung lurch lure luridness lurk lushly lushness luster lustfully lustily lustiness lustrous lusty luxurious luxury lying lyrically lyricism lyricist lyrics macarena macaroni macaw mace machine machinist magazine magenta maggot magical magician magma magnesium magnetic magnetism magnetize magnifier magnify magnitude magnolia mahogany maimed majestic majesty majorette majority makeover maker makeshift making malformed malt mama mammal mammary mammogram manager managing manatee mandarin mandate mandatory mandolin manger mangle mango mangy manhandle manhole manhood manhunt manicotti manicure manifesto manila mankind manlike manliness manly manmade manned mannish manor manpower mantis mantra manual many map marathon marauding marbled marbles marbling march mardi margarine margarita margin marigold marina marine marital maritime marlin marmalade maroon married marrow marry marshland marshy marsupial marvelous marxism mascot masculine mashed mashing massager masses massive mastiff matador matchbook matchbox matcher matching matchless material maternal maternity math mating matriarch matrimony matrix matron matted matter maturely maturing maturity mauve maverick maximize maximum maybe mayday mayflower moaner moaning mobile mobility mobilize mobster mocha mocker mockup modified modify modular modulator module moisten moistness moisture molar molasses mold molecular molecule molehill mollusk mom monastery monday monetary monetize moneybags moneyless moneywise mongoose mongrel monitor monkhood monogamy monogram monologue monopoly monorail monotone monotype monoxide monsieur monsoon monstrous monthly monument moocher moodiness moody mooing moonbeam mooned moonlight moonlike moonlit moonrise moonscape moonshine moonstone moonwalk mop morale morality morally morbidity morbidly morphine morphing morse mortality mortally mortician mortified mortify mortuary mosaic mossy most mothball mothproof motion motivate motivator motive motocross motor motto mountable mountain mounted mounting mourner mournful mouse mousiness moustache mousy mouth movable move movie moving mower mowing much muck mud mug mulberry mulch mule mulled mullets multiple multiply multitask multitude mumble mumbling mumbo mummified mummify mummy mumps munchkin mundane municipal muppet mural murkiness murky murmuring muscular museum mushily mushiness mushroom mushy music musket muskiness musky mustang mustard muster mustiness musty mutable mutate mutation mute mutilated mutilator mutiny mutt mutual muzzle myself myspace mystified mystify myth nacho nag nail name naming nanny nanometer nape napkin napped napping nappy narrow nastily nastiness national native nativity natural nature naturist nautical navigate navigator navy nearby nearest nearly nearness neatly neatness nebula nebulizer nectar negate negation negative neglector negligee negligent negotiate nemeses nemesis neon nephew nerd nervous nervy nest net neurology neuron neurosis neurotic neuter neutron never next nibble nickname nicotine niece nifty nimble nimbly nineteen ninetieth ninja nintendo ninth nuclear nuclei nucleus nugget nullify number numbing numbly numbness numeral numerate numerator numeric numerous nuptials nursery nursing nurture nutcase nutlike nutmeg nutrient nutshell nuttiness nutty nuzzle nylon oaf oak oasis oat obedience obedient obituary object obligate obliged oblivion oblivious oblong obnoxious oboe obscure obscurity observant observer observing obsessed obsession obsessive obsolete obstacle obstinate obstruct obtain obtrusive obtuse obvious occultist occupancy occupant occupier occupy ocean ocelot octagon octane october octopus ogle oil oink ointment okay old olive olympics omega omen ominous omission omit omnivore onboard oncoming ongoing onion online onlooker only onscreen onset onshore onslaught onstage onto onward onyx oops ooze oozy opacity opal open operable operate operating operation operative operator opium opossum opponent oppose opposing opposite oppressed oppressor opt opulently osmosis other otter ouch ought ounce outage outback outbid outboard outbound outbreak outburst outcast outclass outcome outdated outdoors outer outfield outfit outflank outgoing outgrow outhouse outing outlast outlet outline outlook outlying outmatch outmost outnumber outplayed outpost outpour output outrage outrank outreach outright outscore outsell outshine outshoot outsider outskirts outsmart outsource outspoken outtakes outthink outward outweigh outwit oval ovary oven overact overall overarch overbid overbill overbite overblown overboard overbook overbuilt overcast overcoat overcome overcook overcrowd overdraft overdrawn overdress overdrive overdue overeager overeater overexert overfed overfeed overfill overflow overfull overgrown overhand overhang overhaul overhead overhear overheat overhung overjoyed overkill overlabor overlaid overlap overlay overload overlook overlord overlying overnight overpass overpay overplant overplay overpower overprice overrate overreach overreact override overripe overrule overrun overshoot overshot oversight oversized oversleep oversold overspend overstate overstay overstep overstock overstuff oversweet overtake overthrow overtime overtly overtone overture overturn overuse overvalue overview overwrite owl oxford oxidant oxidation oxidize oxidizing oxygen oxymoron oyster ozone paced pacemaker pacific pacifier pacifism pacifist pacify padded padding paddle paddling padlock pagan pager paging pajamas palace palatable palm palpable palpitate paltry pampered pamperer pampers pamphlet panama pancake pancreas panda pandemic pang panhandle panic panning panorama panoramic panther pantomime pantry pants pantyhose paparazzi papaya paper paprika papyrus parabola parachute parade paradox paragraph parakeet paralegal paralyses paralysis paralyze paramedic parameter paramount parasail parasite parasitic parcel parched parchment pardon parish parka parking parkway parlor parmesan parole parrot parsley parsnip partake parted parting partition partly partner partridge party passable passably passage passcode passenger passerby passing passion passive passivism passover passport password pasta pasted pastel pastime pastor pastrami pasture pasty patchwork patchy paternal paternity path patience patient patio patriarch patriot patrol patronage patronize pauper pavement paver pavestone pavilion paving pawing payable payback paycheck payday payee payer paying payment payphone payroll pebble pebbly pecan pectin peculiar peddling pediatric pedicure pedigree pedometer pegboard pelican pellet pelt pelvis penalize penalty pencil pendant pending penholder penknife pennant penniless penny penpal pension pentagon pentagram pep perceive percent perch percolate perennial perfected perfectly perfume periscope perish perjurer perjury perkiness perky perm peroxide perpetual perplexed persecute persevere persuaded persuader pesky peso pessimism pessimist pester pesticide petal petite petition petri petroleum petted petticoat pettiness petty petunia phantom phobia phoenix phonebook phoney phonics phoniness phony phosphate photo phrase phrasing placard placate placidly plank planner plant plasma plaster plastic plated platform plating platinum platonic platter platypus plausible plausibly playable playback player playful playgroup playhouse playing playlist playmaker playmate playoff playpen playroom playset plaything playtime plaza pleading pleat pledge plentiful plenty plethora plexiglas pliable plod plop plot plow ploy pluck plug plunder plunging plural plus plutonium plywood poach pod poem poet pogo pointed pointer pointing pointless pointy poise poison poker poking polar police policy polio polish politely polka polo polyester polygon polygraph polymer poncho pond pony popcorn pope poplar popper poppy popsicle populace popular populate porcupine pork porous porridge portable portal portfolio porthole portion portly portside poser posh posing possible possibly possum postage postal postbox postcard posted poster posting postnasal posture postwar pouch pounce pouncing pound pouring pout powdered powdering powdery power powwow pox praising prance prancing pranker prankish prankster prayer praying preacher preaching preachy preamble precinct precise precision precook precut predator predefine predict preface prefix preflight preformed pregame pregnancy pregnant preheated prelaunch prelaw prelude premiere premises premium prenatal preoccupy preorder prepaid prepay preplan preppy preschool prescribe preseason preset preshow president presoak press presume presuming preteen pretended pretender pretense pretext pretty pretzel prevail prevalent prevent preview previous prewar prewashed prideful pried primal primarily primary primate primer primp princess print prior prism prison prissy pristine privacy private privatize prize proactive probable probably probation probe probing probiotic problem procedure process proclaim procreate procurer prodigal prodigy produce product profane profanity professed professor profile profound profusely progeny prognosis program progress projector prologue prolonged promenade prominent promoter promotion prompter promptly prone prong pronounce pronto proofing proofread proofs propeller properly property proponent proposal propose props prorate protector protegee proton prototype protozoan protract protrude proud provable proved proven provided provider providing province proving provoke provoking provolone prowess prowler prowling proximity proxy prozac prude prudishly prune pruning pry psychic public publisher pucker pueblo pug pull pulmonary pulp pulsate pulse pulverize puma pumice pummel punch punctual punctuate punctured pungent punisher punk pupil puppet puppy purchase pureblood purebred purely pureness purgatory purge purging purifier purify purist puritan purity purple purplish purposely purr purse pursuable pursuant pursuit purveyor pushcart pushchair pusher pushiness pushing pushover pushpin pushup pushy putdown putt puzzle puzzling pyramid pyromania python quack quadrant quail quaintly quake quaking qualified qualifier qualify quality qualm quantum quarrel quarry quartered quarterly quarters quartet quench query quicken quickly quickness quicksand quickstep quiet quill quilt quintet quintuple quirk quit quiver quizzical quotable quotation quote rabid race racing racism rack racoon radar radial radiance radiantly radiated radiation radiator radio radish raffle raft rage ragged raging ragweed raider railcar railing railroad railway raisin rake raking rally ramble rambling ramp ramrod ranch rancidity random ranged ranger ranging ranked ranking ransack ranting rants rare rarity rascal rash rasping ravage raven ravine raving ravioli ravishing reabsorb reach reacquire reaction reactive reactor reaffirm ream reanalyze reappear reapply reappoint reapprove rearrange rearview reason reassign reassure reattach reawake rebalance rebate rebel rebirth reboot reborn rebound rebuff rebuild rebuilt reburial rebuttal recall recant recapture recast recede recent recess recharger recipient recital recite reckless reclaim recliner reclining recluse reclusive recognize recoil recollect recolor reconcile reconfirm reconvene recopy record recount recoup recovery recreate rectal rectangle rectified rectify recycled recycler recycling reemerge reenact reenter reentry reexamine referable referee reference refill refinance refined refinery refining refinish reflected reflector reflex reflux refocus refold reforest reformat reformed reformer reformist refract refrain refreeze refresh refried refueling refund refurbish refurnish refusal refuse refusing refutable refute regain regalia regally reggae regime region register registrar registry regress regretful regroup regular regulate regulator rehab reheat rehire rehydrate reimburse reissue reiterate rejoice rejoicing rejoin rekindle relapse relapsing relatable related relation relative relax relay relearn release relenting reliable reliably reliance reliant relic relieve relieving relight relish relive reload relocate relock reluctant rely remake remark remarry rematch remedial remedy remember reminder remindful remission remix remnant remodeler remold remorse remote removable removal removed remover removing rename renderer rendering rendition renegade renewable renewably renewal renewed renounce renovate renovator rentable rental rented renter reoccupy reoccur reopen reorder repackage repacking repaint repair repave repaying repayment repeal repeated repeater repent rephrase replace replay replica reply reporter repose repossess repost repressed reprimand reprint reprise reproach reprocess reproduce reprogram reps reptile reptilian repugnant repulsion repulsive repurpose reputable reputably request require requisite reroute rerun resale resample rescuer reseal research reselect reseller resemble resend resent reset reshape reshoot reshuffle residence residency resident residual residue resigned resilient resistant resisting resize resolute resolved resonant resonate resort resource respect resubmit result resume resupply resurface resurrect retail retainer retaining retake retaliate retention rethink retinal retired retiree retiring retold retool retorted retouch retrace retract retrain retread retreat retrial retrieval retriever retry return retying retype reunion reunite reusable reuse reveal reveler revenge revenue reverb revered reverence reverend reversal reverse reversing reversion revert revisable revise revision revisit revivable revival reviver reviving revocable revoke revolt revolver revolving reward rewash rewind rewire reword rework rewrap rewrite rhyme ribbon ribcage rice riches richly richness rickety ricotta riddance ridden ride riding rifling rift rigging rigid rigor rimless rimmed rind rink rinse rinsing riot ripcord ripeness ripening ripping ripple rippling riptide rise rising risk risotto ritalin ritzy rival riverbank riverbed riverboat riverside riveter riveting roamer roaming roast robbing robe robin robotics robust rockband rocker rocket rockfish rockiness rocking rocklike rockslide rockstar rocky rogue roman romp rope roping roster rosy rotten rotting rotunda roulette rounding roundish roundness roundup roundworm routine routing rover roving royal rubbed rubber rubbing rubble rubdown ruby ruckus rudder rug ruined rule rumble rumbling rummage rumor runaround rundown runner running runny runt runway rupture rural ruse rush rust rut sabbath sabotage sacrament sacred sacrifice sadden saddlebag saddled saddling sadly sadness safari safeguard safehouse safely safeness saffron saga sage sagging saggy said saint sake salad salami salaried salary saline salon saloon salsa salt salutary salute salvage salvaging salvation same sample sampling sanction sanctity sanctuary sandal sandbag sandbank sandbar sandblast sandbox sanded sandfish sanding sandlot sandpaper sandpit sandstone sandstorm sandworm sandy sanitary sanitizer sank santa sapling sappiness sappy sarcasm sarcastic sardine sash sasquatch sassy satchel satiable satin satirical satisfied satisfy saturate saturday sauciness saucy sauna savage savanna saved savings savior savor saxophone say scabbed scabby scalded scalding scale scaling scallion scallop scalping scam scandal scanner scanning scant scapegoat scarce scarcity scarecrow scared scarf scarily scariness scarring scary scavenger scenic schedule schematic scheme scheming schilling schnapps scholar science scientist scion scoff scolding scone scoop scooter scope scorch scorebook scorecard scored scoreless scorer scoring scorn scorpion scotch scoundrel scoured scouring scouting scouts scowling scrabble scraggly scrambled scrambler scrap scratch scrawny screen scribble scribe scribing scrimmage script scroll scrooge scrounger scrubbed scrubber scruffy scrunch scrutiny scuba scuff sculptor sculpture scurvy scuttle secluded secluding seclusion second secrecy secret sectional sector secular securely security sedan sedate sedation sedative sediment seduce seducing segment seismic seizing seldom selected selection selective selector self seltzer semantic semester semicolon semifinal seminar semisoft semisweet senate senator send senior senorita sensation sensitive sensitize sensually sensuous sepia september septic septum sequel sequence sequester series sermon serotonin serpent serrated serve service serving sesame sessions setback setting settle settling setup sevenfold seventeen seventh seventy severity shabby shack shaded shadily shadiness shading shadow shady shaft shakable shakily shakiness shaking shaky shale shallot shallow shame shampoo shamrock shank shanty shape shaping share sharpener sharper sharpie sharply sharpness shawl sheath shed sheep sheet shelf shell shelter shelve shelving sherry shield shifter shifting shiftless shifty shimmer shimmy shindig shine shingle shininess shining shiny ship shirt shivering shock shone shoplift shopper shopping shoptalk shore shortage shortcake shortcut shorten shorter shorthand shortlist shortly shortness shorts shortwave shorty shout shove showbiz showcase showdown shower showgirl showing showman shown showoff showpiece showplace showroom showy shrank shrapnel shredder shredding shrewdly shriek shrill shrimp shrine shrink shrivel shrouded shrubbery shrubs shrug shrunk shucking shudder shuffle shuffling shun shush shut shy siamese siberian sibling siding sierra siesta sift sighing silenced silencer silent silica silicon silk silliness silly silo silt silver similarly simile simmering simple simplify simply sincere sincerity singer singing single singular sinister sinless sinner sinuous sip siren sister sitcom sitter sitting situated situation sixfold sixteen sixth sixties sixtieth sixtyfold sizable sizably size sizing sizzle sizzling skater skating skedaddle skeletal skeleton skeptic sketch skewed skewer skid skied skier skies skiing skilled skillet skillful skimmed skimmer skimming skimpily skincare skinhead skinless skinning skinny skintight skipper skipping skirmish skirt skittle skydiver skylight skyline skype skyrocket skyward slab slacked slacker slacking slackness slacks slain slam slander slang slapping slapstick slashed slashing slate slather slaw sled sleek sleep sleet sleeve slept sliceable sliced slicer slicing slick slider slideshow sliding slighted slighting slightly slimness slimy slinging slingshot slinky slip slit sliver slobbery slogan sloped sloping sloppily sloppy slot slouching slouchy sludge slug slum slurp slush sly small smartly smartness smasher smashing smashup smell smelting smile smilingly smirk smite smith smitten smock smog smoked smokeless smokiness smoking smoky smolder smooth smother smudge smudgy smuggler smuggling smugly smugness snack snagged snaking snap snare snarl snazzy sneak sneer sneeze sneezing snide sniff snippet snipping snitch snooper snooze snore snoring snorkel snort snout snowbird snowboard snowbound snowcap snowdrift snowdrop snowfall snowfield snowflake snowiness snowless snowman snowplow snowshoe snowstorm snowsuit snowy snub snuff snuggle snugly snugness speak spearfish spearhead spearman spearmint species specimen specked speckled specks spectacle spectator spectrum speculate speech speed spellbind speller spelling spendable spender spending spent spew sphere spherical sphinx spider spied spiffy spill spilt spinach spinal spindle spinner spinning spinout spinster spiny spiral spirited spiritism spirits spiritual splashed splashing splashy splatter spleen splendid splendor splice splicing splinter splotchy splurge spoilage spoiled spoiler spoiling spoils spoken spokesman sponge spongy sponsor spoof spookily spooky spool spoon spore sporting sports sporty spotless spotlight spotted spotter spotting spotty spousal spouse spout sprain sprang sprawl spray spree sprig spring sprinkled sprinkler sprint sprite sprout spruce sprung spry spud spur sputter spyglass squabble squad squall squander squash squatted squatter squatting squeak squealer squealing squeamish squeegee squeeze squeezing squid squiggle squiggly squint squire squirt squishier squishy stability stabilize stable stack stadium staff stage staging stagnant stagnate stainable stained staining stainless stalemate staleness stalling stallion stamina stammer stamp stand stank staple stapling starboard starch stardom stardust starfish stargazer staring stark starless starlet starlight starlit starring starry starship starter starting startle startling startup starved starving stash state static statistic statue stature status statute statutory staunch stays steadfast steadier steadily steadying steam steed steep steerable steering steersman stegosaur stellar stem stench stencil step stereo sterile sterility sterilize sterling sternness sternum stew stick stiffen stiffly stiffness stifle stifling stillness stilt stimulant stimulate stimuli stimulus stinger stingily stinging stingray stingy stinking stinky stipend stipulate stir stitch stock stoic stoke stole stomp stonewall stoneware stonework stoning stony stood stooge stool stoop stoplight stoppable stoppage stopped stopper stopping stopwatch storable storage storeroom storewide storm stout stove stowaway stowing straddle straggler strained strainer straining strangely stranger strangle strategic strategy stratus straw stray streak stream street strength strenuous strep stress stretch strewn stricken strict stride strife strike striking strive striving strobe strode stroller strongbox strongly strongman struck structure strudel struggle strum strung strut stubbed stubble stubbly stubborn stucco stuck student studied studio study stuffed stuffing stuffy stumble stumbling stump stung stunned stunner stunning stunt stupor sturdily sturdy styling stylishly stylist stylized stylus suave subarctic subatomic subdivide subdued subduing subfloor subgroup subheader subject sublease sublet sublevel sublime submarine submerge submersed submitter subpanel subpar subplot subprime subscribe subscript subsector subside subsiding subsidize subsidy subsoil subsonic substance subsystem subtext subtitle subtly subtotal subtract subtype suburb subway subwoofer subzero succulent such suction sudden sudoku suds sufferer suffering suffice suffix suffocate suffrage sugar suggest suing suitable suitably suitcase suitor sulfate sulfide sulfite sulfur sulk sullen sulphate sulphuric sultry superbowl superglue superhero superior superjet superman supermom supernova supervise supper supplier supply support supremacy supreme surcharge surely sureness surface surfacing surfboard surfer surgery surgical surging surname surpass surplus surprise surreal surrender surrogate surround survey survival survive surviving survivor sushi suspect suspend suspense sustained sustainer swab swaddling swagger swampland swan swapping swarm sway swear sweat sweep swell swept swerve swifter swiftly swiftness swimmable swimmer swimming swimsuit swimwear swinger swinging swipe swirl switch swivel swizzle swooned swoop swoosh swore sworn swung sycamore sympathy symphonic symphony symptom synapse syndrome synergy synopses synopsis synthesis synthetic syrup system t-shirt tabasco tabby tableful tables tablet tableware tabloid tackiness tacking tackle tackling tacky taco tactful tactical tactics tactile tactless tadpole taekwondo tag tainted take taking talcum talisman tall talon tamale tameness tamer tamper tank tanned tannery tanning tantrum tapeless tapered tapering tapestry tapioca tapping taps tarantula target tarmac tarnish tarot tartar tartly tartness task tassel taste tastiness tasting tasty tattered tattle tattling tattoo taunt tavern thank that thaw theater theatrics thee theft theme theology theorize thermal thermos thesaurus these thesis thespian thicken thicket thickness thieving thievish thigh thimble thing think thinly thinner thinness thinning thirstily thirsting thirsty thirteen thirty thong thorn those thousand thrash thread threaten threefold thrift thrill thrive thriving throat throbbing throng throttle throwaway throwback thrower throwing thud thumb thumping thursday thus thwarting thyself tiara tibia tidal tidbit tidiness tidings tidy tiger tighten tightly tightness tightrope tightwad tigress tile tiling till tilt timid timing timothy tinderbox tinfoil tingle tingling tingly tinker tinkling tinsel tinsmith tint tinwork tiny tipoff tipped tipper tipping tiptoeing tiptop tiring tissue trace tracing track traction tractor trade trading tradition traffic tragedy trailing trailside train traitor trance tranquil transfer transform translate transpire transport transpose trapdoor trapeze trapezoid trapped trapper trapping traps trash travel traverse travesty tray treachery treading treadmill treason treat treble tree trekker tremble trembling tremor trench trend trespass triage trial triangle tribesman tribunal tribune tributary tribute triceps trickery trickily tricking trickle trickster tricky tricolor tricycle trident tried trifle trifocals trillion trilogy trimester trimmer trimming trimness trinity trio tripod tripping triumph trivial trodden trolling trombone trophy tropical tropics trouble troubling trough trousers trout trowel truce truck truffle trump trunks trustable trustee trustful trusting trustless truth try tubby tubeless tubular tucking tuesday tug tuition tulip tumble tumbling tummy turban turbine turbofan turbojet turbulent turf turkey turmoil turret turtle tusk tutor tutu tux tweak tweed tweet tweezers twelve twentieth twenty twerp twice twiddle twiddling twig twilight twine twins twirl twistable twisted twister twisting twisty twitch twitter tycoon tying tyke udder ultimate ultimatum ultra umbilical umbrella umpire unabashed unable unadorned unadvised unafraid unaired unaligned unaltered unarmored unashamed unaudited unawake unaware unbaked unbalance unbeaten unbend unbent unbiased unbitten unblended unblessed unblock unbolted unbounded unboxed unbraided unbridle unbroken unbuckled unbundle unburned unbutton uncanny uncapped uncaring uncertain unchain unchanged uncharted uncheck uncivil unclad unclaimed unclamped unclasp uncle unclip uncloak unclog unclothed uncoated uncoiled uncolored uncombed uncommon uncooked uncork uncorrupt uncounted uncouple uncouth uncover uncross uncrown uncrushed uncured uncurious uncurled uncut undamaged undated undaunted undead undecided undefined underage underarm undercoat undercook undercut underdog underdone underfed underfeed underfoot undergo undergrad underhand underline underling undermine undermost underpaid underpass underpay underrate undertake undertone undertook undertow underuse underwear underwent underwire undesired undiluted undivided undocked undoing undone undrafted undress undrilled undusted undying unearned unearth unease uneasily uneasy uneatable uneaten unedited unelected unending unengaged unenvied unequal unethical uneven unexpired unexposed unfailing unfair unfasten unfazed unfeeling unfiled unfilled unfitted unfitting unfixable unfixed unflawed unfocused unfold unfounded unframed unfreeze unfrosted unfrozen unfunded unglazed ungloved unglue ungodly ungraded ungreased unguarded unguided unhappily unhappy unharmed unhealthy unheard unhearing unheated unhelpful unhidden unhinge unhitched unholy unhook unicorn unicycle unified unifier uniformed uniformly unify unimpeded uninjured uninstall uninsured uninvited union uniquely unisexual unison unissued unit universal universe unjustly unkempt unkind unknotted unknowing unknown unlaced unlatch unlawful unleaded unlearned unleash unless unleveled unlighted unlikable unlimited unlined unlinked unlisted unlit unlivable unloaded unloader unlocked unlocking unlovable unloved unlovely unloving unluckily unlucky unmade unmanaged unmanned unmapped unmarked unmasked unmasking unmatched unmindful unmixable unmixed unmolded unmoral unmovable unmoved unmoving unnamable unnamed unnatural unneeded unnerve unnerving unnoticed unopened unopposed unpack unpadded unpaid unpainted unpaired unpaved unpeeled unpicked unpiloted unpinned unplanned unplanted unpleased unpledged unplowed unplug unpopular unproven unquote unranked unrated unraveled unreached unread unreal unreeling unrefined unrelated unrented unrest unretired unrevised unrigged unripe unrivaled unroasted unrobed unroll unruffled unruly unrushed unsaddle unsafe unsaid unsalted unsaved unsavory unscathed unscented unscrew unsealed unseated unsecured unseeing unseemly unseen unselect unselfish unsent unsettled unshackle unshaken unshaved unshaven unsheathe unshipped unsightly unsigned unskilled unsliced unsmooth unsnap unsocial unsoiled unsold unsolved unsorted unspoiled unspoken unstable unstaffed unstamped unsteady unsterile unstirred unstitch unstopped unstuck unstuffed unstylish unsubtle unsubtly unsuited unsure unsworn untagged untainted untaken untamed untangled untapped untaxed unthawed unthread untidy untie until untimed untimely untitled untoasted untold untouched untracked untrained untreated untried untrimmed untrue untruth unturned untwist untying unusable unused unusual unvalued unvaried unvarying unveiled unveiling unvented unviable unvisited unvocal unwanted unwarlike unwary unwashed unwatched unweave unwed unwelcome unwell unwieldy unwilling unwind unwired unwitting unwomanly unworldly unworn unworried unworthy unwound unwoven unwrapped unwritten unzip upbeat upchuck upcoming upcountry update upfront upgrade upheaval upheld uphill uphold uplifted uplifting upload upon upper upright uprising upriver uproar uproot upscale upside upstage upstairs upstart upstate upstream upstroke upswing uptake uptight uptown upturned upward upwind uranium urban urchin urethane urgency urgent urging urologist urology usable usage useable used uselessly user usher usual utensil utility utilize utmost utopia utter vacancy vacant vacate vacation vagabond vagrancy vagrantly vaguely vagueness valiant valid valium valley valuables value vanilla vanish vanity vanquish vantage vaporizer variable variably varied variety various varmint varnish varsity varying vascular vaseline vastly vastness veal vegan veggie vehicular velcro velocity velvet vendetta vending vendor veneering vengeful venomous ventricle venture venue venus verbalize verbally verbose verdict verify verse version versus vertebrae vertical vertigo very vessel vest veteran veto vexingly viability viable vibes vice vicinity victory video viewable viewer viewing viewless viewpoint vigorous village villain vindicate vineyard vintage violate violation violator violet violin viper viral virtual virtuous virus visa viscosity viscous viselike visible visibly vision visiting visitor visor vista vitality vitalize vitally vitamins vivacious vividly vividness vixen vocalist vocalize vocally vocation voice voicing void volatile volley voltage volumes voter voting voucher vowed vowel voyage wackiness wad wafer waffle waged wager wages waggle wagon wake waking walk walmart walnut walrus waltz wand wannabe wanted wanting wasabi washable washbasin washboard washbowl washcloth washday washed washer washhouse washing washout washroom washstand washtub wasp wasting watch water waviness waving wavy whacking whacky wham wharf wheat whenever whiff whimsical whinny whiny whisking whoever whole whomever whoopee whooping whoops why wick widely widen widget widow width wieldable wielder wife wifi wikipedia wildcard wildcat wilder wildfire wildfowl wildland wildlife wildly wildness willed willfully willing willow willpower wilt wimp wince wincing wind wing winking winner winnings winter wipe wired wireless wiring wiry wisdom wise wish wisplike wispy wistful wizard wobble wobbling wobbly wok wolf wolverine womanhood womankind womanless womanlike womanly womb woof wooing wool woozy word work worried worrier worrisome worry worsening worshiper worst wound woven wow wrangle wrath wreath wreckage wrecker wrecking wrench wriggle wriggly wrinkle wrinkly wrist writing written wrongdoer wronged wrongful wrongly wrongness wrought xbox xerox yahoo yam yanking yapping yard yarn yeah yearbook yearling yearly yearning yeast yelling yelp yen yesterday yiddish yield yin yippee yo-yo yodel yoga yogurt yonder yoyo yummy zap zealous zebra zen zeppelin zero zestfully zesty zigzagged zipfile zipping zippy zips zit zodiac zombie zone zoning zookeeper zoologist zoology zoom chbs-0.1.1/res/eff/short.txt000064400000000000000000000250320072674642500140250ustar 00000000000000aardvark abandoned abbreviate abdomen abhorrence abiding abnormal abrasion absorbing abundant abyss academy accountant acetone achiness acid acoustics acquire acrobat actress acuteness aerosol aesthetic affidavit afloat afraid aftershave again agency aggressor aghast agitate agnostic agonizing agreeing aidless aimlessly ajar alarmclock albatross alchemy alfalfa algae aliens alkaline almanac alongside alphabet already also altitude aluminum always amazingly ambulance amendment amiable ammunition amnesty amoeba amplifier amuser anagram anchor android anesthesia angelfish animal anklet announcer anonymous answer antelope anxiety anyplace aorta apartment apnea apostrophe apple apricot aquamarine arachnid arbitrate ardently arena argument aristocrat armchair aromatic arrowhead arsonist artichoke asbestos ascend aseptic ashamed asinine asleep asocial asparagus astronaut asymmetric atlas atmosphere atom atrocious attic atypical auctioneer auditorium augmented auspicious automobile auxiliary avalanche avenue aviator avocado awareness awhile awkward awning awoke axially azalea babbling backpack badass bagpipe bakery balancing bamboo banana barracuda basket bathrobe bazooka blade blender blimp blouse blurred boatyard bobcat body bogusness bohemian boiler bonnet boots borough bossiness bottle bouquet boxlike breath briefcase broom brushes bubblegum buckle buddhist buffalo bullfrog bunny busboy buzzard cabin cactus cadillac cafeteria cage cahoots cajoling cakewalk calculator camera canister capsule carrot cashew cathedral caucasian caviar ceasefire cedar celery cement census ceramics cesspool chalkboard cheesecake chimney chlorine chopsticks chrome chute cilantro cinnamon circle cityscape civilian clay clergyman clipboard clock clubhouse coathanger cobweb coconut codeword coexistent coffeecake cognitive cohabitate collarbone computer confetti copier cornea cosmetics cotton couch coverless coyote coziness crawfish crewmember crib croissant crumble crystal cubical cucumber cuddly cufflink cuisine culprit cup curry cushion cuticle cybernetic cyclist cylinder cymbal cynicism cypress cytoplasm dachshund daffodil dagger dairy dalmatian dandelion dartboard dastardly datebook daughter dawn daytime dazzler dealer debris decal dedicate deepness defrost degree dehydrator deliverer democrat dentist deodorant depot deranged desktop detergent device dexterity diamond dibs dictionary diffuser digit dilated dimple dinnerware dioxide diploma directory dishcloth ditto dividers dizziness doctor dodge doll dominoes donut doorstep dorsal double downstairs dozed drainpipe dresser driftwood droppings drum dryer dubiously duckling duffel dugout dumpster duplex durable dustpan dutiful duvet dwarfism dwelling dwindling dynamite dyslexia eagerness earlobe easel eavesdrop ebook eccentric echoless eclipse ecosystem ecstasy edged editor educator eelworm eerie effects eggnog egomaniac ejection elastic elbow elderly elephant elfishly eliminator elk elliptical elongated elsewhere elusive elves emancipate embroidery emcee emerald emission emoticon emperor emulate enactment enchilada endorphin energy enforcer engine enhance enigmatic enjoyably enlarged enormous enquirer enrollment ensemble entryway enunciate envoy enzyme epidemic equipment erasable ergonomic erratic eruption escalator eskimo esophagus espresso essay estrogen etching eternal ethics etiquette eucalyptus eulogy euphemism euthanize evacuation evergreen evidence evolution exam excerpt exerciser exfoliate exhale exist exorcist explode exquisite exterior exuberant fabric factory faded failsafe falcon family fanfare fasten faucet favorite feasibly february federal feedback feigned feline femur fence ferret festival fettuccine feudalist feverish fiberglass fictitious fiddle figurine fillet finalist fiscally fixture flashlight fleshiness flight florist flypaper foamless focus foggy folksong fondue footpath fossil fountain fox fragment freeway fridge frosting fruit fryingpan gadget gainfully gallstone gamekeeper gangway garlic gaslight gathering gauntlet gearbox gecko gem generator geographer gerbil gesture getaway geyser ghoulishly gibberish giddiness giftshop gigabyte gimmick giraffe giveaway gizmo glasses gleeful glisten glove glucose glycerin gnarly gnomish goatskin goggles goldfish gong gooey gorgeous gosling gothic gourmet governor grape greyhound grill groundhog grumbling guacamole guerrilla guitar gullible gumdrop gurgling gusto gutless gymnast gynecology gyration habitat hacking haggard haiku halogen hamburger handgun happiness hardhat hastily hatchling haughty hazelnut headband hedgehog hefty heinously helmet hemoglobin henceforth herbs hesitation hexagon hubcap huddling huff hugeness hullabaloo human hunter hurricane hushing hyacinth hybrid hydrant hygienist hypnotist ibuprofen icepack icing iconic identical idiocy idly igloo ignition iguana illuminate imaging imbecile imitator immigrant imprint iodine ionosphere ipad iphone iridescent irksome iron irrigation island isotope issueless italicize itemizer itinerary itunes ivory jabbering jackrabbit jaguar jailhouse jalapeno jamboree janitor jarring jasmine jaundice jawbreaker jaywalker jazz jealous jeep jelly jeopardize jersey jetski jezebel jiffy jigsaw jingling jobholder jockstrap jogging john joinable jokingly journal jovial joystick jubilant judiciary juggle juice jujitsu jukebox jumpiness junkyard juror justifying juvenile kabob kamikaze kangaroo karate kayak keepsake kennel kerosene ketchup khaki kickstand kilogram kimono kingdom kiosk kissing kite kleenex knapsack kneecap knickers koala krypton laboratory ladder lakefront lantern laptop laryngitis lasagna latch laundry lavender laxative lazybones lecturer leftover leggings leisure lemon length leopard leprechaun lettuce leukemia levers lewdness liability library licorice lifeboat lightbulb likewise lilac limousine lint lioness lipstick liquid listless litter liverwurst lizard llama luau lubricant lucidity ludicrous luggage lukewarm lullaby lumberjack lunchbox luridness luscious luxurious lyrics macaroni maestro magazine mahogany maimed majority makeover malformed mammal mango mapmaker marbles massager matchstick maverick maximum mayonnaise moaning mobilize moccasin modify moisture molecule momentum monastery moonshine mortuary mosquito motorcycle mousetrap movie mower mozzarella muckiness mudflow mugshot mule mummy mundane muppet mural mustard mutation myriad myspace myth nail namesake nanosecond napkin narrator nastiness natives nautically navigate nearest nebula nectar nefarious negotiator neither nemesis neoliberal nephew nervously nest netting neuron nevermore nextdoor nicotine niece nimbleness nintendo nirvana nuclear nugget nuisance nullify numbing nuptials nursery nutcracker nylon oasis oat obediently obituary object obliterate obnoxious observer obtain obvious occupation oceanic octopus ocular office oftentimes oiliness ointment older olympics omissible omnivorous oncoming onion onlooker onstage onward onyx oomph opaquely opera opium opossum opponent optical opulently oscillator osmosis ostrich otherwise ought outhouse ovation oven owlish oxford oxidize oxygen oyster ozone pacemaker padlock pageant pajamas palm pamphlet pantyhose paprika parakeet passport patio pauper pavement payphone pebble peculiarly pedometer pegboard pelican penguin peony pepperoni peroxide pesticide petroleum pewter pharmacy pheasant phonebook phrasing physician plank pledge plotted plug plywood pneumonia podiatrist poetic pogo poison poking policeman poncho popcorn porcupine postcard poultry powerboat prairie pretzel princess propeller prune pry pseudo psychopath publisher pucker pueblo pulley pumpkin punchbowl puppy purse pushup putt puzzle pyramid python quarters quesadilla quilt quote racoon radish ragweed railroad rampantly rancidity rarity raspberry ravishing rearrange rebuilt receipt reentry refinery register rehydrate reimburse rejoicing rekindle relic remote renovator reopen reporter request rerun reservoir retriever reunion revolver rewrite rhapsody rhetoric rhino rhubarb rhyme ribbon riches ridden rigidness rimmed riptide riskily ritzy riverboat roamer robe rocket romancer ropelike rotisserie roundtable royal rubber rudderless rugby ruined rulebook rummage running rupture rustproof sabotage sacrifice saddlebag saffron sainthood saltshaker samurai sandworm sapphire sardine sassy satchel sauna savage saxophone scarf scenario schoolbook scientist scooter scrapbook sculpture scythe secretary sedative segregator seismology selected semicolon senator septum sequence serpent sesame settler severely shack shelf shirt shovel shrimp shuttle shyness siamese sibling siesta silicon simmering singles sisterhood sitcom sixfold sizable skateboard skeleton skies skulk skylight slapping sled slingshot sloth slumbering smartphone smelliness smitten smokestack smudge snapshot sneezing sniff snowsuit snugness speakers sphinx spider splashing sponge sprout spur spyglass squirrel statue steamboat stingray stopwatch strawberry student stylus suave subway suction suds suffocate sugar suitcase sulphur superstore surfer sushi swan sweatshirt swimwear sword sycamore syllable symphony synagogue syringes systemize tablespoon taco tadpole taekwondo tagalong takeout tallness tamale tanned tapestry tarantula tastebud tattoo tavern thaw theater thimble thorn throat thumb thwarting tiara tidbit tiebreaker tiger timid tinsel tiptoeing tirade tissue tractor tree tripod trousers trucks tryout tubeless tuesday tugboat tulip tumbleweed tupperware turtle tusk tutorial tuxedo tweezers twins tyrannical ultrasound umbrella umpire unarmored unbuttoned uncle underwear unevenness unflavored ungloved unhinge unicycle unjustly unknown unlocking unmarked unnoticed unopened unpaved unquenched unroll unscrewing untied unusual unveiled unwrinkled unyielding unzip upbeat upcountry update upfront upgrade upholstery upkeep upload uppercut upright upstairs uptown upwind uranium urban urchin urethane urgent urologist username usher utensil utility utmost utopia utterance vacuum vagrancy valuables vanquished vaporizer varied vaseline vegetable vehicle velcro vendor vertebrae vestibule veteran vexingly vicinity videogame viewfinder vigilante village vinegar violin viperfish virus visor vitamins vivacious vixen vocalist vogue voicemail volleyball voucher voyage vulnerable waffle wagon wakeup walrus wanderer wasp water waving wheat whisper wholesaler wick widow wielder wifeless wikipedia wildcat windmill wipeout wired wishbone wizardry wobbliness wolverine womb woolworker workbasket wound wrangle wreckage wristwatch wrongdoing xerox xylophone yacht yahoo yard yearbook yesterday yiddish yield yo-yo yodel yogurt yuppie zealot zebra zeppelin zestfully zigzagged zillion zipping zirconium zodiac zombie zookeeper zucchini chbs-0.1.1/src/component/mod.rs000064400000000000000000000021620072674642500145110ustar 00000000000000//! Various [`Scheme`](::scheme::Scheme) components to define passphrase generation //! //! These components are used in a [`Scheme`](::scheme::Scheme) to define how passphrases are //! generated. Components are used for providing a set of words, for combining words into a //! passphrase and for styling words and passphrases. These types are defined as trait, to allow //! implementing custom components in your own crate to extend passphrase generation //! functionallity. //! //! The available component kind traits are defined in the [`traits`](self::traits) module and //! are listed below: //! //! - [`WordSetProvider`](self::traits::WordSetProvider) //! - [`WordStyler`](self::traits::WordStyler) //! - [`PhraseBuilder`](self::traits::PhraseBuilder) //! - [`PhraseStyler`](self::traits::PhraseStyler) //! //! The modules [`word`](self::word) and [`phrase`](self::phrase) contains various included //! components to use. For example, the [`WordCapitalizer`](self::word::WordCapitalizer) component //! may be used to capitalize passphrase words as configured. // Re-export the modules pub mod phrase; pub mod traits; pub mod word; chbs-0.1.1/src/component/phrase.rs000064400000000000000000000025300072674642500152130ustar 00000000000000//! Passphrase related components //! //! This module provides some component implementations for processing passphrases. //! These components implement any of the following component kind traits: //! //! - [`PhraseBuilder`](super::traits::PhraseBuilder) //! - [`PhraseStyler`](super::traits::PhraseStyler) //! //! Most of these components are used by configuration strucutres provided by this crate, see //! the [`config`](::config) module. You may of course implement these components in your own //! configuration structures and [`Scheme`](::scheme::Scheme) definitions. use crate::entropy::Entropy; use crate::prelude::*; /// A passphrase builder with as constant word separator. /// /// This is a basic passphrase builder that uses a given set of words to build a full passphrase. /// This builder uses a single fixed separator, that is used as glue between all the passphrase /// words. #[derive(Debug)] pub struct BasicPhraseBuilder { /// The separator that is used. separator: String, } impl BasicPhraseBuilder { pub fn new(separator: String) -> Self { Self { separator } } } impl HasEntropy for BasicPhraseBuilder { fn entropy(&self) -> Entropy { Entropy::zero() } } impl PhraseBuilder for BasicPhraseBuilder { fn build_phrase(&self, words: Vec) -> String { words.join(&self.separator) } } chbs-0.1.1/src/component/traits.rs000064400000000000000000000054500072674642500152430ustar 00000000000000//! Component kind traits //! //! The function of this trait is defined in the [`component`](super) module. use std::fmt::Debug; use crate::prelude::*; /// Something that provides random words. /// /// A word provider is used to provide any number of words for passphrase generation. /// Whether random words are genrated, or whether they are sampled from a known wordlist is /// undefined and decided by the implementor. Providers must be infinite and should never deplete. /// It is possible that the same word may be obtained more than once. /// /// When generating a passphrase a set of words is obtained from a word provider by subsequent /// calls to [`word`](WordProvider::word). /// /// This trait is not used as component kind on [`Scheme`](::scheme::Scheme), it may however be /// useful to implement on types that support this functionallity. In addition to that, the /// [`WordSetProvider`](WordSetProvider) should be easy to implement on types that implement this /// trait. pub trait WordProvider: HasEntropy + Debug + Clone + IntoIterator + Send + Sync { /// Obtain a random word. /// /// This method should obtain and return a random word from the provider. /// The randomization must be cryptographically secure as it's used for generating passphrases. fn word(&self) -> String; } /// Something that provides sets of random words. /// /// A component that provides functionallity to source a random set of passphrase words. /// On sourcing, an ordered list of random passphrase words is returned that will be used in the /// password. /// /// This differs from [`WordProvider`](WordProvider) as this provides a set of words instead of a /// single word. It should be fairly easy to implement this trait on types that have the /// [`WordProvider`](WordProvider) implemented. pub trait WordSetProvider: HasEntropy + Debug + Send + Sync { /// Source a set of random passphrase words to use in a passphrase. fn words(&self) -> Vec; } /// Something that provides logic to _style_ each passphrase word. /// This could be used to build a styler for word capitalization. pub trait WordStyler: HasEntropy + Debug + Send + Sync { /// Style the given `word`. fn style_word(&self, word: String) -> String; } /// Something that provides logic to combine a list of passphrase words into a passphrase. pub trait PhraseBuilder: HasEntropy + Debug + Send + Sync { /// Build the passphrase from the given words, and combine them in one final passphrase. fn build_phrase(&self, words: Vec) -> String; } /// Something that provides logic to _style_ a passphrase as a whole. pub trait PhraseStyler: HasEntropy + Debug + Send + Sync { /// Style the given `phrase` as a whole. /// The styled passphrase is returned. fn style_phrase(&self, phrase: String) -> String; } chbs-0.1.1/src/component/word.rs000064400000000000000000000077710072674642500147200ustar 00000000000000//! Passphrase word related components //! //! This module provides some component implementations for processing words. //! These components implement any of the following component kind traits: //! //! - [`WordSetProvider`](super::traits::WordSetProvider) //! - [`WordStyler`](super::traits::WordStyler) //! //! Most of these components are used by configuration strucutres provided by this crate, see //! the [`config`](::config) module. You may of course implement these components in your own //! configuration structures and [`Scheme`](::scheme::Scheme) definitions. use rand::thread_rng; use crate::entropy::Entropy; use crate::prelude::*; use crate::probability::Probability; /// A generator providing a fixed number of passphrase words. /// /// This generator provides a set of passphrase words for passphrase generation with a fixed number /// of words based on the configuration. #[derive(Debug)] pub struct FixedWordSetProvider

where P: WordProvider, { /// The word provider to obtain words from. provider: P, /// The number of passphrase words to obtain. words: usize, } impl

FixedWordSetProvider

where P: WordProvider, { /// Construct a word set provider with a fixed word count. /// /// The number of words to fill a set with must be provided as `words`. /// It is recommended to use at least 5 passphrase words with a wordlist of at least /// 7776 (65) words. /// /// # Panic /// /// `words` must be higher than zero. pub fn new(provider: P, words: usize) -> Self { // At least 1 word must be obtained by this set provider if words == 0 { panic!("cannot construct FixedWordSetProvider that obtains zero words"); } Self { provider, words } } } impl

HasEntropy for FixedWordSetProvider

where P: WordProvider, { fn entropy(&self) -> Entropy { self.provider.entropy() * self.words as f64 } } impl

WordSetProvider for FixedWordSetProvider

where P: WordProvider, { fn words(&self) -> Vec { let mut res: Vec = vec![]; for _ in 0..self.words { res.push(self.provider.word()); } res } } /// A word styler to capitalize passphrase words. /// /// This word styler component capitalizes words for a passphrase in different styles depending /// on it's configuration. This styler currently supports capitalization of the first character /// in words and/or passphrase words as a whole. #[derive(Debug)] pub struct WordCapitalizer { /// Whether to capitalize the first characters of words. first: Probability, /// Whether to capitalize whole words. all: Probability, } impl WordCapitalizer { /// Construct the word capitalizer component /// /// Whehter to capitalize the first character or the whole word must be defined using the /// `first` and `all` parameters. pub fn new(first: Probability, all: Probability) -> Self { Self { first, all } } } impl HasEntropy for WordCapitalizer { fn entropy(&self) -> Entropy { // For capitalizing all, capitalizing the first character doesn't change anything if let Probability::Always = self.all { Entropy::zero() } else { self.first.entropy() + self.all.entropy() } } } impl WordStyler for WordCapitalizer { fn style_word(&self, mut word: String) -> String { if word.is_empty() { return word; } let mut rng = thread_rng(); // Capitalize the first character if self.first.gen_bool(&mut rng) { let first = word .chars() .map(|c| c.to_uppercase().to_string()) .next() .unwrap_or_else(String::new); let rest: String = word.chars().skip(1).collect(); word = first + &rest; } // Capitalize whole words if self.all.gen_bool(&mut rng) { word = word.to_uppercase(); } word } } chbs-0.1.1/src/config.rs000064400000000000000000000073770072674642500132120ustar 00000000000000//! Provided structures to easily configure passphrase generation [schemes](::scheme::Scheme) //! //! This module contains various configuration structures that allow easy configuring of a //! [`Scheme`](::scheme::Scheme) used to define how passphrases are generated. //! //! These predefined configuration structures use a predefined set of [components](::component) and //! support configurability through struct fields. All configuration strucutres have a matching //! builder to use if you prefer to use the builder pattern. //! //! The most basic configuration structure provides is [`BasicConfig`](BasicConfig), see it's //! documentation for information on how to use it and for some examples. use crate::component::{ phrase::BasicPhraseBuilder, word::{FixedWordSetProvider, WordCapitalizer}, }; use crate::prelude::*; use crate::probability::Probability; use crate::scheme::{Scheme, SchemeBuilder}; use crate::word::{WordList, WordSampler}; use super::{DEFAULT_SEPARATOR, DEFAULT_WORDS}; /// A simple passphrase configuration struct. /// /// This struct provides basic passphrase generation options for simple passphrases. /// When the struct is configured, a [`Scheme`](Scheme) may be created based on it to actually /// generate passphrases. /// /// # Examples /// /// Use the default basic configuration, and change the separator. Then build a scheme, and /// generate a passphrase. /// /// ```rust /// use chbs::{config::BasicConfig, prelude::*}; /// /// // Define the configuration /// let mut config = BasicConfig::default(); /// config.separator = "-".into(); /// /// // Build the scheme for generation /// let mut scheme = config.to_scheme(); /// /// // Generate and output /// println!("Passphrase: {}", scheme.generate()); /// ``` /// /// Or use the [`BasicConfigBuilder`](BasicConfigBuilder) instead for a builder pattern: /// /// ```rust /// // TODO: fix this example /// // extern crate chbs; /// // use chbs::{config::*, word::WordSampler}; /// // /// // let config = BasicConfigBuilder::default() /// // .separator("-") /// // .build() /// // .unwrap(); /// ``` #[derive(Builder, Clone, Debug)] #[builder(setter(into))] pub struct BasicConfig

where P: WordProvider, { /// The number of words the passphrase will consist of. pub words: usize, /// A provider random passphrase words can be obtained from. pub word_provider: P, /// The separator string to use between passphrase words. pub separator: String, /// Whether to capitalize the first characters of words. pub capitalize_first: Probability, /// Whether to capitalize whole words. pub capitalize_words: Probability, } impl Default for BasicConfig { /// Build a default basic configuration instance. /// /// This configuration uses the defaul wordlist as word provider for generating passphrases. fn default() -> BasicConfig { BasicConfig { words: DEFAULT_WORDS, word_provider: WordList::default().sampler(), separator: DEFAULT_SEPARATOR.into(), capitalize_first: Probability::half(), capitalize_words: Probability::Never, } } } impl

ToScheme for BasicConfig

where P: WordProvider + 'static, { fn to_scheme(&self) -> Scheme { SchemeBuilder::default() .word_set_provider(Box::new(FixedWordSetProvider::new( self.word_provider.clone(), self.words, ))) .word_stylers(vec![Box::new(WordCapitalizer::new( self.capitalize_first, self.capitalize_words, ))]) .phrase_builder(Box::new(BasicPhraseBuilder::new(self.separator.clone()))) .phrase_stylers(Vec::new()) .build() .unwrap() } } chbs-0.1.1/src/entropy.rs000064400000000000000000000073740072674642500134420ustar 00000000000000//! Passphrase entropy related structures //! //! This module provides the [`Entropy`](Entropy) type that is used to define passphrase generation //! entropy. [Components](::component) use this type to accumulate their entropy for a final total. //! //! The [`HasEntropy`](HasEntropy) trait may be implemented on types that provide some sort of //! entropy. Implementing this is required on [components](::component) to allow entropy //! calculation on a configured [`Scheme`](::scheme::Scheme). use std::{ fmt::{self, Display, Formatter}, iter::Sum, ops::{Add, Div, Mul, Sub}, }; /// Password entropy. /// /// The entropy number used internally represents the number of base 2 entropy bits, /// and is calculated using `log2(choices)`. #[derive(Copy, Clone, Debug, PartialEq, PartialOrd)] pub struct Entropy(f64); impl Entropy { /// Construct entropy for zero bits, representing no entropy. pub fn zero() -> Self { Entropy(0.0) } /// Construct entropy for one bit, representing 50/50 chance. pub fn one() -> Self { Entropy(1.0) } /// Construct entropy from a number of entropy bits. pub fn from_bits>(bits: F) -> Self { Entropy(bits.into()) } /// Construct entropy from a real number. /// /// For a wordlist of 7776 words where choices are uniform, the real number `7776` may be given /// to construct the proper entropy value. This would produce an entropy instance with about /// `12.9` bits. /// /// If `Entropy` should be constructed from a number of bits, use /// [`from_bits`](Entropy::from_bits) instead. pub fn from_real>(real: F) -> Self { Entropy(real.into().log2()) } /// Get the number of entropy bits. pub fn bits(self) -> f64 { self.0 } } impl Display for Entropy { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{} bits", self.bits()) } } impl Sum for Entropy { #[inline] fn sum(iter: I) -> Self where I: Iterator, I::Item: Into, { iter.fold(Entropy::zero(), |total, e| total + e.into()) } } /// A macro to derive common operator traits for a struct. macro_rules! derive_ops { (impl $trait_: ident for $type_: ident { fn $method: ident }) => { // Operation with another Entropy object impl $trait_<$type_> for $type_ { type Output = $type_; #[inline] fn $method(self, $type_(b): $type_) -> $type_ { let $type_(a) = self; $type_(a.$method(&b)) } } // Operation with another integer or float value impl $trait_ for $type_ where B: Into, { type Output = $type_; #[inline] fn $method(self, b: B) -> $type_ { let $type_(a) = self; $type_(a.$method(&b.into())) } } }; } derive_ops! { impl Add for Entropy { fn add } } derive_ops! { impl Sub for Entropy { fn sub } } derive_ops! { impl Mul for Entropy { fn mul } } derive_ops! { impl Div for Entropy { fn div } } /// An entropy source. /// /// Get the entropy value for the current component, whether that is a word styler, a phrase /// builder or something else. /// /// TODO: properly describe what entropy is here. pub trait HasEntropy { /// Get the entropy value for this whole component. /// The returned entropy value may be accumulated from various internal entropy sources. /// /// See the documentation on [Entropy](Entropy) for details on what entropy is and how it /// should be calculated. /// If this component does not have any effect on passphrase entropy `1` should be returned. fn entropy(&self) -> Entropy; } chbs-0.1.1/src/lib.rs000064400000000000000000000213700072674642500125000ustar 00000000000000//! _Note: this crate is still a work in progress, APIs might change until //! stabilisation_ //! //! A secure, easy to use, configurable and extendable passphrase generation library //! based on a wordlist, generally known as [diceware]. //! //! The crate name `chbs` is short for the well known "correct horse battery staple" password //! which originates from an [XKCD][xkcd] comic shown in the README [here][xkcd_comic]. //! //! This library uses cryptographically secure randomization, and may be used //! for generating secret passphrases. //! Please refer to the [README][readme] for more information on security. //! //! ## Concepts //! As the passphrase generation system in this crate is thoroughly abstracted it is //! important to understand how the concepts used in this crate work. //! //! Here is what is required for passphrase generation: //! - A [`Scheme`](scheme::Scheme) defines how a passphrase is generated. Passphrases are only //! generated through a scheme. //! - A [`Scheme`](scheme::Scheme) contains components which represents how the passphrase is built //! up and styled. Four kinds of components exist, defining the passphrase generation //! steps. For some kinds one must be defined, //! for other kinds any number is fine: //! 1. [`WordSetProvider`](component::traits::WordSetProvider) (`1` required): //! provides a list of words to use in a passphrase. //! 2. [`WordStyler`](component::traits::WordStyler) (`>=0` required): //! styles passphrase words, for example, to capitalize. //! 3. [`PhraseBuilder`](component::traits::PhraseBuilder) (`1` required): //! builds a phrase from a set of passphrase words. //! 4. [`PhraseStyler`](component::traits::PhraseBuilder) (`>=0` required): //! styles a whole passphrase. //! //! Things to understand: //! - Passphrase generation schemes are commonly created by using a configuration //! structure. Such as structure will provide various configurable fields, and //! builds a corresponding scheme based on it for passphrase generation. //! //! The usual steps for generating a passphrase: //! - A configuration structure is built and configured, //! such as [`BasicConfig`](config::BasicConfig). //! - The configuration struct creates a corresponding passphrase generation scheme. //! - The scheme is used to generate as many passphrases as needed. //! - Instead, the [`passphrase()`](passphrase) helper method may be used to generate a passphrase //! with zero configuration for ease of use. //! //! See, it isn't too difficult, but allows great extensibility. You probably won't //! use most of what this crate provides. //! Take a look at [`BasicConfig`](config::BasicConfig) to see how to configure your first //! passphrase generator. //! //! Additional good-to-know things: //! - This crate provides a selection of components for specific tasks, custom //! components may be built. //! - This crate provides a [`WordList`](word::WordList) struct to hold a static wordlist, //! that may use a built-in wordlist or loads a wordlist from a specified file. //! - A [`WordSampler`](word::WordSampler) may be [constructed](word::WordList::sampler) based //! on a [`WordList`](word::WordList) to allow randomized word sampling in an uniform manner. //! Such a sampler is usually what is used as word provider in a configuration struct. //! //! ## Examples //! Here are two very basic examples. //! First to generate a passphrase with zero configuration using a helper function applying //! library defaults ([src][example_passphrase]): //! //! ```rust //! use chbs::passphrase; //! //! println!("Passphrase: {:?}", passphrase()); //! ``` //! //! Generating a passphrase with configuration is recommended, here is a basic //! example ([src][example_passphrase_config]): //! //! ```rust //! use chbs::{config::BasicConfig, prelude::*, probability::Probability}; //! //! // Build a custom configuration to: //! let mut config = BasicConfig::default(); //! config.words = 8; //! config.separator = "-".into(); //! config.capitalize_first = Probability::from(0.33); //! config.capitalize_words = Probability::half(); //! let mut scheme = config.to_scheme(); //! //! println!("Passphrase: {:?}", scheme.generate()); //! println!("Entropy: {:?}", scheme.entropy().bits()); //! ``` //! //! More examples are available in the documentation throughout the crate, //! and in the [`./examples`][examples] directory. //! //! ## More information //! Please reference to the [README][readme] in the [code repository][repo] for more information. //! //! [diceware]: https://en.wikipedia.org/wiki/Diceware //! [examples]: https://gitlab.com/timvisee/chbs/tree/master/examples //! [example_passphrase]: https://gitlab.com/timvisee/chbs/blob/master/examples/passphrase.rs //! [example_passphrase_config]: https://gitlab.com/timvisee/chbs/blob/master/examples/passphrase_config.rs //! [readme]: https://gitlab.com/timvisee/chbs/blob/master/README.md //! [repo]: https://gitlab.com/timvisee/chbs //! [xkcd]: https://xkcd.com/936/ //! [xkcd_comic]: https://gitlab.com/timvisee/chbs#rust-library-correct-horse-battery-staple #[macro_use] extern crate derive_builder; extern crate rand; use crate::config::BasicConfig; use crate::prelude::*; pub mod component; pub mod config; pub mod entropy; pub mod prelude; pub mod probability; pub mod scheme; pub mod word; /// The default number of words the passphrase will consist of. const DEFAULT_WORDS: usize = 5; /// The default separator used between passphrase words. const DEFAULT_SEPARATOR: &str = " "; /// Zero-configuration passphrase generation helper /// /// A quick way to generate a passphrase with no configuration. /// Passphrases are based on the `default()` of a [`BasicConfig`](config::BasicConfig), /// detailed properties can be found in it's documentation. /// /// Although this crate considers the used configuration secure, your project might have different /// requirements. It is therefore highly recommended however to set up your own configuration to /// meet your requirements. This can easily be done by choosing any of the configuration structs /// in the [`config`](::config) module such as [`BasicConfig`](config::BasicConfig), which has a /// [builder](config::BasicConfigBuilder) available. /// Or build your own configuration type with support for converting it into a /// [`Scheme`](scheme::Scheme) by implementing the [`ToScheme`](scheme::ToScheme) trait. /// /// A configuration instance is created each time this method is invoked. For generating multiple /// passphrases it is recommended to build a [`Scheme`](scheme::Scheme) instead as it's much more /// performant. /// /// # Entropy /// /// To figure out what entropy these passphrases have, use: /// /// ```rust /// use chbs::{config::BasicConfig, prelude::*}; /// /// let entropy = BasicConfig::default().to_scheme().entropy(); /// println!("passphrase() entropy: {:?}", entropy); /// ``` pub fn passphrase() -> String { BasicConfig::default().to_scheme().generate() } #[cfg(test)] mod tests { use std::sync::mpsc::RecvError; use std::sync::{mpsc::channel, mpsc::Sender, Arc}; use std::thread; use super::config::BasicConfig; use super::passphrase; use super::scheme::{Scheme, ToScheme}; use super::word::WordList; /// How many times to iterate for small or infinite tests. const ITERS: usize = 32; /// Generating a passphrase must produce a string of at least 10 characters. #[test] fn passphrase_len() { assert!( passphrase().len() >= 10, "passphrase generated by defaults helper is too short", ); } /// Repeatedly generating passphrases should produce somewhat unique results. #[test] fn passphrase_unique() { // Generate phrases with helper and dedup let mut phrases: Vec = (1..=ITERS).map(|_| passphrase()).collect(); phrases.dedup(); // There must be at least 2 unique passphrases assert!(phrases.len() > 1); } #[test] fn sampler_into_iterator() { let words = WordList::default(); let iterator = words.sampler().into_iter(); let result: Vec = iterator.take(8).collect(); assert_eq!(8, result.len()); } #[test] fn threading() -> Result<(), RecvError> { let scheme = Arc::new(BasicConfig::default().to_scheme()); let (tx, rx) = channel::(); let handle1 = spawn_thread(scheme.clone(), tx.clone()); let handle2 = spawn_thread(scheme.clone(), tx.clone()); handle1.join().unwrap(); handle2.join().unwrap(); std::mem::drop(tx); rx.recv()?; rx.recv()?; Ok(()) } fn spawn_thread(scheme: Arc, tx: Sender) -> thread::JoinHandle<()> { thread::spawn(move || { tx.send(scheme.generate()).unwrap(); }) } } chbs-0.1.1/src/prelude.rs000064400000000000000000000011300072674642500133620ustar 00000000000000//! Convenience re-export of common members //! //! Like the standard library's prelude, this module simplifies importing of //! common items such as traits. Unlike the standard prelude, the contents of //! this module must be imported manually. //! //! # Examples //! ```rust //! use chbs::{config::BasicConfig, prelude::*}; //! //! let config = BasicConfig::default(); //! //! // This method requires the ToScheme trait, imported through prelude //! let scheme = config.to_scheme(); //! ``` pub use crate::component::traits::*; pub use crate::entropy::HasEntropy; pub use crate::scheme::ToScheme; chbs-0.1.1/src/probability.rs000064400000000000000000000110770072674642500142550ustar 00000000000000//! Probability related strucutres //! //! This module provides the [`Probability`](Probability) type that is used to define the //! probability of something being true. This is commonly used in passphrase generation //! [components](::component) for randomisation of passphrase styling features. //! For example, the [`WordCapitalizer`](::component::word::WordCapitalizer) uses this type in it's //! fields. //! //! See [`Probability`](Probability) for more details. use rand::{prelude::*, thread_rng}; use crate::entropy::Entropy; use crate::prelude::*; /// A probability definition. /// /// This defines what the probability is of something being true. /// /// The function [`gen_bool`](Probability::gen_bool) can be used to generate a boolean based on /// this probability. Depending on what randomness source is given, it may be cryptographically /// secure. #[derive(Copy, Clone, Debug)] pub enum Probability { /// This is always true. Always, /// This is sometimes true. /// /// If `1.0` it's always true, if `0.0` it is never true, the value may be anywhere in between. /// /// If the value is exactly `0.0` or `1.0` the variants [`Always`](Probability::Always) and /// [`Never`](Probability::Never) should be used instead. /// It is therefore recommended to construct this type using the /// [`from`](Probability::from) method as this automatically chooses the correct variant. /// /// This value may never be `p < 0` or `p > 1`, as it will cause panics. Sometimes(f64), /// This is never true, and is always false. Never, } impl Probability { /// Construct a probability from the given probability value. /// /// If `1.0` it's always true, if `0.0` it is never true. /// Values outside this range will be wrapped to their corresponding edge. pub fn from(probability: f64) -> Self { match probability { x if x >= 1.0 => Probability::Always, x if x <= 0.0 => Probability::Never, x => Probability::Sometimes(x), } } /// Construct a probability from the given percentage. /// /// If `100.0` it's always true, if `0.0` it is never true. /// Values outside this range will be wrapped to their corresponding edge. pub fn from_percentage(percentage: f64) -> Self { match percentage { x if x >= 100.0 => Probability::Always, x if x <= 0.0 => Probability::Never, x => Probability::Sometimes(x / 100.0), } } /// Construct a probability that is true half of the times (50/50, 50%). pub fn half() -> Self { Self::from(0.5) } /// Get the probability value. /// /// To get the percentage, use [`percentage`](Probability::percentage). pub fn value(&self) -> f64 { match self { Probability::Always => 1.0, Probability::Sometimes(p) => *p, Probability::Never => 0.0, } } /// Get the probability percentage. /// /// To get the probability value, use [`value`](Probability::value). pub fn percentage(&self) -> f64 { self.value() * 100.0 } /// Generate a boolean for this probability. /// /// If the given randomness source to `rng` is cryptographically secure, /// the generated boolean can be considered cryptographically secure as well. pub fn gen_bool(self, rng: &mut R) -> bool { match self { Probability::Always => true, Probability::Never => false, Probability::Sometimes(p) => rng.gen_bool(p), } } /// Generate a cryptographically secure boolean for this probability. /// /// This method obtains a cryptographically secure randomness source through `thread_rng` /// provided by the `rand` crate and generates a boolean through /// [`gen_bool`](Probability::gen_bool). pub fn gen_bool_secure(self) -> bool { match self { Probability::Always => true, Probability::Never => false, Probability::Sometimes(_) => self.gen_bool(&mut thread_rng()), } } } impl HasEntropy for Probability { fn entropy(&self) -> Entropy { match self { // TODO: properly calculate entropy here Probability::Sometimes(_p) => Entropy::one(), _ => Entropy::zero(), } } } /// Allow easy `Probability` selection of `Always` and `Never` from a boolean. impl From for Probability { fn from(b: bool) -> Probability { if b { Probability::Always } else { Probability::Never } } } chbs-0.1.1/src/scheme.rs000064400000000000000000000147300072674642500132000ustar 00000000000000//! Generation scheme module to define how to generate passphrases //! //! This module defines the [`Scheme`](Scheme) type, with a corresponding [build](SchemeBuilder) if //! that pattern is desired. //! //! As both provided and custom structures may produce a [`Scheme`](Scheme) for passphrase //! generation, the [`ToScheme`](ToScheme) trait is used for a generic way of doing this. use crate::entropy::Entropy; use crate::prelude::*; /// A passphrase generation scheme. /// /// The scheme defines how passphrases should be generated, and can be directly used to so. /// This scheme holds various components used during generation to modify and combine passphrase /// parts or words. The scheme may be used as iterator, which will produce an infinite number of /// passphrases. /// /// It is recommended to use a configuration struct to confige and build a specific `Scheme` /// instead of setting one up manually. /// The `chbs` crate provides [`BasicConfig`](::config::BasicConfig). /// /// A scheme cannot be modified after creation, to ensure passphrase generation and calculating /// entropy is consistent. /// /// # Components /// /// The following components are part of this scheme and the passphrase generation process: /// /// - The word generator is used once for each passphrase to generate, and provides a set of words /// to use for that specific phrase. The generator internally samples a known wordlist or /// generates randomized strings depending on how it is configured. /// - A set of word stylers is used to modify each passphrase word from the generated set, to /// randomize capitalization, to add special characters and more depending on their /// configuration. Each styler is applied once to each phrase word in the specified order. /// If no word styler is available, the words are kept intact. /// - The phrase builder combines the set of now modified passphrase words into a full passphrase, /// the builder separates the words with a space or anything else depending on it's /// configuration. /// - A set of phrase stylers is used to modify the full passphrase that is now combined. They /// may be used for further modifications with full control over the phrase. If no phrase /// styler is available, the phrase is kept intact. /// /// # Examples /// /// The scheme implements `Iterator`. You may easily generate many passphrases this way: /// /// ```rust /// use chbs::{config::BasicConfig, prelude::*, scheme::Scheme}; /// /// let scheme = BasicConfig::default().to_scheme(); /// /// scheme.take(8) /// .for_each(|passphrase| println!("{}", passphrase)); /// ``` #[derive(Builder, Debug)] #[builder(pattern = "owned")] pub struct Scheme { /// A word set provider, which sources a set of random words to use in the passphrase. word_set_provider: Box, /// A set of word stylers to apply to each passphrase word. word_stylers: Vec>, /// A phrase builder that builds a passphrase out of a styled set of passphrase words. phrase_builder: Box, /// A set of phrase stylers to apply to each passphrase. phrase_stylers: Vec>, } impl Scheme { /// Construct a scheme with the given components /// /// When all components for a scheme are collected, a scheme can be constructed using this /// method. /// /// If you prefer the builder pattern to build a scheme, use [`SchemeBuilder`](SchemeBuilder) /// instead. pub fn new( word_set_provider: Box, word_stylers: Vec>, phrase_builder: Box, phrase_stylers: Vec>, ) -> Self { Self { word_set_provider, word_stylers, phrase_builder, phrase_stylers, } } /// Build a configuration based on the given object. pub fn from(config: &S) -> Self { config.to_scheme() } /// Construct a [`SchemeBuilder`](SchemeBuilder) for building a [`Scheme`](Scheme) pub fn build() -> SchemeBuilder { SchemeBuilder::default() } /// Generate a single passphrase based on this scheme. pub fn generate(&self) -> String { // Generate the passphrase words let mut words = self.word_set_provider.words(); // Run the passphrase words through the word stylers for p in &self.word_stylers { words = words.into_iter().map(|w| p.style_word(w)).collect(); } // Build the passphrase let mut phrase = self.phrase_builder.build_phrase(words); // Run the phrase through the passphrase stylers for p in &self.phrase_stylers { phrase = p.style_phrase(phrase); } phrase } /// Calculate the entropy that passphrases based on this scheme have. /// /// See the documentation on [Entropy](Entropy) for details on what entropy is and how it /// should be calculated. pub fn entropy(&self) -> Entropy { self.word_set_provider.entropy() + self .word_stylers .iter() .map(|p| p.entropy()) .sum::() + self.phrase_builder.entropy() + self .phrase_stylers .iter() .map(|p| p.entropy()) .sum::() } } impl Iterator for Scheme { type Item = String; /// Generate a new passphrase based on this scheme. /// /// This method always returns `Some` holding a passphrase. fn next(&mut self) -> Option { Some(self.generate()) } } impl SchemeBuilder { /// Add a single word styler to the scheme. pub fn add_word_styler(mut self, styler: Box) -> Self { match self.word_stylers { Some(ref mut stylers) => stylers.push(styler), None => self.word_stylers = Some(vec![styler]), } self } /// Add a single phrase styler to the scheme. pub fn add_phrase_styler(mut self, styler: Box) -> Self { match self.phrase_stylers { Some(ref mut stylers) => stylers.push(styler), None => self.phrase_stylers = Some(vec![styler]), } self } } /// A trait providing an interface to build a password scheme based on some sort of configuration. pub trait ToScheme { /// Build a password scheme based on configuration in this object. fn to_scheme(&self) -> Scheme; } chbs-0.1.1/src/word.rs000064400000000000000000000275650072674642500127210ustar 00000000000000//! Utilities for collecting and generating words for in a passphrase //! //! This module provides various constructs for collecting and/or generating words to use in a //! passphrase. //! //! The [`WordList`](WordList) structure is used for static wordlists, which may be uniformly //! sampled using a [`WordSampler`](WordSampler). //! //! Constants holding a static built-in wordlist are included so providing your own wordlist is not //! required, see the [`BUILTIN_`](#constants) constants. //! These lists can easily be loaded using the [`buildin_`](WordList) methods on //! [`WordList`](WordList). use std::fs::read_to_string; use std::path::Path; use thiserror::Error; use rand::{distributions::Uniform, prelude::*}; use crate::entropy::Entropy; use crate::prelude::*; /// The built-in EFF large wordlist words. /// /// Construct a [`WordList`](WordList) from this list using /// [`WordList::builtin_eff_large()`](WordList::builtin_eff_large). /// /// This wordlist contains 7776 (65) words, /// and has an entropy of about 12.9 bits when uniformly sampling words from it. /// /// The list is slightly modified to discard the dice numbers, /// [source](https://www.eff.org/deeplinks/2016/07/new-wordlists-random-passphrases). pub const BUILTIN_EFF_LARGE: &str = include_str!("../res/eff/large.txt"); /// The built-in EFF short wordlist words. /// /// Construct a [`WordList`](WordList) from this list using /// [`WordList::builtin_eff_short()`](WordList::builtin_eff_short). /// /// **Note:** this wordlist is considered short, as it only contains 1296 (64) words. /// The list has an entropy of about 10.3 bits when uniformly sampling words from it. /// It is recommended to use a larger wordlist such as [`BUILTIN_EFF_LARGE`](BUILTIN_EFF_LARGE). /// /// The list is slightly modified to discard the dice numbers, /// [source](https://www.eff.org/deeplinks/2016/07/new-wordlists-random-passphrases). pub const BUILTIN_EFF_SHORT: &str = include_str!("../res/eff/short.txt"); /// The built-in EFF general short wordlist words. /// /// Construct a [`WordList`](WordList) from this list using /// [`WordList::builtin_eff_general_short()`](WordList::builtin_eff_general_short). /// /// **Note:** this wordlist is considered short, as it only contains 1296 (64) words. /// The list has an entropy of about 10.3 bits when uniformly sampling words from it. /// It is recommended to use a larger wordlist such as [`BUILTIN_EFF_LARGE`](BUILTIN_EFF_LARGE). /// /// The list is slightly modified to discard the dice numbers, /// [source](https://www.eff.org/deeplinks/2016/07/new-wordlists-random-passphrases). pub const BUILTIN_EFF_GENERAL_SHORT: &str = include_str!("../res/eff/general_short.txt"); /// A wordlist. /// /// To load a built-in wordlist, checkout the methods on this struct prefixed with `builtin_`. /// The default wordlist loaded when using `default()` uses /// [`builtin_eff_large()`](WordList::builtin_eff_large). /// /// A loaded fixed wordlist which may be used as word provider for passphrase generation by /// constructing a sampler using [`sampler`](WordList::sampler). /// /// It is highly recommended that the worlist contains at least 7776 (65) words to /// provide enough entropy when uniformly sampling words from it. #[derive(Clone, Debug)] pub struct WordList { /// A fixed set of words. words: Vec, } impl WordList { /// Construct a new word list with the given words. /// /// To load a wordlist from a file, use [`load`](WordList::load) instead. /// To load a built-in wordlist, use the methods on this struct prefixed with `builtin_`. /// /// # Panics /// /// This panics if the given set of words is empty. pub fn new(words: Vec) -> Self { if words.is_empty() { panic!("cannot construct wordlist, given list of words is empty"); } WordList { words } } /// Load a wordlist from a file. /// /// This loads a wordlist from a file at the given path, and constructs a `WordList`. /// /// - Words are splitted by any whitespace (including newlines), /// see `char::is_whitespace` /// - It assumes any non-whitespace character is part of a word /// - Whitespaces are omitted the final wordlist /// - Emtpy items are omitted /// - The file must not include dice numbers /// /// For wordlists that include dice numbers, the [`load_diced`](WordList::load_diced) method /// may be used instead. /// If words are separated in a different manner, manually load each word and use the /// [`new`](WordList::new) constructor instead. /// /// An error is returned if loading the wordlist failed, or if the loaded file didn't contain /// any words. /// /// # File examples /// ```txt /// abacus abdomen abdominal abide abiding /// ``` /// or /// ```txt /// abacus /// abdomen /// ``` pub fn load

(path: P) -> Result where P: AsRef, { // Load all words, error if empty let words: Vec = read_to_string(path)? .split_terminator(char::is_whitespace) .filter(|w| !w.is_empty()) .map(|w| w.to_owned()) .collect(); if words.is_empty() { return Err(WordListError::Empty); } Ok(Self::new(words)) } /// Load a diced wordlist from a file. /// /// This loads a diced wordlist from a file at the given path, and constructs a `WordList`. /// Many diceware wordlists include dice numbers for each word, these should be omitted when /// using this crate. This method helps with that. /// /// - Words are splitted by the newline character (`\n`). /// - Only the last word on each line is kept, terminated by any whitespace, see /// `char::is_whitespace` /// - It assumes any non-whitespace character is part of a word /// - Prefixed words do not have to be dice numbers /// - Lines having a single word with no dice number prefix are included /// - Emtpy lines are omitted /// /// For wordlists that do not include dice numbers, the the regular [`load`](WordList::load) /// method instead. /// If words are separated in a different manner, manually load each word and use the /// [`new`](WordList::new) constructor instead. /// /// An error is returned if loading the wordlist failed, or if the loaded file didn't contain /// any words. /// /// # File examples /// ```txt /// 11111 abacus /// 11112 abdomen /// 11113 abdominal /// ``` /// or /// ```txt /// #1 (1,1,1,1,2) abacus /// #2 (1,1,1,1,2) abdomen /// ``` pub fn load_diced

(path: P) -> Result where P: AsRef, { // Load all words, error if emtpy let words: Vec = read_to_string(path)? .lines() .filter(|w| !w.is_empty()) .filter_map(|w| w.rsplit_terminator(char::is_whitespace).next()) .map(|w| w.to_owned()) .collect(); if words.is_empty() { return Err(WordListError::Empty); } Ok(Self::new(words)) } /// Construct wordlist from built-in EFF large. /// /// Use the built-in EFF large list of words, and construct a wordlist from it. /// This is based on [`BUILTIN_EFF_LARGE`](BUILTIN_EFF_LARGE). pub fn builtin_eff_large() -> Self { Self::new( BUILTIN_EFF_LARGE .lines() .map(|w| w.to_owned()) .collect::>(), ) } /// Construct wordlist from built-in EFF short. /// /// Use the built-in EFF short list of words, and construct a wordlist from it. /// This is based on [`BUILTIN_EFF_SHORT`](BUILTIN_EFF_SHORT). /// /// **Note:** this wordlist is considered short, as it only contains 1296 (64) /// words. /// The list has an entropy of about 10.3 bits when uniformly sampling words from it. /// It is recommended to use a larger wordlist such as /// [`builtin_eff_large`](WordList::builtin_eff_large). pub fn builtin_eff_short() -> Self { Self::new( BUILTIN_EFF_SHORT .lines() .map(|w| w.to_owned()) .collect::>(), ) } /// Construct wordlist from built-in EFF general short. /// /// Use the built-in EFF general short list of words, and construct a wordlist from it. /// This is based on [`BUILTIN_EFF_GENERAL_SHORT`](BUILTIN_EFF_GENERAL_SHORT). /// /// **Note:** this wordlist is considered short, as it only contains 1296 (64) /// words. /// The list has an entropy of about 10.3 bits when uniformly sampling words from it. /// It is recommended to use a larger wordlist such as /// [`builtin_eff_large`](WordList::builtin_eff_large). pub fn builtin_eff_general_short() -> Self { Self::new( BUILTIN_EFF_GENERAL_SHORT .lines() .map(|w| w.to_owned()) .collect::>(), ) } /// Build a sampler for this wordlist. /// /// The word sampler may be used to pull any number of random words from the wordlist for /// passphrase generation. pub fn sampler(&self) -> WordSampler { WordSampler::new(self.words.clone()) } } impl Default for WordList { /// Construct a default wordlist. /// /// This uses the built-in EFF large wordlist, which can be constructed with /// [`WordList::builtin_eff_large()`](WordList::builtin_eff_large). fn default() -> WordList { WordList::builtin_eff_large() } } /// A [`WordList`](WordList) error. #[derive(Error, Debug)] pub enum WordListError { /// Failed to load a wordlist from a file. #[error("failed to load wordlist from file")] Load(#[from] std::io::Error), /// A loaded wordlist is emtpy, which is not allowed. #[error("loaded wordlist did not contain words")] Empty, } /// An iterator uniformly sampling words. /// /// This sampler uses a given wordlist of wich random words are picked for use in passphrases. /// The randomization is concidered cryptographically secure. /// /// The iterator is infinite, as much words as needed may be pulled from this iterator. /// /// To construct an instance based on a [`WordList`](WordList), use the /// [`sampler`](WordList::sampler) method. // TODO: use string references #[derive(Clone, Debug)] pub struct WordSampler { /// List of words that is used for sampling. words: Vec, /// Random distribution used for sampling. distribution: Uniform, } impl WordSampler { /// Build a new word sampler which samples the given word list. pub fn new(words: Vec) -> WordSampler { WordSampler { distribution: Uniform::new(0, words.len()), words, } } /// Sample a random word by reference. /// /// This returns a cryptographically secure random word by reference, which is faster than /// [`word`](WordSampler::word) as it prevents cloning the chosen word. fn word_ref(&self) -> &str { // Used instead of `rng.choose` for better performance &self.words[rand::thread_rng().sample(self.distribution)] } } impl WordProvider for WordSampler { fn word(&self) -> String { self.word_ref().to_owned() } } impl HasEntropy for WordSampler { fn entropy(&self) -> Entropy { Entropy::from_real(self.words.len() as f64) } } impl IntoIterator for WordSampler { type Item = String; type IntoIter = WordSamplerIter; fn into_iter(self) -> Self::IntoIter { WordSamplerIter { sampler: self } } } pub struct WordSamplerIter { sampler: WordSampler, } impl Iterator for WordSamplerIter { type Item = String; fn next(&mut self) -> Option { Some(self.sampler.word()) } }