Repository navigation
v0.10.0
-
Make short AES-128-GCM-SIV sealing faster on x86-64 CPUs with VAES and VPCLMUL.
Secret cleanup does not change. -
Use the portable Argon2 compression on AArch64.
Native measurements showed that it is faster than the NEON backend. -
Add
Argon2Block,Argon2Params::memory_blocks, and these methods onArgon2d,Argon2i, andArgon2id:derive_with_memory,derive_with_context_and_memory, andverify_with_memory.
They borrow work memory from the caller instead of allocating it.
Callers can reuse the memory across operations, or take it from any allocator.
The operation ignores the initial contents, and clears every block it uses before it returns.
If the memory is too short, the operation returns the newArgon2Error::MemoryTooSmall. -
On AArch64 cores with
FEAT_DIT, set Arm data-independent timing (PSTATE.DIT) during X25519, Ed25519, ECDSA,
P-256 and P-384 ECDH, ML-KEM, ML-DSA, RSA private operations, Argon2, scrypt, and PBKDF2.
The caller's state is restored after each operation.
Addtraits::ct::with_data_independent_timing, which sets DIT for a scope that the caller selects.
Use it to cover short symmetric operations without a toggle on each call. -
The package now pins the upstream source and SHA-256 of the ChaCha20-Poly1305 and BLAKE3 x86-64 assembly that
derives from AWS-LC and BLAKE3, as it already did for the RSA and signature assembly.
The x86-64 ChaCha20-Poly1305 assembly now carries the CloudFlare copyright notice of its upstream source. -
Add
Blake3::digest_batch, which hashes many independent inputs in one call.
Runs of inputs with equal length, from 1 to 1,024 bytes, share SIMD lanes
(SSE4.1, AVX2, AVX-512, and NEON).
Other inputs, and targets without those kernels, use the one-shot path.
For every input, the output is equal toBlake3::digest. -
Add
Blake3DeriveContext, a BLAKE3 key-derivation context that is hashed only once, withBlake3::derive_key_withandBlake3::new_derive_key_from.
Build it at compile time withBlake3DeriveContext::new_const(for contexts of at most 1,024 bytes), or at run time withBlake3DeriveContext::new.
The outputs are equal toBlake3::derive_keyandBlake3::new_derive_key, without hashing the context on each call. -
Add
Blake3::digest_const, which computes the unkeyed BLAKE3 digest of at most 1,024 bytes in a constant context.
Callers can use it to build digest tables at compile time.
It uses the same portable compression code as the runtime portable backend.
Longer inputs panic, which makes the build fail in a constant context. -
Make keyed BLAKE3 one-shot hashing faster.
It no longer repeats dispatch, input handling, secret-key handling, or full compression-output work.
Cleanup does not change. -
Add BLAKE3 subtree hashing in
hashes::expert::blake3_tree.
Blake3Treehashes chunk-aligned parts of one input independently intoBlake3ChainingValues.
It then merges them into the same root hash, keyed hash, derived key,
or XOF output as one-shot hashing.
Each chaining value records its input range and mode.
An invalid offset, an oversized subtree,
or a merge that is not a BLAKE3 parent node returns aBlake3SubtreeErrorinstead of an unrelated hash. -
Add
Blake3XofReader::positionandBlake3XofReader::set_positionfor random access into BLAKE3 output.
A seek moves to any byte offset of the output stream, forward or backward,
without producing the bytes before it.
It matchesOutputReader::set_positionof the upstreamblake3crate in hash, keyed, and derive-key modes. -
Reduce the CRC-32 and CRC-64 selection diagnostics to these fields: polynomial, input length,
architecture, selection reason, effective force setting, and selected kernel.
Remove old policy thresholds, stream counts, capability flags,
and placeholder values that no longer described active dispatch.
Remove the unusedSelectionReason::BelowSmallThresholdandBelowSimdThresholdvariants.
The numeric discriminants of the remaining selection reasons change.
Checksum computation and backend selection do not change. -
Remove the migration guide and the broad API tours.
Keep the current API contracts, feature selection, secret ownership,
and focused runnable examples in the documentation that owns them.
Correct the platform coverage and the limits of retained evidence.
Update the installation examples for v0.10, and remove temporary notes about development versions.
Rewrite the guides in short, direct technical English, and correct stale evidence statements.
Document the modulus lengths thatRsaPrivateKey::generateaccepts, and how to generate an RSA-2048 compatibility key. -
Add
EcdsaP256PublicKey::verify_sha384andEcdsaP384PublicKey::verify_sha256for explicit P-256/SHA-384 and P-384/SHA-256 signature verification.
The existingverifymethods keep their P-256/SHA-256 and P-384/SHA-384 behavior. -
Keep masked ECDSA point selection on AArch64 and Windows,
and masked secret selection in portable P-256.
Use ECDSA table traversal with fixed bounds.
Keep RISC-V generator-table loads unconditional under LLVM optimization.
Signature behavior does not change.Make portable P-256 public derivation and agreement faster with RV64-shaped multiplication,
sparse field arithmetic, and shared fixed-base tables.
ECDH and signature behavior do not change. -
Remove secret-dependent branches from Ed25519 scalar arithmetic on RISC-V.
On RV64GC, checked 128-bit additions on secret-derived carries compiled to branches.
The bounded arithmetic now uses wrapping operations.
Signatures and public APIs do not change. -
Expose fallible P-256 and P-384 blinded signing
and public-key derivation with entropy from the caller.
Removepublic_key_blindedandtry_sign_blinded.
The supported entry points aretry_public_key_blinded_withandtry_sign_blinded_with.
They report an entropy failure before any private arithmetic.Add direct-fill constructors for
SecretBytesandSecretVec,
and ownership transfer fromVecandStringthat keeps the existing allocation. -
Keep Ed25519 and X25519 building on x86-64 Linux with every supported compiler
when the assembly backend owns fixed-base dispatch.
Keep standalone AEAD features lint-clean on Linux.
When SIMD128 is disabled, exclude SIMD backends from scalar WebAssembly hash, AEAD,
and Argon2 dispatch. -
Limit ordinary
diagbuilds to capability and backend-selection introspection.
Remove benchmark, forced-kernel, constant-time, zeroization,
and component operations from ordinary public module paths, re-exports, and associated methods.
This covers AEADs, MACs, KDFs, password hashing, signatures, key agreement, RSA, ML-KEM,
and cryptographic hashes.
It includes the RSA seeded diagnostic encryption methods, the BLAKE3 diagnostic selectors,
the SHA-256 benchmark compression helper, and the diagnostic-onlyArgon2Error::BackendUnavailablevariant.
Removing that variant changes the numeric discriminant ofVerificationLimitTooLowin ordinarydiagbuilds withphc-strings.Repository evidence tools keep explicit internal access.
Internal PBKDF2 verification probes now exercise the primitive,
instead of being rejected by the application password policy because of their fixed parameters.
Application cryptographic operations do not change. -
Copy complete SHAKE output lanes directly into the caller's buffer.
Do not use a temporary lane byte array when extracting a short output tail. -
Make ML-DSA forward and inverse transforms faster with NEON on macOS AArch64.
The portable fallback and byte-for-byte results do not change.
Merge the portable forward-transform conversion into the first butterfly to remove repeated
arithmetic.Make fixed-work ML-DSA challenge selection parallel, with a minimum reduction.
Memory access stays independent of secrets, and failure stays bounded.Make matrix-product accumulation faster with four-lane NEON on macOS AArch64.
Batch public matrix expansion through paired SHAKE on macOS AArch64.
portable-onlyand other targets keep scalar expansion.
Private polynomial cleanup does not change.
The accelerated row path uses one more public polynomial buffer. -
Require evidence for the ML-DSA secret kernels in the constant-time harness.
Cover all parameter sets with production timing adapters, retained linked-binary roots,
and a bounded proof root for the portable Montgomery multiplication.
The existing sample budgets and thresholds do not change.
Whole signing keeps its variable retries, and stays outside a strict constant-time claim.Protect x86-64 scalar selections and secret sampler masks from branches that the compiler creates.
The standard arithmetic and sampling order do not change.Follow direct tail transfers when building linked-code call closures,
so that optimized evidence wrappers cannot hide the production kernel from assembly review. -
Add original ML-DSA arithmetic for Linux IBM Z and little-endian POWER8,
with CPU and OS capability checks.
Add it also for RISC-V32 and RISC-V64 with compile-time M support.
The targets share the vector transform schedule.
The portable fallback, public APIs, encodings, canonical coefficients,
and secret-owner cleanup do not change.Keep scalar ML-DSA reduction and selection masks opaque to the compiler on IBM Z and RISC-V,
includingportable-onlybuilds, without forcing the masks through memory.
Protect the secret-candidate minimum of the challenge sampler on these targets too. -
Clear the dead stack below ML-DSA's private SHAKE256 helper after each call.
This removes Keccak lane spill copies that the compiler creates and
that named state wipes cannot reach.
Capability detection now runs before the helper.
The first call in a process therefore no longer initializes the detection cache below the cleared
region.
Outputs and public APIs do not change. -
Make ML-DSA transforms and matrix-product accumulation faster: with AVX2, selected at run time,
on Linux x86-64, and with compile-time NEON on Linux AArch64.
The portable fallback, public APIs, encodings, and byte-for-byte results do not change.
The Linux NEON inverse middle stage stays out of line,
to prevent the coefficient spills seen in the reviewed build. -
Remove secret-coefficient branches from ML-DSA secret-noise coefficient mapping in IBM Z release
builds.
The eta=2 reduction now uses a multiply-shift without comparisons.
The final modular correction uses the shared register-barrier reduction.
Outputs, sampling order, and public APIs do not change. -
Add original portable ML-DSA-44, ML-DSA-65, and ML-DSA-87 signatures under the
ml-dsafeature.
They support explicit deterministic and hedged signing, contexts, HashML-DSA, strict encodings,
prepared keys, and core-only operation.With
alloc,keypair_from_seed_in,generate_keypair_in,try_generate_keypair_in, andSecretKey::try_from_slice_inwrite the secret key directly into a box from an allocator
that the caller selects.
Moves then leave no by-value copies of the key.Prepared keys fill storage that the caller owns, in place.
ConstructMlDsa{44,65,87}Prepared{Secret,Public}KeyStorage::new()where the storage should live, then callprepare(&mut storage).
Preparation needs at most 4 KiB of measured stack, instead of holding two copies of a prepared owner
(up to 163 KiB for ML-DSA-87).Remove unguarded byte-array temporaries from the partial Keccak lane extraction
that secret SHAKE operations use.Decode prepared ML-DSA signing state directly into its caller-owned storage,
without secret-bearing construction temporaries.Remove repeated inverse-NTT reductions.
Outputs stay canonical.Do not compute unused low remainders when ML-DSA signing needs only the high bits.
-
Protect POWER ML-DSA scalar selections and sampler masks from secret-dependent branches
that the compiler creates.
The register barrier applies to native andportable-onlybuilds.
Arithmetic, sampling order, and timing-test requirements do not change.Blind the POWER vector forward NTT of secret polynomials with a mask derived from the secret seed,
so that repeated small coefficients never reach the vector multiplier.
Signatures and keys do not change. -
Keep the ML-DSA secret-noise acceptance masks and counts inside zeroizing scratch owners.
Sampling order, bounded work, public APIs,
and the existing timing and cleanup claim boundaries do not change. -
Keep ML-DSA SHAKE256 finalization and squeezing inside a local zeroizing reader,
so that no temporary with secret state is returned.
Sampler output, public hash APIs,
and the existing cleanup and constant-time claim boundaries do not change. -
Add the ML-KEM functions
generate_keypair_in,try_generate_keypair_in,DecapsulationKey::try_from_slice_in, andDecapsulationKey::prepare_in.
Withalloc, they take anAllocatorand write the decapsulation key or prepared key directly into itsBox,
so that no by-value copy of the secret stays behind.
On QEMU RV32 and Cortex-M, generating, importing,
or preparing a key by value leaves up to a full secret-key copy in the caller's dead stack.
The new constructors leave none, on the stack or in the freed allocation.
The by-value constructors stay for core-only use. -
Clear the dead stack below ML-KEM's secret SHA-3 and SHAKE calls
(G, J, and the PRF) after each call, as ML-DSA does.
This removes Keccak lane spill copies of seeds, messages,
and the implicit-rejection secret that the compiler creates and that named state wipes cannot reach.
Outputs and public APIs do not change.
Public SHA-3 and SHAKE hashing is not scrubbed. -
Mask the decryption inverse NTT in prepared ML-KEM decapsulation keys.
Preparation derives a secret dense polynomial from the implicit-rejection secret.
Decryption adds it before the inverse NTT, and the fused final pass of the transform removes it.
A ciphertext therefore cannot make the transform process sparse data.
Outputs and the work for each call do not change.
One-shot decapsulation does not change. -
Add standalone
no_stdP-256 ephemeral Diffie-Hellman under thep256-ecdhfeature.
It validates canonical uncompressed SEC1 peer points,
generates scalars with a bounded fallible loop, and uses zeroizing secret owners that are notClone.
Assembly derived from s2n-bignum accelerates it on Apple and Linux AArch64,
and on Linux and Windows x86-64 (baseline and BMI2/ADX).
RV64 uses accelerated field arithmetic.
Other targets use the safe Rust implementation. -
Add the
p384-ecdhfeature with ephemeral P-384 Diffie-Hellman key agreement:P384EphemeralSecret,P384PublicKey,P384SharedSecret,P384KeyGenerationError, andP384PublicKeyError.
Peer keys must be canonical uncompressed SEC1 points on the curve.
Thekey-exchangeumbrella feature now enablesp384-ecdh. -
With the
portable-onlyfeature, or under Miri, ECDSA no longer calls its AArch64 and x86-64 assembly.
It uses the portable Rust implementation, as other targets do.
HKDF-SHA256 uses its AArch64 SHA2 single-block path only when the build enablestarget_feature = "sha2"and not
portable-only. -
Keep the standalone fuzz and evidence-tool lockfiles at the
rscryptoversion during release preparation. -
Remove Intel macOS from the supported target catalog.
Apple Silicon is now the only supported macOS architecture. -
Remove
verify_with_policyandverify_password_with_policyfrom PBKDF2-SHA256 and PBKDF2-SHA512.
Explicit password policies useverify_with_policy_boundedandverify_password_with_policy_bounded, which need an upper iteration limit.
Default password verification and explicit primitive operations stay.Bounded PBKDF2 verification now limits total work, not only the iteration count.
EachOUTPUT_SIZEblock ofexpectedcosts one full run ofiterations, so verification fails before derivation wheniterations * expected.len().div_ceil(OUTPUT_SIZE)exceeds the limit.
Before, a stored record with a longexpectedvalue could multiply verification time without bound.
verifyandverify_passwordapply the same rule withMAX_VERIFY_ITERATIONS. -
Remove the retired performance chart and its withdrawn claims from crate packages.
-
RSA decryption now requires
outto hold the longest message the padding admits:k - 11bytes for PKCS#1 v1.5 andk - 2 * profile.digest_len() - 2bytes for OAEP, for ak-byte modulus.
A shorteroutreturnsRsaPrivateOpError::InvalidLengthbefore decryption, whatever the ciphertext.
Before, a shortoutreturnedInvalidLengthonly when the padding was valid andDecryptionFailedotherwise, so an attacker could tell valid padding from invalid padding.
Anoutof modulus length, as in the examples, still works. -
Raise the minimum supported Rust version to 1.100.0,
the release that stabilizes the allocator API subset.
Until Rust 1.100 is stable, build with the 1.100 beta or a newer nightly.
POWER, IBM Z, and RISC-V builds still need a nightly compiler after that.
docs/platforms.mdlists their unstable features.Exclude x86 SIMD backends on soft-float x86-64 targets, such as
x86_64-unknown-none.
Those targets never selected them, because their compile-time capabilities lack SSE2.
The portable backends stay.
Rust is phasing out#[target_feature]SSE functions on soft-float targets. -
Add
ScryptBlock,ScryptParams::memory_blocks,Scrypt::derive_with_memory, andScrypt::verify_with_memory.
They borrow work memory from the caller instead of allocating it.
Callers can reuse the memory across operations, or take it from any allocator.
The operation ignores the initial contents, and clears every block it uses before it returns.
If the memory is too short, the operation returns the newScryptError::MemoryTooSmall. -
Require both SHA and SSE4.1 for SHA-224 SHA-NI dispatch.
SHA-224 now uses the same compression capability policy as SHA-256. -
Move the shared RSA verification fixtures out of the benchmark tree.
Document the provenance, integrity, inventory,
and consumers of the checked-in external test corpora.
Make ChaCha20 forced-backend differential runs report production-derived backend IDs, availability,
and the number of cases run.
Add source, toolchain, suite, environment, and artifact provenance to coverage reports.