Packages
Secure, memorable password generation using the XKPasswd method. Combines random words with configurable transforms to create strong, easy-to-remember passwords. Zero runtime dependencies, uses only Elixir stdlib and :crypto.
Current section
Files
Jump to
Current section
Files
exk_passwd
CONTRIBUTING.md
CONTRIBUTING.md
# Contributing to ExkPasswd
Thank you for considering contributing to ExkPasswd! This document provides guidelines and information to help you get started.
---
## Interactive Developer Guide
We've created an **interactive Livebook notebook** to help you understand the codebase and experiment with changes in real-time:
[](https://livebook.dev/run?url=https%3A%2F%2Fgithub.com%2Ffuthr%2Fexk_passwd%2Fblob%2Fmain%2Fnotebooks%2Fcontributing.livemd)
**Why use the interactive notebook?**
* **Immediate feedback** - Test your changes without running the full test suite
* **Explore architecture** - See how Dictionary, Password, Config, and Transforms work together
* **Run examples live** - Execute code while reading documentation
* **Safe experimentation** - Try ideas without modifying the actual codebase
* **Performance testing** - Verify O(1) lookups and benchmark your changes
The notebook covers:
- Project structure and architecture
- Key design patterns (schema-driven config, Transform protocol, O(1) lookups)
- Security verification (cryptographic randomness, entropy analysis)
- Creating custom presets and transforms
- Testing edge cases
- Performance benchmarking
---
## How Can I Contribute?
### Reporting Bugs
Before creating bug reports, please check existing issues as you might find out that you don't need to create one. When you are creating a bug report, please include as many details as possible:
* **Use a clear and descriptive title**
* **Describe the exact steps to reproduce the problem**
* **Provide specific examples to demonstrate the steps**
* **Describe the behavior you observed and what behavior you expected**
* **Include your environment details** (Elixir version, OS, etc.)
### Suggesting Enhancements
Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion, please include:
* **Use a clear and descriptive title**
* **Provide a detailed description of the suggested enhancement**
* **Provide specific examples to demonstrate the enhancement**
* **Describe the current behavior and expected behavior**
* **Explain why this enhancement would be useful**
### Pull Requests
1. Fork the repo and create your branch from `main`
2. Add tests for any new functionality
3. Ensure the complete quality gate passes (`mix check`)
4. Use focused checks such as `mix test`, `mix format`, and `mix credo` while iterating
5. Write clear, descriptive commit messages
6. Issue that pull request!
## Development Setup
1. **Fork and clone the repository**
```bash
git clone https://github.com/futhr/exk_passwd.git
cd exk_passwd
```
2. **Install dependencies**
```bash
mix deps.get
```
3. **Run tests to ensure everything is working**
```bash
mix test
```
## Development Workflow
### Running Tests
```bash
# Run all tests
mix test
# Run tests with coverage
mix coveralls.html
# Run tests in watch mode
mix test.watch
# Run specific test file
mix test test/exk_passwd/password_test.exs
```
### Code Quality
```bash
# Format code
mix format
# Run Credo for style consistency
mix credo --strict
# Run Dialyzer for type checking
mix dialyzer
# Run the complete required gate, including coverage and documentation warnings
mix check
```
### Building Documentation
```bash
# Generate docs
mix docs
# View docs
open doc/index.html
```
## Project Structure
```
lib/exk_passwd/
├── config/ # Configuration system
│ ├── presets.ex # Built-in presets (Agent-based)
│ └── schema.ex # Configuration validation
├── transform/ # Transform protocol implementations
│ ├── case_transform.ex
│ └── substitution.ex
├── config.ex # Configuration struct (schema-driven)
├── dictionary.ex # ETS-backed word storage (O(1) lookups)
├── password.ex # Core password generation engine
├── batch.ex # Optimized batch generation
├── token.ex # Random number/symbol generation
├── buffer.ex # Buffered random bytes for performance
├── entropy.ex # Entropy calculation
├── strength.ex # Password strength analysis
├── transform.ex # Transform protocol definition
├── validator.ex # Configuration validation
└── random.ex # Cryptographically secure random utilities
```
## Testing Guidelines
### Writing Tests
* Write tests for all public functions
* Include both success and error cases
* Use descriptive test names
* Aim for 95%+ test coverage (100% for security-critical code)
* Test randomness and uniqueness for password generation
Example test structure:
```elixir
describe "generate/1" do
test "generates password with default settings" do
password = ExkPasswd.generate()
assert is_binary(password)
assert String.length(password) > 0
end
test "generates different passwords each time" do
passwords = for _ <- 1..10, do: ExkPasswd.generate()
assert length(Enum.uniq(passwords)) == 10
end
test "generates unique passwords at scale" do
passwords = for _ <- 1..1000, do: ExkPasswd.generate()
unique_count = passwords |> Enum.uniq() |> length()
# Allow tiny collision chance
assert unique_count > 995
end
end
```
## Coding Style
The library and its test suite support Elixir 1.16+. Run development tools and
`mix check` with the current Elixir release; some development dependencies
require Elixir 1.18 or newer. Compatibility CI sets `MIX_ENV=test` to keep those
tools out of minimum-version builds.
### Elixir Style Guide
* Use pattern matching over conditionals when possible
* Keep functions under 20 lines
* Use descriptive variable and function names
* Write `@moduledoc` and `@doc` documentation for every public module and function
* Include doctests in documentation
* Prefer pipelines over nested calls
### Commit Messages
We follow conventional commits:
* `feat:` New feature
* `fix:` Bug fix
* `docs:` Documentation changes
* `style:` Formatting, missing semicolons, etc.
* `refactor:` Code restructuring
* `test:` Adding tests
* `chore:` Maintenance tasks
Examples:
```
feat: add passphrase generation
fix: handle edge case in strength checker
docs: update README with examples
test: add integration tests for validator
```
## Project Principles
ExkPasswd follows these core principles:
### 1. Security First
- **Always use cryptographically secure randomness** (`:crypto.strong_rand_bytes/1`)
- **Never use** `Enum.random/1` or `:rand` module for password generation
- Test randomness and uniqueness thoroughly
### 2. Zero Runtime Dependencies
- Only use Elixir stdlib and `:crypto`
- Dev/test dependencies are acceptable
- No external dependencies for core functionality
### 3. Well-Tested
- Maintain 95%+ overall test coverage
- 100% coverage for security-critical code
- All public API functions must be tested
### 4. Performance Matters
- Dictionary uses O(1) lookups (tuple-based)
- Batch generation uses buffered random bytes
- Run benchmarks to verify performance
## Documentation
* All public modules must have `@moduledoc`
* All public functions must have `@doc` with examples
* Include doctests where appropriate
* Update README.md for user-facing changes
* Update CHANGELOG.md following Keep a Changelog format
## Release Process
Releases are managed by maintainers using git_ops:
1. Ensure the complete quality gate passes: `mix check`
2. Run `mix release` (alias for `mix git_ops.release`) — updates changelog, bumps version, commits, and tags
3. Push with tags: `git push --follow-tags`
4. CI verifies the exact version tag and tagged commit, reruns `mix check`, and
exposes the Hex API key only to the publish step
## Resources
### Documentation
- [README](README.md) - Project overview
- AGENTS.md (in repository root) - Agent guidelines and best practices
- [Hex Docs](https://hexdocs.pm/exk_passwd) - Published documentation
### Interactive Notebooks
- [Quick Start](notebooks/quickstart.livemd) - Basic usage
- [Advanced Usage](notebooks/advanced.livemd) - Custom configurations
- [Security Analysis](notebooks/security.livemd) - Entropy and strength
- [Benchmarks](notebooks/benchmarks.livemd) - Performance testing
- [Contributing](notebooks/contributing.livemd) - **Interactive developer guide**
### References
- [EFF Large Wordlist](https://www.eff.org/deeplinks/2016/07/new-wordlists-random-passphrases)
- [Original Perl Implementation](https://github.com/bbusschots/hsxkpasswd)
- [XKCD Comic #936](https://xkcd.com/936/)
---
## Questions?
- Open an issue on GitHub
- Check existing issues and discussions
- Review the interactive contributing notebook
**Thank you for contributing to ExkPasswd!** 🎉