From ecec40c7f59e3c805e0b373939175c466f9e2863 Mon Sep 17 00:00:00 2001 From: LoadingALIAS Date: Tue, 21 Jul 2026 22:14:10 -0400 Subject: [PATCH] docs: align public guidance with current release --- CONTRIBUTING.md | 12 ++++++++---- README.md | 4 ++-- SECURITY.md | 2 +- THREAT_MODEL.md | 14 +++++++++----- docs/compliance.md | 5 +++-- docs/features.md | 16 ++++++++-------- docs/migration/README.md | 6 +++--- docs/migration/RustCrypto/aes-gcm-siv.md | 8 ++++---- docs/migration/RustCrypto/aes-gcm.md | 10 +++++----- docs/migration/RustCrypto/argon2.md | 4 ++-- docs/migration/RustCrypto/ascon-aead.md | 10 +++++----- docs/migration/RustCrypto/ascon-hash.md | 8 ++++---- docs/migration/RustCrypto/blake2.md | 8 ++++---- docs/migration/RustCrypto/chacha20poly1305.md | 10 +++++----- docs/migration/RustCrypto/ed25519-dalek.md | 8 ++++---- docs/migration/RustCrypto/hkdf.md | 8 ++++---- docs/migration/RustCrypto/hmac.md | 8 ++++---- docs/migration/RustCrypto/p256.md | 6 +++--- docs/migration/RustCrypto/p384.md | 6 +++--- docs/migration/RustCrypto/pbkdf2.md | 8 ++++---- docs/migration/RustCrypto/rsa.md | 4 ++-- docs/migration/RustCrypto/scrypt.md | 4 ++-- docs/migration/RustCrypto/sha2.md | 8 ++++---- docs/migration/RustCrypto/sha3.md | 8 ++++---- docs/migration/RustCrypto/x25519-dalek.md | 8 ++++---- docs/migration/aegis.md | 8 ++++---- docs/migration/aws-lc-rs.md | 2 +- docs/migration/blake3.md | 8 ++++---- docs/migration/crc-fast.md | 8 ++++---- docs/migration/crc.md | 8 ++++---- docs/migration/crc32c.md | 6 +++--- docs/migration/crc32fast.md | 6 +++--- docs/migration/crc64fast.md | 8 ++++---- docs/migration/dryoc.md | 2 +- docs/migration/openssl.md | 2 +- docs/migration/rapidhash.md | 8 ++++---- docs/migration/ring.md | 2 +- docs/migration/sha3-kmac.md | 6 +++--- docs/migration/tiny-keccak.md | 8 ++++---- docs/migration/twox-hash.md | 6 +++--- docs/migration/xxhash-rust.md | 8 ++++---- docs/platforms.md | 4 ++-- scripts/README.md | 12 ++++++++++++ 43 files changed, 163 insertions(+), 142 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c1374d33..ad234c7a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -98,16 +98,20 @@ the required `Complete` check. Because the repository currently has one maintainer, no second approval is required; review the final diff yourself, resolve any open threads, and merge in the GitHub UI. -After the merge: +After GitHub reports the pull request merged: ```bash git switch main git pull --ff-only -git branch -d +git branch -D ``` -GitHub can delete the remote branch during the merge. Do not create release -tags during daily development. +Squash merges do not place the topic branch tip in `main`'s ancestry, so +`git branch -d` can reject a branch whose pull request is already merged. Use +`-D` only after verifying that exact pull request. GitHub can delete the remote +branch during the merge; otherwise delete that exact branch with `git push +origin --delete `. Do not create release tags during daily +development. ## Security boundaries diff --git a/README.md b/README.md index 765854b7..19f7c253 100644 --- a/README.md +++ b/README.md @@ -52,14 +52,14 @@ Minimal `no_std` SHA-2 build: ```toml [dependencies] -rscrypto = { version = "0.6.4", default-features = false, features = ["sha2"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["sha2"] } ``` Full primitive stack with OS randomness enabled: ```toml [dependencies] -rscrypto = { version = "0.6.4", features = ["full", "getrandom"] } +rscrypto = { version = "0.7.8", features = ["full", "getrandom"] } ``` Use `default-features = false` for `no_std` builds. Enable `getrandom` only when you need APIs that generate salts, keys, nonces, or RSA key-gen entropy from the operating system. diff --git a/SECURITY.md b/SECURITY.md index ee84c97c..1dac2c2c 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -49,7 +49,7 @@ Out of scope: | Version | Supported | | ------- | --------- | -| `0.6.x` | Yes | +| `0.7.x` | Yes | Only the latest published minor release receives security patches. Users should stay current. diff --git a/THREAT_MODEL.md b/THREAT_MODEL.md index cbb30c15..377230cd 100644 --- a/THREAT_MODEL.md +++ b/THREAT_MODEL.md @@ -30,9 +30,13 @@ unlisted build configurations are not blanket constant-time claims. `rscrypto` is a primitives library. It computes hashes, MACs, KDFs, password hashes, AEADs, signatures, key exchanges, and checksums on caller-provided -buffers. It does not open sockets, touch the filesystem, read the clock, or -spawn threads outside the opt-in `parallel` feature. Protocol design, key -storage, key rotation, and transport are the caller's responsibility. +inputs. It does not open sockets, read the clock, or spawn production threads +outside the opt-in `parallel` feature. With `std`, runtime CPU detection may +read OS-exposed capability data such as `/proc/self/auxv`, `/proc/cpuinfo`, and +sysfs; `getrandom` constructors obtain randomness from the operating system. +The crate does not read application data or manage keys on disk. Protocol +design, key storage, key rotation, and transport are the caller's +responsibility. Everything that crosses the boundary: @@ -98,14 +102,14 @@ Ordered by exposure to untrusted input: | Parsers | RSA DER/SPKI/PKCS#8 import, ECDSA DER signatures and SEC1 points, ML-KEM key and ciphertext parsing, PHC strings, hex | Memory safety, panics, accepting what should be rejected | | Verification oracles | MAC `verify_tag`, AEAD open, signature `verify`, ML-KEM implicit rejection | Timing or error detail beyond the single failure bit | | Secret-bearing compute | Sign, decrypt, decapsulate, derive; the release-evidenced subset of `ct.toml` | Timing leakage, incorrect arithmetic | -| `unsafe` SIMD and assembly kernels | Per-architecture modules | Undefined behavior, divergence from the portable authority | +| `unsafe` low-level code | SIMD/assembly kernels, raw buffer helpers, zeroization, and dispatch | Undefined behavior, divergence from the portable authority | | Dispatch | `src/platform`, `src/backend` | Selecting a kernel the CPU cannot run, or one that produces wrong output | ## Mitigations And Evidence | Risk | Mitigation | Evidence | |---|---|---| -| Memory safety | `unsafe` confined to kernel and platform modules; unsafe lint gates enabled | Miri on portable paths in CI | +| Memory safety | Unsafe operations are lint-gated and require local `SAFETY` proofs; the safe portable path remains authoritative | Miri on portable paths in CI | | Parser abuse | Strict imports, `strict_*` arithmetic, release overflow checks | Fuzz targets, Wycheproof where mapped, official vectors | | Wrong output from accelerated kernels | Portable path is the byte-for-byte authority | Portable-vs-accelerated differential tests and native CI | | Timing leakage | Constant-time coding rules on claimed paths | `ct.toml` evidence gate: timing tests, generated-code review, binary checks where supported | diff --git a/docs/compliance.md b/docs/compliance.md index 0cf265f8..5e5c70f9 100644 --- a/docs/compliance.md +++ b/docs/compliance.md @@ -10,8 +10,9 @@ building your own module boundary and evidence package. Do not use it as a FIPS 140-3 answer by itself. External standards references in this page were checked against NIST CSRC on -2026-06-23. Regulated deployments should check the current standard text and -their own assessor requirements before release. +2026-07-21. Several linked publications have active revision or errata notes; +regulated deployments must review those notes, the current standard text, and +their assessor's requirements before release. ## Quick Answer diff --git a/docs/features.md b/docs/features.md index 5038186a..e8091e7e 100644 --- a/docs/features.md +++ b/docs/features.md @@ -10,28 +10,28 @@ Every primitive has its own leaf feature so size-conscious builds compile only w ```toml # One algorithm, no_std. -rscrypto = { version = "0.6.4", default-features = false, features = ["sha2"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["sha2"] } # RSA public-key import and verification, no_std + alloc. -rscrypto = { version = "0.6.4", default-features = false, features = ["rsa"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["rsa"] } # RSA key generation, signing, encryption, and private-operation blinding. -rscrypto = { version = "0.6.4", default-features = false, features = ["rsa", "getrandom"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["rsa", "getrandom"] } # ECDSA P-256/SHA-256 and P-384/SHA-384 signing and verification. -rscrypto = { version = "0.6.4", default-features = false, features = ["ecdsa"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["ecdsa"] } # FIPS 203 ML-KEM-512/768/1024 KEM APIs with caller-supplied randomness. -rscrypto = { version = "0.6.4", default-features = false, features = ["ml-kem"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["ml-kem"] } # Everything. -rscrypto = { version = "0.6.4", features = ["full", "getrandom"] } +rscrypto = { version = "0.7.8", features = ["full", "getrandom"] } # Everything, with parallel BLAKE3 / Argon2 lanes via Rayon. -rscrypto = { version = "0.6.4", features = ["full", "parallel", "getrandom"] } +rscrypto = { version = "0.7.8", features = ["full", "parallel", "getrandom"] } # Audit-constrained: makes runtime dispatch ignore host SIMD/ASM capabilities. -rscrypto = { version = "0.6.4", features = ["full", "portable-only"] } +rscrypto = { version = "0.7.8", features = ["full", "portable-only"] } ``` ## Complete Feature Index diff --git a/docs/migration/README.md b/docs/migration/README.md index 18203317..3acaaa2d 100644 --- a/docs/migration/README.md +++ b/docs/migration/README.md @@ -47,10 +47,10 @@ API shape change, or not a good fit. | From | To | Status | |---|---|---| -| [`aes-gcm`](RustCrypto/aes-gcm.md) (RustCrypto) | `Aes128Gcm`, `Aes256Gcm` | Verified against `aes-gcm 0.10.3` | +| [`aes-gcm`](RustCrypto/aes-gcm.md) (RustCrypto) | `Aes128Gcm`, `Aes256Gcm` | Verified against `aes-gcm 0.11.0` | | [`aes-gcm-siv`](RustCrypto/aes-gcm-siv.md) (RustCrypto) | `Aes128GcmSiv`, `Aes256GcmSiv` | Verified against `aes-gcm-siv 0.11.1` | -| [`chacha20poly1305`](RustCrypto/chacha20poly1305.md) (RustCrypto) | `ChaCha20Poly1305`, `XChaCha20Poly1305` | Verified against `chacha20poly1305 0.10.1` | -| [`ascon-aead`](RustCrypto/ascon-aead.md) (RustCrypto) | `AsconAead128` | Verified against `ascon-aead 0.5.2` | +| [`chacha20poly1305`](RustCrypto/chacha20poly1305.md) (RustCrypto) | `ChaCha20Poly1305`, `XChaCha20Poly1305` | Verified against `chacha20poly1305 0.11.0` | +| [`ascon-aead`](RustCrypto/ascon-aead.md) (RustCrypto) | `AsconAead128` | Verified against `ascon-aead 0.6.0` | | [`aegis`](aegis.md) | `Aegis256` | Verified against `aegis 0.9.12` | ## Signatures + Key Exchange diff --git a/docs/migration/RustCrypto/aes-gcm-siv.md b/docs/migration/RustCrypto/aes-gcm-siv.md index 72d28ba2..85174920 100644 --- a/docs/migration/RustCrypto/aes-gcm-siv.md +++ b/docs/migration/RustCrypto/aes-gcm-siv.md @@ -2,14 +2,14 @@ > Same algorithm (RFC 8452), same nonce-misuse-resistant guarantees. Replace `Aes256GcmSiv` / `Key` / `Nonce` / `Payload { msg, aad }` with rscrypto's named types and a buffer-style API. -Verified against `aes-gcm-siv = "0.11.1"` and the `rscrypto` 0.5.0 line. +Verified against `aes-gcm-siv = "0.11.1"` and the `rscrypto` 0.7.8 line. Evidence: `tests/aes128gcmsiv_oracle.rs`, `tests/aes256gcmsiv_oracle.rs`, and `tests/aead_wycheproof.rs`. ## TL;DR -| | Before (`aes-gcm-siv` 0.11.x) | After (`rscrypto` 0.5.0) | +| | Before (`aes-gcm-siv` 0.11.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `aes-gcm-siv = "0.11"` | `rscrypto = { version = "0.5.0", features = ["aes-gcm-siv"] }` | +| Cargo dep | `aes-gcm-siv = "0.11"` | `rscrypto = { version = "0.7.8", features = ["aes-gcm-siv"] }` | | Import | `use aes_gcm_siv::{Aes256GcmSiv, Key, Nonce, KeyInit, aead::{Aead, Payload}};` | `use rscrypto::{Aead, Aes256GcmSiv, Aes256GcmSivKey, aead::Nonce96};` | | Encrypt | `cipher.encrypt(nonce, Payload { msg, aad })?` | `cipher.encrypt(&nonce, aad, msg, &mut out)?` | @@ -24,7 +24,7 @@ aes-gcm-siv = "0.11" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["aes-gcm-siv"] } +rscrypto = { version = "0.7.8", features = ["aes-gcm-siv"] } ``` ## Algorithm map diff --git a/docs/migration/RustCrypto/aes-gcm.md b/docs/migration/RustCrypto/aes-gcm.md index d3da2c22..b1931ae3 100644 --- a/docs/migration/RustCrypto/aes-gcm.md +++ b/docs/migration/RustCrypto/aes-gcm.md @@ -2,14 +2,14 @@ > Replace the `Aes256Gcm` / `Key` / `Nonce` / `Payload { msg, aad }` builder with rscrypto's named types and a buffer-style `encrypt(&nonce, aad, plaintext, &mut out)`. Same algorithm, byte-identical ciphertext+tag, no `Vec` allocations on the hot path. -Verified against `aes-gcm = "0.10.3"` and the `rscrypto` 0.5.0 line. +Verified against `aes-gcm = "0.11.0"` and the `rscrypto` 0.7.8 line. Evidence: `tests/aes128gcm_oracle.rs`, `tests/aes256gcm_oracle.rs`, and `tests/aead_wycheproof.rs`. ## TL;DR -| | Before (`aes-gcm` 0.10.x) | After (`rscrypto` 0.5.0) | +| | Before (`aes-gcm` 0.11.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `aes-gcm = "0.10"` | `rscrypto = { version = "0.5.0", features = ["aes-gcm"] }` | +| Cargo dep | `aes-gcm = "0.11"` | `rscrypto = { version = "0.7.8", features = ["aes-gcm"] }` | | Import | `use aes_gcm::{Aes256Gcm, Key, Nonce, KeyInit, aead::{Aead, Payload}};` | `use rscrypto::{Aead, Aes256Gcm, Aes256GcmKey, aead::Nonce96};` | | Encrypt | `cipher.encrypt(nonce, Payload { msg, aad })?` (returns `Vec`) | `cipher.encrypt(&nonce, aad, msg, &mut out)?` (writes into caller buffer) | @@ -18,13 +18,13 @@ Evidence: `tests/aes128gcm_oracle.rs`, `tests/aes256gcm_oracle.rs`, and `tests/a ```toml # Before [dependencies] -aes-gcm = "0.10" +aes-gcm = "0.11" ``` ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["aes-gcm"] } +rscrypto = { version = "0.7.8", features = ["aes-gcm"] } ``` ## Algorithm map diff --git a/docs/migration/RustCrypto/argon2.md b/docs/migration/RustCrypto/argon2.md index b777f96f..a85b45ad 100644 --- a/docs/migration/RustCrypto/argon2.md +++ b/docs/migration/RustCrypto/argon2.md @@ -11,10 +11,10 @@ The raw implementations are checked against RFC 9106 vectors and the RustCrypto ```toml # Raw Argon2 KDF -rscrypto = { version = "0.7", default-features = false, features = ["argon2"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["argon2"] } # Password-record generation and verification -rscrypto = { version = "0.7", default-features = false, features = [ +rscrypto = { version = "0.7.8", default-features = false, features = [ "argon2", "phc-strings", "getrandom", diff --git a/docs/migration/RustCrypto/ascon-aead.md b/docs/migration/RustCrypto/ascon-aead.md index 76424e20..ad5f26a4 100644 --- a/docs/migration/RustCrypto/ascon-aead.md +++ b/docs/migration/RustCrypto/ascon-aead.md @@ -2,14 +2,14 @@ > NIST SP 800-232 lightweight AEAD. Replace `AsconAead128` / `Key` / `Nonce` / `Payload { msg, aad }` with rscrypto's named types and a buffer-style API. 128-bit key, 128-bit nonce, 128-bit tag: all the bytes are 16. -Verified against `ascon-aead = "0.5.2"` and the `rscrypto` 0.5.0 line. +Verified against `ascon-aead = "0.6.0"` and the `rscrypto` 0.7.8 line. Evidence: `tests/ascon_aead_oracle.rs`. ## TL;DR -| | Before (`ascon-aead` 0.5.x) | After (`rscrypto` 0.5.0) | +| | Before (`ascon-aead` 0.6.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `ascon-aead = "0.5"` | `rscrypto = { version = "0.5.0", features = ["ascon-aead"] }` | +| Cargo dep | `ascon-aead = "0.6"` | `rscrypto = { version = "0.7.8", features = ["ascon-aead"] }` | | Import | `use ascon_aead::{AsconAead128, Key, Nonce, aead::{Aead, KeyInit, Payload}};` | `use rscrypto::{Aead, AsconAead128, AsconAead128Key, aead::Nonce128};` | | Encrypt | `cipher.encrypt(nonce, Payload { msg, aad })?` | `cipher.encrypt(&nonce, aad, msg, &mut out)?` | @@ -18,13 +18,13 @@ Evidence: `tests/ascon_aead_oracle.rs`. ```toml # Before [dependencies] -ascon-aead = "0.5" +ascon-aead = "0.6" ``` ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["ascon-aead"] } +rscrypto = { version = "0.7.8", features = ["ascon-aead"] } ``` ## Algorithm map diff --git a/docs/migration/RustCrypto/ascon-hash.md b/docs/migration/RustCrypto/ascon-hash.md index dbb2b8bf..4164a329 100644 --- a/docs/migration/RustCrypto/ascon-hash.md +++ b/docs/migration/RustCrypto/ascon-hash.md @@ -2,14 +2,14 @@ > Same algorithm (NIST LWC Ascon-Hash256). `ascon_hash::AsconHash256` becomes `rscrypto::AsconHash256`; everything else (trait shape, `update`, `finalize`) carries over. -Verified against `ascon-hash = "0.4.0"` and the `rscrypto` 0.5.0 line. +Verified against `ascon-hash = "0.4.0"` and the `rscrypto` 0.7.8 line. Evidence: `tests/ascon_official_vectors.rs`, `tests/ascon_hash_oracle.rs`, `tests/ascon_cxof_vectors.rs`, and `tests/ascon_differential.rs`. ## TL;DR -| | Before (`ascon-hash` 0.4.x) | After (`rscrypto` 0.5.0) | +| | Before (`ascon-hash` 0.4.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `ascon-hash = "0.4"` | `rscrypto = { version = "0.5.0", features = ["ascon-hash"] }` | +| Cargo dep | `ascon-hash = "0.4"` | `rscrypto = { version = "0.7.8", features = ["ascon-hash"] }` | | Import | `use ascon_hash::{AsconHash256, digest::Digest};` | `use rscrypto::{AsconHash256, Digest};` | | Call | `AsconHash256::digest(data)` | `AsconHash256::digest(data)` | @@ -24,7 +24,7 @@ ascon-hash = "0.4" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["ascon-hash"] } +rscrypto = { version = "0.7.8", features = ["ascon-hash"] } ``` ## Algorithm map diff --git a/docs/migration/RustCrypto/blake2.md b/docs/migration/RustCrypto/blake2.md index c14c4c1b..f6b0af4f 100644 --- a/docs/migration/RustCrypto/blake2.md +++ b/docs/migration/RustCrypto/blake2.md @@ -2,16 +2,16 @@ > Same algorithms (RFC 7693), with named convenience types replacing `Blake2b`-style generic instantiations and `Blake2b256::keyed_digest(key, data)` replacing the separate `Blake2bMac` MAC type. -Verified against `blake2 = "0.11.0-rc.6"` and the `rscrypto` 0.5.0 line. +Verified against `blake2 = "0.11.0-rc.6"` and the `rscrypto` 0.7.8 line. Evidence: `tests/blake2_official_vectors.rs` and `tests/blake2_differential.rs`. Code samples use the 0.10-style names where they remain the clearest migration shape for existing projects. ## TL;DR -| | Before (`blake2` 0.10.x) | After (`rscrypto` 0.5.0) | +| | Before (`blake2` 0.10.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `blake2 = "0.10"` | `rscrypto = { version = "0.5.0", features = ["blake2b", "blake2s"] }` | +| Cargo dep | `blake2 = "0.10"` | `rscrypto = { version = "0.7.8", features = ["blake2b", "blake2s"] }` | | Import | `use blake2::{Blake2b512, Digest};` | `use rscrypto::{Blake2b512, Digest};` | | Call | `Blake2b512::digest(data)` | `Blake2b512::digest(data)` | @@ -28,7 +28,7 @@ blake2 = "0.10" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["blake2b", "blake2s"] } +rscrypto = { version = "0.7.8", features = ["blake2b", "blake2s"] } ``` ## Algorithm map diff --git a/docs/migration/RustCrypto/chacha20poly1305.md b/docs/migration/RustCrypto/chacha20poly1305.md index c2ffc143..eedbe69e 100644 --- a/docs/migration/RustCrypto/chacha20poly1305.md +++ b/docs/migration/RustCrypto/chacha20poly1305.md @@ -2,14 +2,14 @@ > Covers both `ChaCha20Poly1305` (96-bit nonce, RFC 8439) and `XChaCha20Poly1305` (192-bit nonce). Same algorithm, byte-identical ciphertext+tag; replace `Key` / `Nonce` / `XNonce` / `Payload { msg, aad }` with `ChaCha20Poly1305Key` + `Nonce96` / `Nonce192` and a buffer-style API. -Verified against `chacha20poly1305 = "0.10.1"` and the `rscrypto` 0.5.0 line. +Verified against `chacha20poly1305 = "0.11.0"` and the `rscrypto` 0.7.8 line. Evidence: `tests/chacha20poly1305.rs`, `tests/xchacha20poly1305.rs`, and `tests/aead_wycheproof.rs`. ## TL;DR -| | Before (`chacha20poly1305` 0.10.x) | After (`rscrypto` 0.5.0) | +| | Before (`chacha20poly1305` 0.11.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `chacha20poly1305 = "0.10"` | `rscrypto = { version = "0.5.0", features = ["chacha20poly1305", "xchacha20poly1305"] }` | +| Cargo dep | `chacha20poly1305 = "0.11"` | `rscrypto = { version = "0.7.8", features = ["chacha20poly1305", "xchacha20poly1305"] }` | | Import | `use chacha20poly1305::{ChaCha20Poly1305, Key, Nonce, KeyInit, aead::{Aead, Payload}};` | `use rscrypto::{Aead, ChaCha20Poly1305, ChaCha20Poly1305Key, aead::Nonce96};` | | Encrypt | `cipher.encrypt(nonce, Payload { msg, aad })?` | `cipher.encrypt(&nonce, aad, msg, &mut out)?` | @@ -20,13 +20,13 @@ Drop `xchacha20poly1305` from the feature list if you don't use the 192-bit-nonc ```toml # Before [dependencies] -chacha20poly1305 = "0.10" +chacha20poly1305 = "0.11" ``` ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["chacha20poly1305", "xchacha20poly1305"] } +rscrypto = { version = "0.7.8", features = ["chacha20poly1305", "xchacha20poly1305"] } ``` ## Algorithm map diff --git a/docs/migration/RustCrypto/ed25519-dalek.md b/docs/migration/RustCrypto/ed25519-dalek.md index ed5f3f38..9a7d77a0 100644 --- a/docs/migration/RustCrypto/ed25519-dalek.md +++ b/docs/migration/RustCrypto/ed25519-dalek.md @@ -2,14 +2,14 @@ > Replace `SigningKey` / `VerifyingKey` / `Signature` with `Ed25519SecretKey` / `Ed25519PublicKey` / `Ed25519Signature`. Same RFC 8032 algorithm, byte-identical signatures (Ed25519 is deterministic), strict verification on by default. -Verified against `ed25519-dalek = "2.2.0"` and the `rscrypto` 0.5.0 line. +Verified against `ed25519-dalek = "2.2.0"` and the `rscrypto` 0.7.8 line. Evidence: `tests/ed25519_rfc8032_vectors.rs`, `tests/ed25519_oracle.rs`, and `tests/ed25519_wycheproof.rs`. ## TL;DR -| | Before (`ed25519-dalek` 2.x) | After (`rscrypto` 0.5.0) | +| | Before (`ed25519-dalek` 2.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `ed25519-dalek = "2.2"` | `rscrypto = { version = "0.5.0", features = ["ed25519"] }` | +| Cargo dep | `ed25519-dalek = "2.2"` | `rscrypto = { version = "0.7.8", features = ["ed25519"] }` | | Import | `use ed25519_dalek::{SigningKey, Signer, Verifier};` | `use rscrypto::{Ed25519SecretKey, Ed25519PublicKey, Ed25519Signature};` | | Sign | `signing_key.sign(msg)` | `secret.sign(msg)` | | Verify | `verifying_key.verify_strict(msg, &sig)?` | `public_key.verify(msg, &sig)?` | @@ -25,7 +25,7 @@ ed25519-dalek = "2.2" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["ed25519"] } +rscrypto = { version = "0.7.8", features = ["ed25519"] } ``` The `ed25519` feature implies `sha2` (Ed25519 uses SHA-512 internally per RFC 8032). diff --git a/docs/migration/RustCrypto/hkdf.md b/docs/migration/RustCrypto/hkdf.md index 9468dd3d..79ce2f1d 100644 --- a/docs/migration/RustCrypto/hkdf.md +++ b/docs/migration/RustCrypto/hkdf.md @@ -2,14 +2,14 @@ > Replace `Hkdf::::new(Some(salt), ikm)` with `HkdfSha256::new(salt, ikm)`. The `Option<&[u8]>` salt becomes a plain `&[u8]` (empty slice == "no salt"); fused one-shot `HkdfSha256::derive_array::(...)` collapses extract+expand. -Verified against `hkdf = "0.13.0"` and the `rscrypto` 0.6.4 line. +Verified against `hkdf = "0.13.0"` and the `rscrypto` 0.7.8 line. Evidence: `tests/hkdf_sha256_vectors.rs`, `tests/hkdf_sha384_vectors.rs`, `tests/hkdf_sha512_vectors.rs`, the HKDF proptests, and `tests/hkdf_wycheproof.rs`. ## TL;DR -| | Before (`hkdf` 0.13.x) | After (`rscrypto` 0.6.4) | +| | Before (`hkdf` 0.13.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `hkdf = "0.13"` + `sha2 = "0.11"` | `rscrypto = { version = "0.6.4", features = ["hkdf"] }` | +| Cargo dep | `hkdf = "0.13"` + `sha2 = "0.11"` | `rscrypto = { version = "0.7.8", features = ["hkdf"] }` | | Import | `use hkdf::Hkdf; use sha2::Sha256;` | `use rscrypto::HkdfSha256;` | | Call | `Hkdf::::new(Some(salt), ikm).expand(info, &mut okm)?` | `HkdfSha256::new(salt, ikm).expand(info, &mut okm)?` | @@ -25,7 +25,7 @@ sha2 = "0.11" ```toml # After [dependencies] -rscrypto = { version = "0.6.4", features = ["hkdf"] } +rscrypto = { version = "0.7.8", features = ["hkdf"] } ``` The `hkdf` feature implies `hmac` which implies `sha2`. diff --git a/docs/migration/RustCrypto/hmac.md b/docs/migration/RustCrypto/hmac.md index 763d81db..84267489 100644 --- a/docs/migration/RustCrypto/hmac.md +++ b/docs/migration/RustCrypto/hmac.md @@ -2,14 +2,14 @@ > Replace `Hmac::` / `Hmac::` (generic over digest) with named rscrypto types such as `HmacSha256` and `HmacSha3_256`. Key construction is infallible, `finalize()` borrows, and one-shot helpers return typed tags with sealed comparison decisions. -Verified against `hmac = "0.13.0"` and the `rscrypto` 0.6.4 line. +Verified against `hmac = "0.13.0"` and the `rscrypto` 0.7.8 line. Evidence: `tests/hmac_sha256_vectors.rs`, `tests/hmac_sha2_family_vectors.rs`, `tests/hmac_sha3_vectors.rs`, the HMAC proptests, and `tests/hmac_wycheproof.rs`. ## TL;DR -| | Before (`hmac` 0.13.x) | After (`rscrypto` 0.6.4) | +| | Before (`hmac` 0.13.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `hmac = "0.13"` + `sha2 = "0.11"` | `rscrypto = { version = "0.6.4", features = ["hmac"] }` | +| Cargo dep | `hmac = "0.13"` + `sha2 = "0.11"` | `rscrypto = { version = "0.7.8", features = ["hmac"] }` | | Import | `use hmac::{Hmac, Mac, KeyInit}; use sha2::Sha256;` | `use rscrypto::{HmacSha256, Mac};` | | Call | `Hmac::::new_from_slice(key).unwrap().chain_update(data).finalize().into_bytes()` | `HmacSha256::mac(key, data)` | @@ -25,7 +25,7 @@ sha2 = "0.11" # required as the generic parameter ```toml # After [dependencies] -rscrypto = { version = "0.6.4", features = ["hmac"] } +rscrypto = { version = "0.7.8", features = ["hmac"] } ``` The `hmac` feature implies `sha2`: no second dep to manage for SHA-2 HMAC. Use `features = ["hmac-sha3"]` for HMAC-SHA3, or `features = ["macs"]` when you want both SHA-2 and SHA-3 HMAC families. diff --git a/docs/migration/RustCrypto/p256.md b/docs/migration/RustCrypto/p256.md index 9e6b74f2..d2b19cf2 100644 --- a/docs/migration/RustCrypto/p256.md +++ b/docs/migration/RustCrypto/p256.md @@ -13,9 +13,9 @@ Evidence: `tests/ecdsa_oracle.rs`, `src/auth/ecdsa.rs` unit tests, and ## TL;DR -| | Before (`p256` 0.14) | After (`rscrypto` 0.6) | +| | Before (`p256` 0.14) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `p256 = { version = "0.14", features = ["ecdsa"] }` | `rscrypto = { version = "0.6", default-features = false, features = ["ecdsa-p256"] }` | +| Cargo dep | `p256 = { version = "0.14", features = ["ecdsa"] }` | `rscrypto = { version = "0.7.8", default-features = false, features = ["ecdsa-p256"] }` | | Import | `use p256::ecdsa::{SigningKey, Signature};` | `use rscrypto::{EcdsaP256SecretKey, EcdsaP256PublicKey, EcdsaP256Signature};` | | Sign | `signing_key.sign(msg)` | `secret.try_sign(msg)?` | | Verify | `verifying_key.verify(msg, &sig)?` | `public.verify(msg, &sig)?` | @@ -27,7 +27,7 @@ Evidence: `tests/ecdsa_oracle.rs`, `src/auth/ecdsa.rs` unit tests, and p256 = { version = "0.14", features = ["ecdsa"] } # After -rscrypto = { version = "0.6", default-features = false, features = ["ecdsa-p256"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["ecdsa-p256"] } ``` The `ecdsa-p256` feature implies `hmac`, which is used for deterministic nonce diff --git a/docs/migration/RustCrypto/p384.md b/docs/migration/RustCrypto/p384.md index 911b6166..639a3bbf 100644 --- a/docs/migration/RustCrypto/p384.md +++ b/docs/migration/RustCrypto/p384.md @@ -13,9 +13,9 @@ Evidence: `tests/ecdsa_oracle.rs`, `src/auth/ecdsa.rs` unit tests, and ## TL;DR -| | Before (`p384` 0.13) | After (`rscrypto` 0.5.0) | +| | Before (`p384` 0.13) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `p384 = { version = "0.13", features = ["ecdsa"] }` | `rscrypto = { version = "0.5.0", default-features = false, features = ["ecdsa-p384"] }` | +| Cargo dep | `p384 = { version = "0.13", features = ["ecdsa"] }` | `rscrypto = { version = "0.7.8", default-features = false, features = ["ecdsa-p384"] }` | | Import | `use p384::ecdsa::{SigningKey, Signature};` | `use rscrypto::{EcdsaP384SecretKey, EcdsaP384PublicKey, EcdsaP384Signature};` | | Sign | `signing_key.sign(msg)` | `secret.try_sign(msg)?` | | Verify | `verifying_key.verify(msg, &sig)?` | `public.verify(msg, &sig)?` | @@ -27,7 +27,7 @@ Evidence: `tests/ecdsa_oracle.rs`, `src/auth/ecdsa.rs` unit tests, and p384 = { version = "0.13", features = ["ecdsa"] } # After -rscrypto = { version = "0.5.0", default-features = false, features = ["ecdsa-p384"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["ecdsa-p384"] } ``` The `ecdsa-p384` feature implies `hmac`, which is used for deterministic nonce diff --git a/docs/migration/RustCrypto/pbkdf2.md b/docs/migration/RustCrypto/pbkdf2.md index 28de2840..4b16761e 100644 --- a/docs/migration/RustCrypto/pbkdf2.md +++ b/docs/migration/RustCrypto/pbkdf2.md @@ -2,14 +2,14 @@ > Replace the free function `pbkdf2_hmac::(password, salt, iters, &mut out)` with `Pbkdf2Sha256::derive_key_array::(password, salt, iters)?`. The password helpers enforce the current PBKDF2 iteration and salt floors by default, while `*_primitive` APIs remain available for RFC vectors and legacy compatibility. -Verified against `pbkdf2 = "0.13.0"` and the `rscrypto` 0.5.0 line. +Verified against `pbkdf2 = "0.13.0"` and the `rscrypto` 0.7.8 line. Evidence: `tests/pbkdf2_kat_vectors.rs`, `tests/pbkdf2_differential.rs`, and `tests/pbkdf2_wycheproof.rs`. ## TL;DR -| | Before (`pbkdf2` 0.13.x) | After (`rscrypto` 0.5.0) | +| | Before (`pbkdf2` 0.13.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `pbkdf2 = "0.13"` + `sha2 = "0.11"` | `rscrypto = { version = "0.5.0", features = ["pbkdf2"] }` | +| Cargo dep | `pbkdf2 = "0.13"` + `sha2 = "0.11"` | `rscrypto = { version = "0.7.8", features = ["pbkdf2"] }` | | Import | `use pbkdf2::pbkdf2_hmac; use sha2::Sha256;` | `use rscrypto::Pbkdf2Sha256;` | | Call | `pbkdf2_hmac::(pw, salt, iters, &mut okm)` | `Pbkdf2Sha256::derive_key(pw, salt, iters, &mut okm)?` | @@ -25,7 +25,7 @@ sha2 = "0.11" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["pbkdf2"] } +rscrypto = { version = "0.7.8", features = ["pbkdf2"] } ``` The `pbkdf2` feature implies `hmac` which implies `sha2`. diff --git a/docs/migration/RustCrypto/rsa.md b/docs/migration/RustCrypto/rsa.md index a00236d5..c617cb05 100644 --- a/docs/migration/RustCrypto/rsa.md +++ b/docs/migration/RustCrypto/rsa.md @@ -17,10 +17,10 @@ interoperability tests used by the stack migration guides. rsa = { version = "0.9", features = ["sha2"] } # After -rscrypto = { version = "0.5.0", default-features = false, features = ["rsa"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["rsa"] } # After, when generating keys or using randomized private/encryption APIs -rscrypto = { version = "0.5.0", default-features = false, features = ["rsa", "getrandom"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["rsa", "getrandom"] } ``` ## Map diff --git a/docs/migration/RustCrypto/scrypt.md b/docs/migration/RustCrypto/scrypt.md index 8ad62016..df1fb963 100644 --- a/docs/migration/RustCrypto/scrypt.md +++ b/docs/migration/RustCrypto/scrypt.md @@ -11,10 +11,10 @@ The implementation is checked against RFC 7914 vectors and the RustCrypto `scryp ```toml # Raw scrypt KDF -rscrypto = { version = "0.7", default-features = false, features = ["scrypt"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["scrypt"] } # Password-record generation and verification -rscrypto = { version = "0.7", default-features = false, features = [ +rscrypto = { version = "0.7.8", default-features = false, features = [ "scrypt", "phc-strings", "getrandom", diff --git a/docs/migration/RustCrypto/sha2.md b/docs/migration/RustCrypto/sha2.md index fd848436..9271fe34 100644 --- a/docs/migration/RustCrypto/sha2.md +++ b/docs/migration/RustCrypto/sha2.md @@ -2,14 +2,14 @@ > Same algorithms (FIPS 180-4), same `Sha224` / `Sha256` / `Sha384` / `Sha512` / `Sha512_256` names, same `new()` / `update()` / `finalize()` shape. The output type changes from `Output` (a `GenericArray`) to `[u8; N]`, and `finalize()` now borrows instead of consuming. -Verified against `sha2 = "0.11.0"` and the `rscrypto` 0.5.0 line. +Verified against `sha2 = "0.11.0"` and the `rscrypto` 0.7.8 line. Evidence: `tests/sha2_official_vectors.rs`, `tests/sha256_differential.rs`, and `tests/sha512_differential.rs`. ## TL;DR -| | Before (`sha2` 0.11.x) | After (`rscrypto` 0.5.0) | +| | Before (`sha2` 0.11.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `sha2 = "0.11"` | `rscrypto = { version = "0.5.0", features = ["sha2"] }` | +| Cargo dep | `sha2 = "0.11"` | `rscrypto = { version = "0.7.8", features = ["sha2"] }` | | Import | `use sha2::{Sha256, Digest};` | `use rscrypto::Sha256;` | | Call | `Sha256::digest(data)` | `Sha256::digest(data)` | @@ -24,7 +24,7 @@ sha2 = "0.11" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["sha2"] } +rscrypto = { version = "0.7.8", features = ["sha2"] } ``` ## Algorithm map diff --git a/docs/migration/RustCrypto/sha3.md b/docs/migration/RustCrypto/sha3.md index bce832fb..b2b59e0a 100644 --- a/docs/migration/RustCrypto/sha3.md +++ b/docs/migration/RustCrypto/sha3.md @@ -2,14 +2,14 @@ > Same algorithms (FIPS 202: SHA3-224/256/384/512, SHAKE128/256; SP 800-185: cSHAKE128/256), `[u8; N]` outputs replace `Output`, and the SHAKE/cSHAKE reader chain uses `squeeze(&mut out)`. -Verified against `sha3 = "0.12.0"` and the `rscrypto` 0.6.4 line. +Verified against `sha3 = "0.12.0"` and the `rscrypto` 0.7.8 line. Evidence: `tests/sha3_official_vectors.rs`, `tests/sha3_differential.rs`, `tests/shake128_differential.rs`, `tests/shake256_differential.rs`, `tests/cshake256_nist_vectors.rs`, and `tests/cshake256_differential.rs`. ## TL;DR -| | Before (`sha3` 0.12.x) | After (`rscrypto` 0.6.4) | +| | Before (`sha3` 0.12.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `sha3 = "0.12"` | `rscrypto = { version = "0.6.4", features = ["sha3"] }` | +| Cargo dep | `sha3 = "0.12"` | `rscrypto = { version = "0.7.8", features = ["sha3"] }` | | Import | `use sha3::{Sha3_256, Digest};` | `use rscrypto::{Sha3_256, Digest};` | | Call | `Sha3_256::digest(data)` | `Sha3_256::digest(data)` | @@ -24,7 +24,7 @@ sha3 = "0.12" ```toml # After [dependencies] -rscrypto = { version = "0.6.4", features = ["sha3"] } +rscrypto = { version = "0.7.8", features = ["sha3"] } ``` ## Algorithm map diff --git a/docs/migration/RustCrypto/x25519-dalek.md b/docs/migration/RustCrypto/x25519-dalek.md index 1e2b5b9b..3f5c2d47 100644 --- a/docs/migration/RustCrypto/x25519-dalek.md +++ b/docs/migration/RustCrypto/x25519-dalek.md @@ -2,14 +2,14 @@ > Replace `StaticSecret` / `EphemeralSecret` / `PublicKey` / `SharedSecret` with rscrypto's unified `X25519SecretKey` / `X25519PublicKey` / `X25519SharedSecret`. Same RFC 7748 algorithm, byte-identical shared secrets, plus an explicit error on low-order peer input. -Verified against `x25519-dalek = "2.0.1"` and the `rscrypto` 0.5.0 line. +Verified against `x25519-dalek = "2.0.1"` and the `rscrypto` 0.7.8 line. Evidence: `tests/x25519_vectors.rs`, `tests/x25519_oracle.rs`, and `tests/x25519_wycheproof.rs`. ## TL;DR -| | Before (`x25519-dalek` 2.x) | After (`rscrypto` 0.5.0) | +| | Before (`x25519-dalek` 2.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `x25519-dalek = { version = "2.0", features = ["static_secrets"] }` | `rscrypto = { version = "0.5.0", features = ["x25519"] }` | +| Cargo dep | `x25519-dalek = { version = "2.0", features = ["static_secrets"] }` | `rscrypto = { version = "0.7.8", features = ["x25519"] }` | | Import | `use x25519_dalek::{StaticSecret, PublicKey};` | `use rscrypto::{X25519SecretKey, X25519PublicKey};` | | DH | `secret.diffie_hellman(&peer_pub)` (returns `SharedSecret`) | `secret.diffie_hellman(&peer_pub)?` (returns `Result`) | @@ -24,7 +24,7 @@ x25519-dalek = { version = "2.0", features = ["static_secrets"] } ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["x25519"] } +rscrypto = { version = "0.7.8", features = ["x25519"] } ``` The `x25519` feature has no transitive dependencies: X25519 needs nothing beyond Curve25519 arithmetic. diff --git a/docs/migration/aegis.md b/docs/migration/aegis.md index cef85fc7..cdff9d73 100644 --- a/docs/migration/aegis.md +++ b/docs/migration/aegis.md @@ -2,14 +2,14 @@ > Covers AEGIS-256 from the `aegis` crate. Replace `Aegis256::::new(&key, &nonce).encrypt(msg, aad) -> (Vec, [u8; TAG])` with rscrypto's `Aead`-trait-style `encrypt(&nonce, aad, msg, &mut out)`. Same algorithm (draft-irtf-cfrg-aegis-aead), byte-identical ciphertext+tag. -Verified against `aegis = "0.9.12"` and the `rscrypto` 0.5.0 line. +Verified against `aegis = "0.9.12"` and the `rscrypto` 0.7.8 line. Evidence: `tests/aegis256_oracle.rs` and `tests/aead_wycheproof.rs`. ## TL;DR -| | Before (`aegis` 0.9.x) | After (`rscrypto` 0.5.0) | +| | Before (`aegis` 0.9.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `aegis = "0.9"` | `rscrypto = { version = "0.5.0", features = ["aegis256"] }` | +| Cargo dep | `aegis = "0.9"` | `rscrypto = { version = "0.7.8", features = ["aegis256"] }` | | Import | `use aegis::aegis256::Aegis256;` | `use rscrypto::{Aead, Aegis256, Aegis256Key, aead::Nonce256};` | | Encrypt | `Aegis256::<16>::new(&key, &nonce).encrypt(msg, aad) -> (Vec, [u8; 16])` | `cipher.encrypt(&nonce, aad, msg, &mut out)?` | @@ -24,7 +24,7 @@ aegis = "0.9" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["aegis256"] } +rscrypto = { version = "0.7.8", features = ["aegis256"] } ``` ## Algorithm map diff --git a/docs/migration/aws-lc-rs.md b/docs/migration/aws-lc-rs.md index 45f915ec..295a71bf 100644 --- a/docs/migration/aws-lc-rs.md +++ b/docs/migration/aws-lc-rs.md @@ -12,7 +12,7 @@ The direct examples below are covered by `tests/migration_aws_lc_rs.rs`. aws-lc-rs = "1.17" # After: enable only the primitives you use -rscrypto = { version = "0.5.0", default-features = false, features = ["sha2", "hmac", "hkdf", "pbkdf2", "aes-gcm", "chacha20poly1305", "ecdsa", "ed25519", "x25519", "rsa"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["sha2", "hmac", "hkdf", "pbkdf2", "aes-gcm", "chacha20poly1305", "ecdsa", "ed25519", "x25519", "rsa"] } ``` ## Map diff --git a/docs/migration/blake3.md b/docs/migration/blake3.md index 9f46982d..3239bf7a 100644 --- a/docs/migration/blake3.md +++ b/docs/migration/blake3.md @@ -4,14 +4,14 @@ > Unkeyed hashes return `[u8; 32]`; keyed hashes return `Blake3KeyedHash` so > authenticator comparison requires an explicit sealed decision. -Verified against `blake3 = "1.8.5"` and the `rscrypto` 0.5.0 line. +Verified against `blake3 = "1.8.5"` and the `rscrypto` 0.7.8 line. Evidence: `tests/blake3_official_vectors.rs` and `tests/blake3_differential.rs`. ## TL;DR -| | Before (`blake3` 1.x) | After (`rscrypto` 0.5.0) | +| | Before (`blake3` 1.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `blake3 = "1.8"` | `rscrypto = { version = "0.5.0", features = ["blake3"] }` | +| Cargo dep | `blake3 = "1.8"` | `rscrypto = { version = "0.7.8", features = ["blake3"] }` | | Import | `use blake3::Hasher;` | `use rscrypto::{Blake3, prelude::*};` | | Call | `blake3::hash(data).as_bytes()` | `&Blake3::digest(data)` | @@ -26,7 +26,7 @@ blake3 = "1.8" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["blake3"] } +rscrypto = { version = "0.7.8", features = ["blake3"] } ``` ## API patterns diff --git a/docs/migration/crc-fast.md b/docs/migration/crc-fast.md index 865be63a..eff64f89 100644 --- a/docs/migration/crc-fast.md +++ b/docs/migration/crc-fast.md @@ -2,14 +2,14 @@ > Replace `crc-fast`'s enum-driven `checksum(CrcAlgorithm::*, data)` calls with rscrypto's named CRC types. SIMD coverage is comparable on x86_64 and aarch64; rscrypto adds Power, s390x, and RISC-V kernels and removes the `u64`-everywhere return type. -Verified against `crc-fast = "1.10.0"` and the `rscrypto` 0.5.0 line. +Verified against `crc-fast = "1.10.0"` and the `rscrypto` 0.7.8 line. Evidence: `tests/crc16_properties.rs`, `tests/crc32_properties.rs`, and `tests/crc64_properties.rs`. ## TL;DR -| | Before (`crc-fast` 1.x) | After (`rscrypto` 0.5.0) | +| | Before (`crc-fast` 1.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `crc-fast = "1.10"` | `rscrypto = { version = "0.5.0", features = ["crc32", "crc64"] }` | +| Cargo dep | `crc-fast = "1.10"` | `rscrypto = { version = "0.7.8", features = ["crc32", "crc64"] }` | | Import | `use crc_fast::{checksum, CrcAlgorithm};` | `use rscrypto::checksum::{Checksum, Crc32};` | | Call | `checksum(CrcAlgorithm::Crc32IsoHdlc, data) as u32` | `Crc32::checksum(data)` | @@ -24,7 +24,7 @@ crc-fast = "1.10" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["crc32", "crc64"] } +rscrypto = { version = "0.7.8", features = ["crc32", "crc64"] } ``` Drop `crc16` / `crc24` from the feature list if you don't use them. `features = ["checksums"]` is the umbrella shortcut. diff --git a/docs/migration/crc.md b/docs/migration/crc.md index 17d69240..7d1ddbec 100644 --- a/docs/migration/crc.md +++ b/docs/migration/crc.md @@ -2,14 +2,14 @@ > Replace the parameterized `Crc::::new(&CRC_*)` builder with rscrypto's named CRC types. Same outputs, hardware-accelerated dispatch, no generic width to thread through call sites. -Verified against `crc = "3.4.0"` and the `rscrypto` 0.5.0 line. +Verified against `crc = "3.4.0"` and the `rscrypto` 0.7.8 line. Evidence: `tests/crc16_properties.rs`, `tests/crc24_properties.rs`, `tests/crc32_properties.rs`, and `tests/crc64_properties.rs`. ## TL;DR -| | Before (`crc` 3.x) | After (`rscrypto` 0.5.0) | +| | Before (`crc` 3.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `crc = "3.4"` | `rscrypto = { version = "0.5.0", features = ["checksums"] }` | +| Cargo dep | `crc = "3.4"` | `rscrypto = { version = "0.7.8", features = ["checksums"] }` | | Import | `use crc::{Crc, CRC_32_ISO_HDLC};` | `use rscrypto::checksum::{Checksum, Crc32};` | | Call | `Crc::::new(&CRC_32_ISO_HDLC).checksum(data)` | `Crc32::checksum(data)` | @@ -24,7 +24,7 @@ crc = "3.4" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["checksums"] } +rscrypto = { version = "0.7.8", features = ["checksums"] } ``` `features = ["checksums"]` enables every CRC family. To trim the build, pick only what you use: `crc16`, `crc24`, `crc32` (covers IEEE + Castagnoli), `crc64` (covers XZ + NVME). diff --git a/docs/migration/crc32c.md b/docs/migration/crc32c.md index 142c4a46..1844fe9e 100644 --- a/docs/migration/crc32c.md +++ b/docs/migration/crc32c.md @@ -6,9 +6,9 @@ Output is covered by the CRC-32C oracle/property tests in `tests/crc32_propertie ## TL;DR -| | Before (`crc32c` 0.6.x) | After (`rscrypto` 0.5.0) | +| | Before (`crc32c` 0.6.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `crc32c = "0.6"` | `rscrypto = { version = "0.5.0", features = ["crc32"] }` | +| Cargo dep | `crc32c = "0.6"` | `rscrypto = { version = "0.7.8", features = ["crc32"] }` | | Import | `use crc32c::{crc32c, crc32c_append, crc32c_combine};` | `use rscrypto::checksum::{Checksum, ChecksumCombine, Crc32C};` | | Call | `crc32c(data)` | `Crc32C::checksum(data)` | @@ -23,7 +23,7 @@ crc32c = "0.6" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["crc32"] } +rscrypto = { version = "0.7.8", features = ["crc32"] } ``` The `crc32` feature enables both `Crc32` (IEEE) and `Crc32C` (Castagnoli) at no extra binary cost. diff --git a/docs/migration/crc32fast.md b/docs/migration/crc32fast.md index cc026a33..75b81a91 100644 --- a/docs/migration/crc32fast.md +++ b/docs/migration/crc32fast.md @@ -6,9 +6,9 @@ Output is covered by the CRC-32 oracle/property tests in `tests/crc32_properties ## TL;DR -| | Before (`crc32fast` 1.x) | After (`rscrypto` 0.5.0) | +| | Before (`crc32fast` 1.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `crc32fast = "1.5"` | `rscrypto = { version = "0.5.0", features = ["crc32"] }` | +| Cargo dep | `crc32fast = "1.5"` | `rscrypto = { version = "0.7.8", features = ["crc32"] }` | | Import | `use crc32fast::Hasher;` | `use rscrypto::checksum::{Checksum, Crc32};` | | Call | `crc32fast::hash(data)` | `Crc32::checksum(data)` | @@ -23,7 +23,7 @@ crc32fast = "1.5" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["crc32"] } +rscrypto = { version = "0.7.8", features = ["crc32"] } ``` `features = ["crc32"]` enables both CRC-32/IEEE (`Crc32`) and CRC-32C/Castagnoli (`Crc32C`) at no extra build cost. diff --git a/docs/migration/crc64fast.md b/docs/migration/crc64fast.md index d522aeb6..f5fa90f6 100644 --- a/docs/migration/crc64fast.md +++ b/docs/migration/crc64fast.md @@ -2,14 +2,14 @@ > Same CRC-64/XZ output with method renames from `Digest` / `write` / `sum64` to `Crc64` / `update` / `finalize`. The aside below also covers `crc64fast-nvme` → `Crc64Nvme`. -Verified against `crc64fast = "1.1.0"` for `Crc64`; `Crc64Nvme` oracle coverage uses `crc-fast = "1.10.0"` and the `rscrypto` 0.5.0 line. +Verified against `crc64fast = "1.1.0"` for `Crc64`; `Crc64Nvme` oracle coverage uses `crc-fast = "1.10.0"` and the `rscrypto` 0.7.8 line. Evidence: `tests/crc64_properties.rs` compares one-shot, streaming, and combine output against those oracle crates. ## TL;DR -| | Before (`crc64fast` 1.x) | After (`rscrypto` 0.5.0) | +| | Before (`crc64fast` 1.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `crc64fast = "1.1"` | `rscrypto = { version = "0.5.0", features = ["crc64"] }` | +| Cargo dep | `crc64fast = "1.1"` | `rscrypto = { version = "0.7.8", features = ["crc64"] }` | | Import | `use crc64fast::Digest;` | `use rscrypto::checksum::{Checksum, Crc64};` | | Call | `Digest::new(); .write(data); .sum64()` | `Crc64::new(); .update(data); .finalize()` | @@ -24,7 +24,7 @@ crc64fast = "1.1" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["crc64"] } +rscrypto = { version = "0.7.8", features = ["crc64"] } ``` `features = ["crc64"]` enables both `Crc64` (XZ / ECMA-182) and `Crc64Nvme`. diff --git a/docs/migration/dryoc.md b/docs/migration/dryoc.md index db22596a..7c0e13a2 100644 --- a/docs/migration/dryoc.md +++ b/docs/migration/dryoc.md @@ -14,7 +14,7 @@ The direct BLAKE2b, Ed25519, and X25519 examples below are covered by dryoc = "0.8" # After: choose only the primitive features you use -rscrypto = { version = "0.5.0", default-features = false, features = ["blake2b", "ed25519", "x25519", "argon2"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["blake2b", "ed25519", "x25519", "argon2"] } ``` ## Map diff --git a/docs/migration/openssl.md b/docs/migration/openssl.md index a9b5000b..a9d06a04 100644 --- a/docs/migration/openssl.md +++ b/docs/migration/openssl.md @@ -15,7 +15,7 @@ RSA test lane. openssl = "0.10" # After: choose only the primitive features you use -rscrypto = { version = "0.5.0", default-features = false, features = ["sha2", "hmac", "hkdf", "pbkdf2", "aes-gcm", "chacha20poly1305", "ed25519", "x25519", "rsa"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["sha2", "hmac", "hkdf", "pbkdf2", "aes-gcm", "chacha20poly1305", "ed25519", "x25519", "rsa"] } ``` ## Map diff --git a/docs/migration/rapidhash.md b/docs/migration/rapidhash.md index de309014..ca9965f4 100644 --- a/docs/migration/rapidhash.md +++ b/docs/migration/rapidhash.md @@ -2,14 +2,14 @@ > Replace `rapidhash::v3::rapidhash_v3` with `rscrypto::RapidHash::hash`. Bit-equivalent, single feature flag, no version-pinning gymnastics. -Verified against `rapidhash = "4.5.1"` (V3 with avalanche, default secrets) and the `rscrypto` 0.6 line. +Verified against `rapidhash = "4.5.1"` (V3 with avalanche, default secrets) and the `rscrypto` 0.7.8 line. Evidence: `tests/rapidhash_differential.rs`. ## TL;DR -| | Before (`rapidhash` 4.x) | After (`rscrypto` 0.6) | +| | Before (`rapidhash` 4.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `rapidhash = "4.5.1"` | `rscrypto = { version = "0.6", features = ["rapidhash"] }` | +| Cargo dep | `rapidhash = "4.5.1"` | `rscrypto = { version = "0.7.8", features = ["rapidhash"] }` | | Import | `use rapidhash::v3::rapidhash_v3;` | `use rscrypto::{FastHash, RapidHash};` | | Call | `rapidhash_v3(data)` | `RapidHash::hash(data)` | @@ -24,7 +24,7 @@ rapidhash = "4.5.1" ```toml # After [dependencies] -rscrypto = { version = "0.6", features = ["rapidhash"] } +rscrypto = { version = "0.7.8", features = ["rapidhash"] } ``` ## Algorithm map diff --git a/docs/migration/ring.md b/docs/migration/ring.md index 4e4d6de0..83d77667 100644 --- a/docs/migration/ring.md +++ b/docs/migration/ring.md @@ -13,7 +13,7 @@ The direct examples below are covered by `tests/migration_ring.rs`. ring = "0.17" # After: choose only the primitive features you use -rscrypto = { version = "0.5.0", default-features = false, features = ["sha2", "hmac", "hkdf", "pbkdf2", "aes-gcm", "chacha20poly1305", "ecdsa", "ed25519", "rsa"] } +rscrypto = { version = "0.7.8", default-features = false, features = ["sha2", "hmac", "hkdf", "pbkdf2", "aes-gcm", "chacha20poly1305", "ecdsa", "ed25519", "rsa"] } ``` ## Map diff --git a/docs/migration/sha3-kmac.md b/docs/migration/sha3-kmac.md index 4e5e49fd..c8ad6c57 100644 --- a/docs/migration/sha3-kmac.md +++ b/docs/migration/sha3-kmac.md @@ -9,9 +9,9 @@ tests; KMAC256 also has Wycheproof coverage in `tests/kmac128_nist_vectors.rs`, ## TL;DR -| | Before (`sha3-kmac` 0.3.x) | After (`rscrypto` 0.6.4) | +| | Before (`sha3-kmac` 0.3.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `sha3-kmac = "0.3"` | `rscrypto = { version = "0.6.4", features = ["kmac"] }` | +| Cargo dep | `sha3-kmac = "0.3"` | `rscrypto = { version = "0.7.8", features = ["kmac"] }` | | Import | `use sha3_kmac::Kmac256;` | `use rscrypto::Kmac256;` | | Call | `let mut k = Kmac256::new(key, custom)?; k.update(data); k.finalize_into(&mut tag);` | `Kmac256::mac_into(key, custom, data, &mut tag);` | @@ -26,7 +26,7 @@ sha3-kmac = "0.3" ```toml # After [dependencies] -rscrypto = { version = "0.6.4", features = ["kmac"] } +rscrypto = { version = "0.7.8", features = ["kmac"] } ``` The `kmac` feature implies `sha3`. diff --git a/docs/migration/tiny-keccak.md b/docs/migration/tiny-keccak.md index 1ebfa4e5..b98a6057 100644 --- a/docs/migration/tiny-keccak.md +++ b/docs/migration/tiny-keccak.md @@ -2,14 +2,14 @@ > Replace `tiny_keccak::Kmac::v128` / `Kmac::v256` and `tiny_keccak::CShake::v128` / `CShake::v256` with `rscrypto::Kmac128` / `Kmac256` and `rscrypto::Cshake128` / `Cshake256`. Same SP 800-185 algorithms, byte-identical output, infallible construction, and `verify` helpers for KMAC tags. -Verified against `tiny-keccak = "2.0.2"` (with `kmac` and `cshake` features) and the `rscrypto` 0.6.4 line. +Verified against `tiny-keccak = "2.0.2"` (with `kmac` and `cshake` features) and the `rscrypto` 0.7.8 line. Evidence: `tests/kmac128_differential.rs`, `tests/kmac256_differential.rs`, `tests/cshake256_differential.rs`, `tests/cshake256_nist_vectors.rs`, and `tests/kmac_wycheproof.rs`. ## TL;DR -| | Before (`tiny-keccak` 2.x) | After (`rscrypto` 0.6.4) | +| | Before (`tiny-keccak` 2.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `tiny-keccak = { version = "2.0", features = ["kmac", "cshake"] }` | `rscrypto = { version = "0.6.4", features = ["kmac"] }` | +| Cargo dep | `tiny-keccak = { version = "2.0", features = ["kmac", "cshake"] }` | `rscrypto = { version = "0.7.8", features = ["kmac"] }` | | KMAC import | `use tiny_keccak::{Hasher, Kmac};` | `use rscrypto::{Kmac128, Kmac256};` | | KMAC call | `let mut k = Kmac::v256(key, custom); k.update(data); k.finalize(&mut tag);` | `Kmac256::mac_into(key, custom, data, &mut tag);` | | cSHAKE import | `use tiny_keccak::{Hasher, CShake};` | `use rscrypto::{Cshake128, Cshake256, Xof};` | @@ -26,7 +26,7 @@ tiny-keccak = { version = "2.0", features = ["kmac", "cshake"] } ```toml # After [dependencies] -rscrypto = { version = "0.6.4", features = ["kmac"] } +rscrypto = { version = "0.7.8", features = ["kmac"] } ``` The `kmac` feature implies `sha3` (which provides the underlying `Cshake128` / `Cshake256` sponges for both KMAC variants and the standalone cSHAKE primitives). diff --git a/docs/migration/twox-hash.md b/docs/migration/twox-hash.md index a5fecf0f..2c1e1f4a 100644 --- a/docs/migration/twox-hash.md +++ b/docs/migration/twox-hash.md @@ -7,9 +7,9 @@ The `twox-hash` mapping is API migration guidance for its 2.x XXH3 surface. ## TL;DR -| | Before (`twox-hash` 2.x) | After (`rscrypto` 0.5.0) | +| | Before (`twox-hash` 2.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `twox-hash = "2.1"` | `rscrypto = { version = "0.5.0", features = ["xxh3"] }` | +| Cargo dep | `twox-hash = "2.1"` | `rscrypto = { version = "0.7.8", features = ["xxh3"] }` | | Import | `use twox_hash::XxHash3_64;` | `use rscrypto::{FastHash, Xxh3};` | | Call | `XxHash3_64::oneshot(data)` | `Xxh3::hash(data)` | @@ -24,7 +24,7 @@ twox-hash = "2.1" ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["xxh3"] } +rscrypto = { version = "0.7.8", features = ["xxh3"] } ``` ## Algorithm map diff --git a/docs/migration/xxhash-rust.md b/docs/migration/xxhash-rust.md index d3100cfd..065e6530 100644 --- a/docs/migration/xxhash-rust.md +++ b/docs/migration/xxhash-rust.md @@ -2,14 +2,14 @@ > Replace `xxhash_rust::xxh3::xxh3_64` with `rscrypto::Xxh3::hash` (and `xxh3_128` with `Xxh3_128::hash`). One-shot bit-equivalent. Streaming routes through `Xxh3Hasher` (a `core::hash::Hasher`). -Verified against `xxhash-rust = "0.8.15"` (with `xxh3` feature) and the `rscrypto` 0.5.0 line. +Verified against `xxhash-rust = "0.8.16"` (with `xxh3` feature) and the `rscrypto` 0.7.8 line. Evidence: `tests/xxh3_differential.rs`. ## TL;DR -| | Before (`xxhash-rust` 0.8.x) | After (`rscrypto` 0.5.0) | +| | Before (`xxhash-rust` 0.8.x) | After (`rscrypto` 0.7.8) | |---|---|---| -| Cargo dep | `xxhash-rust = { version = "0.8", features = ["xxh3"] }` | `rscrypto = { version = "0.5.0", features = ["xxh3"] }` | +| Cargo dep | `xxhash-rust = { version = "0.8", features = ["xxh3"] }` | `rscrypto = { version = "0.7.8", features = ["xxh3"] }` | | Import | `use xxhash_rust::xxh3::xxh3_64;` | `use rscrypto::{FastHash, Xxh3};` | | Call | `xxh3_64(data)` | `Xxh3::hash(data)` | @@ -24,7 +24,7 @@ xxhash-rust = { version = "0.8", features = ["xxh3"] } ```toml # After [dependencies] -rscrypto = { version = "0.5.0", features = ["xxh3"] } +rscrypto = { version = "0.7.8", features = ["xxh3"] } ``` ## Algorithm map diff --git a/docs/platforms.md b/docs/platforms.md index 42479dc1..ab6829a0 100644 --- a/docs/platforms.md +++ b/docs/platforms.md @@ -7,7 +7,7 @@ when the target and CPU support them. ## Dispatch Model 1. **Compile-time**: `#[cfg(target_feature = "...")]` selects the strongest backend permitted by `RUSTFLAGS` / `target-feature`. -2. **Runtime detection** (`std` only): cached `platform::caps()` probes CPU features once at startup via `is_x86_feature_detected!` and the aarch64 / s390x / ppc64le / riscv64 equivalents, then dispatches to the strongest available kernel. +2. **Runtime detection** (`std` only): cached `platform::caps()` probes CPU features once via detection intrinsics and, on supported Linux/Android targets, OS capability files such as `/proc/self/auxv`; it then dispatches to the strongest available kernel. 3. **Portable Rust fallback**: always present. The portable implementation is the source of truth; SIMD and ASM kernels are differentially tested against it. In `no_std` builds, only the compile-time tier runs. @@ -62,4 +62,4 @@ missing. Current geomean speedups by platform live in [`benchmark_results/OVERVIEW.md`](../benchmark_results/OVERVIEW.md#coverage-matrix). -The current public set includes the 2026-06-22 nine-runner Linux CI matrix. +The current public set is the 2026-07-04 nine-runner Linux CI matrix. diff --git a/scripts/README.md b/scripts/README.md index c9814515..c52fb7ec 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -10,6 +10,7 @@ its caller. | `check/check.sh` | `just check` | | `check/check-all.sh` | `just check-all` | | `check/check-feature-matrix.sh`| `just check-feature-matrix`, `scripts/check/check.sh`, `_ci-suite.yaml` | +| `check/asm-ledger.sh` | `scripts/check/check.sh` | | `check/zeroize-evidence.sh` | `just check-zeroize-evidence`, `scripts/check/check-all.sh` | | `ci/ci-check.sh` | `just ci-check`, `_ci-suite.yaml` (quality lane) | | `ci/native-check.sh` | `_ci-suite.yaml` (native Linux/IBM lanes), `riscv.yaml` | @@ -17,6 +18,8 @@ its caller. | `test/test-feature-matrix.sh` | `just test-feature-matrix`, `scripts/check/check.sh`, `_ci-suite.yaml` | | `test/test-miri.sh` | `just test-miri`, `weekly.yaml` | | `test/test-fuzz.sh` | `just test-fuzz`, `weekly.yaml` | +| `test/test-fuzz-asan.sh` | `just test-fuzz-asan` | +| `test/test-rsa-leakage.sh` | `just test-rsa-leakage`, `rsa.yaml` | | `test/test-coverage.sh` | `just test-coverage`, `just test-fuzz-coverage`, `weekly.yaml` | | `bench/bench.sh` | `just bench`, `just bench-quick` | | `ci/check-action-pins.sh` | `just check-actions`, `ci/ci-check.sh`, `ci/dependabot-smoke.sh` | @@ -24,18 +27,26 @@ its caller. | `ci/dependabot-smoke-test.sh` | `just check-actions` | | `ci/check-ci-ownership.sh` | `just check-actions`, `ci/check-ci-ownership-test.sh` | | `ci/check-ci-ownership-test.sh`| `just check-actions` | +| `ci/emit-manual-matrix-test.sh`| `just check-actions` | | `ci/pre-push-test.sh` | `just check-actions` | +| `ci/release-plan-check.sh` | `just release-check` | | `ci/release-evidence-check.sh` | `just release-tag`, `release.yaml`, `ci/release-evidence-check-test.sh` | | `ci/release-evidence-check-test.sh` | `just check-actions` | | `ci/repository-controls-evidence.sh` | `just check-repository-controls`, `release.yaml`, `ci/repository-controls-evidence-test.sh` | | `ci/repository-controls-evidence-test.sh` | `just check-actions` | | `ci/package-release-source.sh` | `release.yaml`, `ci/release-identity-test.sh` | +| `ci/package-release-ct-evidence.sh` | `release.yaml` | +| `ci/release-package-guard.sh` | `ci/release-preflight.sh` | +| `ci/release-preflight.sh` | `release.yaml` | | `ci/write-release-manifest.sh` | `release.yaml`, `ci/release-identity-test.sh` | | `ci/release-identity-test.sh` | `just check-actions` | | `ci/publish-immutable-release.sh` | `release.yaml`, `ci/publish-immutable-release-test.sh` | | `ci/publish-immutable-release-test.sh` | `just check-actions` | | `ci/release-recipes-test.sh` | `just check-actions` | | `ci/pre-push.sh` | `just push`, `just push-full` | +| `ct/artifacts.sh` | `just ct`, `just ct-artifacts`, `scripts/ct/full.py` | +| `ct/dudect.sh` | `just ct-dudect`, `scripts/ct/full.py` | +| `ct/python.sh` | CT recipes and Python-backed CT, check, and release scripts | | `update/update-all.sh` | `just update`, `just update-check` | ## Cross-platform Check Helpers @@ -61,6 +72,7 @@ its caller. | `ci/install-tools.sh` | `.github/actions/setup/action.yaml` | | `ci/dependabot-smoke.sh` | `ci.yaml` (Dependabot PR lane) | | `ci/emit-manual-matrix.sh` | `bench.yaml`, `ct.yaml` | +| `ci/mlkem-aarch64-gate.sh` | `weekly.yaml` | | `ci/nostd-wasm-suite.sh` | `ci/cross-targets.sh` | | `ci/cross-targets.sh` | `_ci-suite.yaml` (consolidated cross-target lane) |