//! This crate implements arbitrary deterministic secret generation from a fixed seed password.
//!
//! The core, basic idea here is that a password schema should be enumerable: e.g. the schema
//! `[a-z]` generates 26 different passwords, the first one is `'a'`, and the last is `'z'`. So
//! then if we can count the size of the universe of passwords generated by a schema, then we can
//! use a cryptographically secure pseudorandom number generator to sample it based on a
//! deterministic secret, yielding a deterministic output.
//!
//! The other main piece of this password generation scheme entails securely deriving a per-site
//! secret from a single seed password, thereby stretching one secret into an arbitrary number of
//! secrets. We do this by taking a [password hash][0] of the seed password against a salt that
//! consists of the full derivation parameters for the site in question; e.g. the site URL,
//! username, and the schema from which the password is generated. Any changes to the derivation
//! should therefore result in securely different secrets, meaning that generally a compromised
//! site password should reveal no information about either the seed password or other site
//! passwords.
//!
//! Combining these ideas then, usage of this library collapses the state for a password manager
//! from `O(n)` secret state, where n is the number of sites for which a user has passwords, to
//! `O(1)` secret state (the seed) plus `O(n)` non-secret state (the public site derivation
//! parameters.) This makes migration much easier and safer than with traditional password
//! managers; a user may simply upload or copy their site derivation info and write down or
//! memorize their seed password.
//!
//! A lot of this crate, then, is about canonical serialization of site parameters and schemas such
//! that derivation paths may be deterministically re-derived from configuration. E.g. we normalize
//! URLs and we specify a canonical formatting of password schemas.
//!
//! This scheme is designed to be user-extensible; crate users may add their own custom secret
//! generators to extend this library into other domains. This is done via
//! <code>[Generator]</code>s. A `Generator` may extend a password schema with specific extra
//! configuration, e.g. a hash of a word list, to ensure that derivations that are different
//! produce uncorrelated passwords.
//!
//! The derivation parameters saved per-site are the (mandatory) URL, an optional username, the
//! password schema, and a nonce (called the “increment” in this crate.) The purpose of the nonce
//! is to make it easy to rotate a site password if one is ever compromised, or to comply with
//! rotation policies; simply incrementing the nonce should yield an uncorrelated, new password for
//! that site from the same seed.
//!
//! ```no_run
//! use onepass_seed::site::Site;
//! # use secrecy::ExposeSecret;
//! let site = Site::new("google.com", None, "{words:4:-}", 0).unwrap();
//! let pw = site.password("seedpass").unwrap();
//! assert_eq!("jaywalker-diffused-verse-abdominal", pw.expose_secret());
//! ```
//!
//! For more information on the schema language see <code>[Expr]</code>.
//!
//! [0]: https://en.wikipedia.org/wiki/Bcrypt
//! [Generator]: expr::Generator
//! [Expr]: expr::Expr

mod crypto;
pub mod dict;
pub mod expr;
mod macros;
pub mod site;
pub mod url;

pub use crypto_bigint::U256;
pub use secrecy::{ExposeSecret, ExposeSecretMut, SecretBox, SecretString};
