ExkPasswd is designed with security as the highest priority. This document outlines the security measures, testing methodology, and known considerations.
All randomness uses :crypto.strong_rand_bytes/1 with rejection sampling to eliminate modulo bias:
# Unbiased random integer generation
def integer(max) do
range_size = 0x1_0000_0000 # 2^32
threshold = range_size - rem(range_size, max)
integer_unbiased(max, threshold)
end
defp integer_unbiased(max, threshold) do
value = :crypto.strong_rand_bytes(4) |> :binary.decode_unsigned()
if value < threshold, do: rem(value, max), else: integer_unbiased(max, threshold)
endBenefits:
- Perfectly uniform distribution (no modulo bias)
- Cryptographically secure randomness
- Verified via chi-square statistical tests
- Zero performance impact (rejection rate < 0.001%)
- Uses EFF Large Wordlist (7,826 words)
- Pre-computed at compile time for O(1) access
- All words verified reachable through statistical testing
- No filtering bias detected
Run comprehensive security tests:
# All security tests
mix test test/exk_passwd/security_test.exs
# Adversarial attack simulations
mix test test/exk_passwd/adversarial_test.exsThe test suite simulates real attack scenarios:
- Statistical bias detection - Chi-square tests for uniformity
- Collision resistance - Birthday attack validation
- State correlation - Batch generation independence
- Dictionary coverage - Complete word space accessibility
- Entropy validation - Collision rate analysis
- Pattern detection - ML-resistant password structure
- Distribution analysis - Word length, digits, case transforms
- Parallel safety - Process independence verification
Test Coverage: 97.1% with 473 tests (60 doctests + 413 unit tests), all passing.
Theoretical entropy is calculated assuming:
- Perfect uniform random selection
- Known configuration parameters
- EFF Large Wordlist (7,826 words)
For 4-word password: ~52 bits of entropy (2^52 ≈ 4.5 quadrillion combinations)
Public presets (:default, :xkcd, :wifi, etc.) have predictable structure.
Recommendation: Use custom Config for high-security applications:
config = Config.new!(
num_words: 5,
separator: "+",
word_length: 6..9,
case_transform: :random,
digits: {3, 3}
)
password = ExkPasswd.generate(config)- Preset fingerprinting - Passwords generated with public presets can be identified by structure
- Dictionary knowledge - Attackers knowing the EFF wordlist reduces search space
- Configuration leakage - Password structure reveals some configuration parameters
These are inherent to structured passphrases, not implementation bugs.
Mitigation: Users should use custom configurations for sensitive applications.
If you discover a security vulnerability:
- DO NOT open a public GitHub issue
- Email security concerns to the maintainers
- Include clear reproduction steps
- Allow reasonable time for a fix before disclosure
Validates uniform distribution of random values:
chi_square = Enum.reduce(frequencies, 0, fn {_, observed}, acc ->
acc + :math.pow(observed - expected, 2) / expected
end)
# For df degrees of freedom at 99.9% confidence:
critical_value = df + :math.sqrt(2 * df) * 3.29
assert chi_square < critical_valueValidates entropy claims via birthday paradox:
# Generate samples, check collision rate
unique = Enum.uniq(passwords) |> length()
collision_rate = (total - unique) / total
# Should be near 0 for high-entropy passwords
assert collision_rate < 0.001- Use custom configs for sensitive applications (avoid public presets)
- Increase word count for higher security (6+ words recommended)
- Add randomization to separators and padding when possible
- Monitor entropy using
ExkPasswd.Entropy.calculate/2orExkPasswd.Strength.analyze/2
- Never use
:randmodule - always useExkPasswd.Random - Avoid Enum.random/1 - not cryptographically secure
- Run security tests before committing:
mix test test/exk_passwd/security_test.exs - Maintain test coverage >90% overall, 100% for crypto code
ExkPasswd follows NIST SP 800-63B recommendations:
- ✅ Minimum 64 bits entropy for high-value passwords (achieved with 5+ words)
- ✅ Cryptographically secure random number generation
- ✅ No weak patterns or predictable structures
- ✅ Resistance to dictionary attacks (large word space)
- ✅ Use of secure random number generator
- ✅ Sufficient entropy for password generation
- ✅ No hardcoded secrets or predictable patterns
- ✅ Regular security testing and validation
For security-related questions or concerns, please contact the maintainers through the project's GitHub repository.
Last Updated: 2025-10-29