You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Buttt I couldn't help but notice the same crate offers "ChaCha20", which is 20 rounds of the same algorithm. As the documentation for ChaCha20 notes:
With the ChaCha algorithm it is possible to choose the number of rounds the core algorithm should run. The number of rounds is a tradeoff between performance and security, where 8 rounds is the minimum potentially secure configuration, and 20 rounds is widely used as a conservative choice.
Seeing as Phraze can afford to be a little slower in order to become more secure and more conservative, this PR explicitly uses 20 rounds (ChaCha20).
As expected, doing 20 rounds takes longer -- about 2x longer it turns out.
Hyperfine benchmark
Using Hyperfine to test the performance of the CLI (cargo install --path=. --force && hyperfine -N -w 1000 -m 1000 'phraze'), which we could argue is a more "real world" benchmark, shows a very minor change, in fact within Hyperfine's margin of error.
Using default thread_rng:
Time (mean ± σ): 1.8 ms ± 0.2 ms [User: 1.2 ms, System: 0.5 ms]
Range (min … max): 1.6 ms … 2.9 ms 1596 runs
Using ChaCha20 explicitly:
Time (mean ± σ): 1.7 ms ± 0.1 ms [User: 1.1 ms, System: 0.5 ms]
Range (min … max): 1.6 ms … 2.4 ms 1757 runs
This is almost certainly because the passphrase generation function itself makes up a relatively small amount of the total time it takes to run the command phraze.
Open questions
What do other password generators use here? I can't tell from a glance at the KeePassXC codebase.
Pros of accepting this PR
Phraze's code becomes more explicit in which PRNG it uses (rather than rely on an alias)
20 rounds may be overkill, but it's clearly more secure than 12 rounds, and the change seems to affect Phraze's overall performance only minimally (see above).
Gives a little future-proof security (though see below for counterargument)
Cons of accepting this PR
Makes Phraze more difficult to maintain: By not using the thread_rng alias, we are relying on Phraze maintainers (me?) to keep up with latest best practice for which PRNG and how many rounds are suitable. In contrast, if we stuck with the alias and just kept upgrading the version of the rand crate that Phraze depends on, we'd probably always be using a good PRNG, with a "good enough" number of rounds.
Security must be considered relative to a threat model and validation requirements. ThreadRng attempts to meet basic security considerations for producing unpredictable random numbers: use a CSPRNG, use a recommended platform-specific seed ([OsRng]), and avoid leaking internal secrets e.g. via [Debug] implementation or serialization. Memory is not zeroized on drop.
While I thinkfrom_entropy() uses a platform-specific seed, I don't know if this PR "avoid[s] leaking internal secrets"? I'd assume so, but it scares me a bit that I'm left confused.
I've updated this PR in light of some changes in rand v0.9.0 that may or may not affect Phraze. Comments and advice welcome. The fundamental question remains similar though:
Which of these two methods of creating an RNG should Phraze use to generate passphrases?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phraze currently uses
thread_rngfrom Rust's rand crate as its pseudo random number generator.I think
thread_rng, "under the hood," uses a stream cipher called ChaCha12 -- here's as much proof I could find in the source code. From what I can tell, this is a good choice!Buttt I couldn't help but notice the same crate offers "ChaCha20", which is 20 rounds of the same algorithm. As the documentation for ChaCha20 notes:
Seeing as Phraze can afford to be a little slower in order to become more secure and more conservative, this PR explicitly uses 20 rounds (ChaCha20).
However! Here's a long discussion among rand crate stake holders arguing that 12 rounds is enough and that 20 is overkill!. But I still thought it'd be interesting to make this PR public and open and see if anyone has any thoughts.
Implementation
I think
is the method we want to use, given this description:
How this change would affect Phraze performance
Criterion benchmark
Using default
thread_rng:Using ChaCha20 explicitly:
As expected, doing 20 rounds takes longer -- about 2x longer it turns out.
Hyperfine benchmark
Using Hyperfine to test the performance of the CLI (
cargo install --path=. --force && hyperfine -N -w 1000 -m 1000 'phraze'), which we could argue is a more "real world" benchmark, shows a very minor change, in fact within Hyperfine's margin of error.Using default
thread_rng:Using ChaCha20 explicitly:
This is almost certainly because the passphrase generation function itself makes up a relatively small amount of the total time it takes to run the command
phraze.Open questions
What do other password generators use here? I can't tell from a glance at the KeePassXC codebase.
Pros of accepting this PR
Cons of accepting this PR
thread_rngalias, we are relying on Phraze maintainers (me?) to keep up with latest best practice for which PRNG and how many rounds are suitable. In contrast, if we stuck with the alias and just kept upgrading the version of therandcrate that Phraze depends on, we'd probably always be using a good PRNG, with a "good enough" number of rounds.