# sealwd

`sealwd` provides small, focused primitives for handling secrets safely in Rust. 

Designed specifically for server-side authentication systems, it enforces a strict separation between low-entropy user passwords and high-entropy machine-generated tokens. It handles memory zeroization, secure generation, policy validation, forward-compatible hashing, and optional encryption at rest.

## Core Philosophy & Security Model

Passwords and tokens serve different purposes and require different cryptographic treatments:
* **Passwords** are low-entropy secrets provided by users. They are hashed using **Argon2id** (slow, memory-hard) to resist brute-force attacks.
* **Tokens** are high-entropy, fixed-length secrets generated by the system (e.g., session IDs, API keys). They are hashed using **BLAKE3** (fast) with a server-side pepper. Using token hashing for passwords is mathematically insecure and intentionally unsupported by this crate.

## Features

* **Explicit Secret Types:** Strongly typed `Password` and `Token<LEN>` primitives.
* **Memory Safety:** Secrets are wrapped in containers that automatically zeroize memory on drop.
* **Password Policies:** Configurable rules for generation and validation (length, character classes).
* **Self-Describing Hashes:** Binary serializable hashes (`PasswordHash`, `TokenHash`) with embedded algorithm versions for forward compatibility.
* **Encryption at Rest (Optional):** AEAD encryption (XChaCha20-Poly1305 or AES-256-GCM-SIV) via the `encryption` feature.
* **Framework Integrations (Optional):** Direct `BYTEA` mappings for PostgreSQL via `sqlx`, and transparent `serde` serialization.

## Usage

### Managing Passwords

```rust
use sealwd::{Password, PasswordPolicy};

// 1. Define a policy
let policy = PasswordPolicy::with_sane_defaults();

// 2. Generate a secure random password satisfying the policy
let password = Password::random(&policy).unwrap();

// 3. Hash the password for storage (uses Argon2id automatically)
let hash = password.to_default_hash().unwrap();

// 4. Verify a login attempt
assert!(hash.verify(&password).is_ok());

```

### Managing High-Entropy Tokens

```rust
use sealwd::Token;

// 1. Generate a 32-byte cryptographic token
let token = Token::<32>::random().unwrap();

// 2. Export to URL-safe Base64 to send to the client
let encoded = token.to_base64();

// 3. Hash with a server-side pepper for database storage (uses BLAKE3)
let pepper = b"my-secret-server-pepper-value";
let token_hash = token.to_default_hash(pepper);

// 4. Store `token_hash.to_bytes()` in your database

```

### Encryption at Rest (Requires `encryption` feature)

When storing secrets that must be reversible (e.g., external API keys), you can encrypt them before storage.

```rust
use sealwd::{Token, crypto::CipherSuite};

let token = Token::<16>::random().unwrap();
let encryption_key = b"thisisa32bytekeyforrustcryptolib";

// Encrypt the token using XChaCha20-Poly1305
let encrypted_token = token.encrypt(encryption_key, CipherSuite::XChaCha20Poly1305).unwrap();

// Decrypt back to a strongly-typed Token<16>
let decrypted_token = encrypted_token.decrypt(encryption_key).unwrap();

```

## Feature Flags

* `encryption`: Enables the `crypto` module, providing `EncryptedPassword` and `EncryptedToken` wrappers backed by AEAD ciphers.
* `serde`: Enables transparent serialization/deserialization for domain types.
* `sqlx`: Implements `sqlx::Type`, `Encode`, and `Decode` allowing hashes and encrypted types to be used directly with database queries (maps to `BYTEA` in Postgres).

## License

Apache-2.0
