The `pbkdf2` crate has a lot of features which leads to a combinatorial
explosion in `cargo hack` with `--feature-powerset`.
On the last CI run, `minimal-versions` took 20 minutes:
https://github.com/RustCrypto/password-hashes/actions/runs/21318294427/job/61364340801?pr=829
This switches the `stable-cmd` from using `cargo hack test` to `cargo
hack check`, which should still check all feature combinations build in
a minimal versions scenario but be significantly faster than trying to
test every possible feature combination.
This is the recommended way to use `cargo hack` according to its
developers:
https://github.com/taiki-e/cargo-hack?tab=readme-ov-file#usage
Also bumps `password-hash` to v0.6.0-rc.10, which permits these bounds.
They were previously impl'd using the PHC params syntax, but now that
we've added MCF support (#806) there isn't one-true-serialization that
actually makes sense to use.
In such a case, I think it's best not to impl `Display`/`FromStr` but
instead use format-specific inherent methods and impls for
format-specific types (like `phc::ParamsString`).
For the password hash algorithms that already have a `struct` where we
can impl traits (i.e. any with a `password-hash`/`phc`/`mcf` feature)
adds feature-gated impls of the traits from the new `kdf` crate.
The `Kdf` trait provides a generic API, and `Pbkdf` is a marker trait
for password-based KDFs where a password can be used as a secret input.
These features are literally doing nothing other than linking `std`.
They seem to be vestiges of `std::error::Error`.
- Removes the feature from `bcrypt-pbkdf` completely
- Makes it a no-op in `password-auth`, but doesn't remove it because it
would be a breaking change and it's a post-1.0 crate
Adds an `alloc` feature which is needed to enable MCF hashing
functionality.
The `PasswordVerifier<mcf::PasswordHashRef>` impl now works without any
dependency on liballoc.
I discovered these test vectors from a Go port of Passlib:
https://github.com/hlandau/passlib/blob/8f820e0/hash/pbkdf2/pbkdf2_test.go
...and also checked against the Python implementation of Passlib itself,
and discovered PBKDF2 seems to use its own variant of Base64 which is
distinct from the ones used by bcrypt/crypt, namely it's a variant of
unpadded Base64 which swaps `+` for `.`
This implements this Base64 variant, and also adds a test vector from
the Go implementation of Passlib for PBKDF2-SHA-512.
Changes this constructor to allow it to customize both the algorithm and
params, leaving `From` impls for `Algorithm` and `Params` as the way to
customize one or the other while using defaults for the one not
explicitly specified.
Removes the `D` generic parameter on `ShaCrypt` and replaces it
internally with a new `Algorithm` enum, similar to other crates like
`argon2` and `pbkdf2`, where `ShaCrypt` can now store a default
algorithm.
The verifier impl now dynamically dispatches on the MCF algorithm ID,
and can verify both SHA-256-crypt and SHA-512-crypt hashes.
Prearranged data into 128bit lanes so we don't have to transpose back
and forth in the BlockMix Salsa20 kernel on SSE2.
The permute constants are the same as
https://github.com/RustCrypto/stream-ciphers/blob/07ee501/salsa20/src/backends/soft.rs#L54-L57
read column wise.
After:
> cargo bench
test scrypt_15_8_1 ... bench: 180,070,625.10 ns/iter (+/- 4,549,929.06)
> RUSTFLAGS="-Ctarget-feature=+simd128" cargo bench --target wasm32-wasip1
test scrypt_15_8_1 ... bench: 118,944,571.20 ns/iter (+/- 3,098,151.70)
> ssh cheap_vps cargo bench
test scrypt_15_8_1 ... bench: 304,886,161.00 ns/iter (+/- 6,625,867.19)
Before:
> cargo bench
test scrypt_15_8_1 ... bench: 230,760,302.00 ns/iter (+/- 8,838,571.54)
> RUSTFLAGS="-Ctarget-feature=+simd128" cargo bench --target wasm32-wasip1
test scrypt_15_8_1 ... bench: 190,474,545.40 ns/iter (+/- 5,895,216.01)
> ssh cheap_vps cargo bench
test scrypt_15_8_1 ... bench: 409,880,353.40 ns/iter (+/- 17,629,444.54)
Picked from my own performance oriented implementation:
https://github.com/eternal-flame-AD/scrypt-opt
`rayon` is an implementation detail of parallel password hash
computation, not the actual feature.
`parallel` matches the existing `argon2` crate feature.