Skip to content

feat!: audit rind's public API, and apply its decisions, before 0.2.0 - #383

Merged
kixelated merged 8 commits into
mainfrom
quest/m1/api-audit
Nov 6, 2026
Merged

kixelated merged 8 commits into
mainfrom
quest/m1/api-audit

Conversation

@kixelated

@kixelated kixelated commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Works on quest/m1/api-audit.md: audit every public item of rind and its published adapters against AGENTS.md's API rules before 0.2.0, which release-plz's moq-dev/rind#367 and the Bun PR wait on.

Problem

0.2.0 commits rind to its API under semver. Every breaking fix has to land before it, and each finding needs either a fix or a recorded maintainer decision to keep it.

Approach

  • I generated each published crate's public surface from rustdoc JSON (the quest's "cargo doc's public surface"), walked every item, and read its source against AGENTS.md's API rules: misuse fails to compile, one way to do each job, names by role (aws-lc-rs's only when as clear), one-line docs, wiped secrets. I compared each against aws-lc-rs 1.19.0 and MIGRATING.md.
  • The audit covers main at f0b7931, which includes the agreement keys from moq-dev/rind#372. I audited agreement last, after that PR merged.
  • rind-ring is checked differently: its rule is "ring 0.17's API name for name", so I diffed its surface against ring 0.17.14's.
  • The first commit fixed only non-breaking docs. The maintainer then picked each finding, and the second commit implements every pick, so 0.2.0 ships one audited break.
  • It updates every caller in the workspace: the adapters, tests, benches, fuzzers, docs, and the Lean hand models whose quotes admin/prove checks, with their definitions and theorems renamed to match.
  • The PR deletes the quest, which it completes.

Inventory

Crates audited: rind 0.1.13 (280 items: types, functions, methods, statics, variants, and fields), rind-ring 0.1.12 (204), rind-rustls 0.1.13 (51), rind-rcgen 0.1.13 (4), rind-dimpl 0.1.13, rind-jsonwebtoken 0.1.13, and rind-object-store 0.1.13 (1 each). Not audited: rind-instant-acme, rind-bench, rind-cpuid, and fuzz, which are publish = false.

The full per-item inventory, with signatures, trait impls, and doc lines, is in the PR comments, along with the script that regenerates it:

RUSTC_BOOTSTRAP=1 cargo rustdoc -p <crate> --lib -- -Z unstable-options --output-format json   # rind-ring with --features std
python3 inventory.py target/doc/<crate>.json <crate>

Mechanical checks over it:

  • Docs: every exported item in all seven crates has a doc line; none is missing.
  • MIGRATING.md: all 280 rind items are mapped. 40 appear only through a family row ("and so on", "their SHA-384 and SHA-512", "one of TagLength's"), and agreement::Scalar was named only as "to_scalar(), wiped on drop" (fixed below).
  • rind-ring vs ring 0.17.14: the names match exactly, apart from the omissions its README lists (aead::chacha20_poly1305_openssh, rsa::KeyPairComponents and KeyPair::from_components, io, test_file!) and the added cpu. Signatures match up to path spelling. Two derives differ harmlessly: error::Unspecified adds Eq, and hmac::Algorithm and pbkdf2::Algorithm implement PartialEq by hand. Their Debug gaps are ring's own.
  • Wiping: every type that owns a key or keyed state wipes it, directly or through an inner type's Drop. That includes cipher::Aes and the kem types, whose Drop rustdoc shows only on the inner type. tests/zeroing.rs covers them.

Decisions

The maintainer picked each finding on 2026-11-05, and this PR implements every pick.

Across modules

  • D1. Where Pkcs8 and Spki live (breaking): ✅ a new rind::encoding module holds them, not the crate root I recommended. Every key type that exports itself returns them, whatever its module.
  • D2. Where the shared RSA key types live (breaking): ✅ rsa::KeySize and rsa::PublicKeyComponents, aws-lc-rs's names, which signature uses from there. signature keeps no alias.
  • D3. Two ways to build an RSA public key from its components (breaking): ✅ signature::PublicKey::from_components(&alg, &components), a constructor on the type it builds, as rsa::EncryptingKey::from_components is; to_public_key is gone.
  • D4. Raw private-key loaders that don't pair with their exporters (breaking): ✅ agreement::PrivateKey::from_scalar and EcdsaKeyPair::from_scalar_and_public_key, pairing to_scalar as Ed25519's from_seed_and_public_key pairs to_seed. rind-ring keeps ring's names.
  • D5. Debug on the 16 symmetric key and state types (additive): ✅ each shows its algorithm only, never key bytes. Nonce, gcm::Iv, RandomizedNonceKey, and cipher::ChaCha20 have one algorithm or none to show, so they print ...

kem

  • D6. DecapsulationKey::decapsulate consumes the key (nominally breaking): ✅ it borrows (&self), as agree and aws-lc-rs's do. Still no loader.

aead

  • D7. gcm::Key's iv and aad are both &[u8] (breaking): ✅ a gcm::Iv<'a> from Iv::assume_unique_for_key(&[u8])?, which refuses an empty or over-long IV, is not Clone, and is consumed per call, as Nonce is.
  • D8. Four-argument open_in_place_separate_tag (keep): ✅ kept. Its four types differ, so a misordering does not compile.

cipher

  • D9. cipher::ChaCha20::new takes its key by value (breaking): ✅ new(key: &[u8; 32]), as RandomizedNonceKey::new takes it.

rsa

  • D10. rsa::OaepAlgorithm's name (keep): ✅ kept, aws-lc-rs's name; rsa now also holds key types, so the name saying OAEP is clearer.

agreement

  • D11. PrivateKey::from_sec1(&X25519, ..) compiles and always fails (keep): ✅ kept, as documented, which is aws-lc-rs's shape.

rind-rcgen

  • D12. KeyPair::to_pkcs8 returns zeroize::Zeroizing<PrivatePkcs8KeyDer<'static>> (keep): ✅ kept; zeroize has been at 1.x since 2019.

Checked and kept, with no decision needed

Each of these was checked against a rule and is kept, because the reason is recorded or upstream fixes the shape:

  • digest::Context::finish(&mut self) resets the context, unlike aws-lc-rs's finish(self): a recorded perf decision in moq-dev/rind#352.
  • PublicKey::verify_digest and EcdsaKeyPair::sign_digest refuse RSA, Ed25519, and non-SHA-2 digests at run time (Error::Unsupported): merged hours ago in moq-dev/rind#379.
  • RsaKeyPair::sign and public_key take the algorithm per call, unlike EcdsaKeyPair: an RSA key signs with several paddings (TLS uses PSS and PKCS#1 with one key). This is aws-lc-rs's shape, and the method docs say so.
  • signature::sign::X and verify::X share names, but their types differ, so a mix-up does not compile.
  • hmac::Key::algorithm() is rind's only algorithm() accessor; rind-rustls's HMAC needs it.
  • key_wrap::AES_128 and AES_256 re-export cipher::AES_128 and AES_256: the same statics, under the module aws-lc-rs puts them in.
  • rind_rustls::Ticketer::new() returns Arc<dyn ProducesTickets> from a unit struct, exactly as rustls's own providers do.
  • rind-jsonwebtoken's DEFAULT_PROVIDER is a static, so it cannot check the CPU: jsonwebtoken requires a static. The docs say to call rind::cpu::check() first.

Where rind differs from aws-lc-rs on purpose

MIGRATING.md maps each of these. In brief:

  • Algorithms are always &'static, and no call takes a random source.
  • Legacy algorithms live in legacy submodules rather than _FOR_LEGACY_USE_ONLY names.
  • One rind::Error, whose variant says which kind of call failed.
  • Outputs (encoding::Pkcs8, encoding::Spki, Signature, the OAEP Plaintext) have fixed capacity rather than being allocated.
  • Public keys are parsed when built, not when they verify: PublicKey::new, with no UnparsedPublicKey.
  • There are no SealingKey/OpeningKey/NonceSequence types: a single aead::Key takes a Nonce per call.
  • RandomizedNonceKey is XChaCha20-Poly1305 with 192-bit nonces.
  • hkdf::Prk::expand cannot fail, and KeyType is sealed.
  • pbkdf2::Secret keys HMAC once for every salt.
  • digest::Context::finish(&mut self).
  • rind refuses input aws-lc-rs takes: compressed or hybrid points where noted, small-order Ed25519 keys, bytes after an encoded key, and PKCS#8 v2 without its public key.

Impact

Breaking, so the title takes !; MIGRATING.md maps each aws-lc-rs name to the new one. Migrating from rind 0.1:

  • rind::signature::{Pkcs8, Spki} become rind::encoding::{Pkcs8, Spki}. .as_ref() callers are unaffected.
  • From moq-dev/rind#382, merged after the audit, ported to its decisions with their behavior unchanged:
    • rind::signature::Sec1, returned by EcdsaKeyPair::to_sec1, becomes rind::encoding::Sec1. This applies D1's rule (every encoded key lives in encoding) to the new type; it is an addition to encoding, not a rename of an encoding item.
    • signature::PublicKey::{from_spki, to_spki}, Ed25519KeyPair::{from_seed, to_pkcs8v1}, and agreement::PublicKey::{new, from_spki, to_spki} keep their names, which already follow the audit's rules (from_seed pairs to_seed), and return encoding::Spki and encoding::Pkcs8.
    • feat(keys): SPKI, SEC1, and seed key formats, and compressed ECDH peers, for Bun #382's tests, fuzz selectors 29 to 42, and Lean quotes use agreement::PrivateKey::from_scalar, and its docs use the audited names. README's encoding line now names SEC1.
  • rind::signature::RsaKeySize::Rsa2048 becomes rind::rsa::KeySize::Rsa2048, and rind::signature::RsaPublicKeyComponents becomes rind::rsa::PublicKeyComponents.
  • components.to_public_key(&alg)? becomes signature::PublicKey::from_components(&alg, &components)?.
  • agreement::PrivateKey::from_private_key(&alg, scalar) becomes from_scalar(&alg, scalar), and EcdsaKeyPair::from_private_key_and_public_key(&alg, scalar, point) becomes from_scalar_and_public_key(&alg, scalar, point).
  • key.decapsulate(ct) compiles unchanged and now leaves the key usable; only UFCS and stored fn pointers change.
  • gcm_key.seal_in_place_append_tag(&iv, aad, buf) becomes gcm_key.seal_in_place_append_tag(gcm::Iv::assume_unique_for_key(&iv)?, aad, buf), and the same for the other three gcm::Key methods. An empty IV now fails at Iv, with the same Error::WrongLength.
  • cipher::ChaCha20::new(key) becomes ChaCha20::new(&key).
  • Additive: Debug on digest::Context, hmac::{Key, Context}, hkdf::{Salt, Prk, Okm}, pbkdf2::Secret, aead::{Key, Nonce, RandomizedNonceKey}, aead::gcm::{Key, Iv}, aead::quic::HeaderProtectionKey, cipher::{Aes, AesCtr, ChaCha20}, and key_wrap::AesKek.

In this workspace, rind-ring and rind-jsonwebtoken change internally, with no change to their own APIs. The docs fixes from the first commit:

  • rind::agreement's module summary no longer says "Ephemeral", since feat(agreement)!: store, load, and export agreement keys, agreeing by reference #372 made its keys storable and reusable.
  • rind-rustls's Ticketer and Ticketer::new are documented by what they do, not "The default ticketer".
  • MIGRATING.md no longer says every adapter function refuses an unsupported CPU: rind_rcgen::KeyPair's constructors return rcgen's errors, which cannot carry one. It also names agreement::Scalar.

Performance: these are API moves, and the codegen shows it. Built with one codegen unit at the base and at this head, every function in rind's release rlib is the same size except the renamed loaders (same sizes under new names), the new Debug impls (44 to 202 bytes each), decapsulate, 343 bytes smaller now that it no longer drops the key, and ChaCha20 QUIC header-protection key setup, 22 bytes larger. gcm::Key's seal and open, Iv included, are byte for byte the same size. The rind-bench ML-KEM decapsulate bench now reuses one key, as aws-lc-rs's does, rather than timing a fresh key's drop.

Alternatives

  • I could have audited without rustdoc JSON, but it lists exactly what cargo doc publishes, re-exports included, so the inventory is reproducible.
  • Fixing as I went would have left 0.2.0's shape to my choices; the quest routes each one to the maintainer.

Follow-ups

  • agreement::PrivateKey's existing Debug prints PrivateKey { .. }, without its algorithm as the D5 types show theirs. It is additive, so it can ship in 0.2.x.

Validation

  • just check on b2981a8: passes, 612 tests, including the armv7 and cross legs, which caught armv7's AES-GCM key missing key_len.
  • nix develop .#prove --command admin/prove on the merged head: every quote matches and the Lean build completes (2454 jobs).
  • quest check --base origin/main: passes (68 documents).
  • New rind/tests/debug.rs pins each D5 type's Debug output and checks that no key byte shows.
  • Codegen: compared at one codegen unit against the base, as Impact describes.
  • Merged origin/main (no rebase) through 8747f62, which brought in moq-dev/rind#382's key formats (ported as Impact describes) and moq-dev/rind#376's SHA tail. On 395db17: CARGO_BUILD_JOBS=3 just check passes (623 tests), nix develop .#prove --command admin/prove passes (2454 jobs, every quote matches), and admin/bench-report render --check reports BENCHMARKS.md current.
  • Earlier, merged origin/main (no rebase) through moq-dev/rind#386, including AES-CBC from moq-dev/rind#381. Its keys' Debug already showed the algorithm only; they now share cipher::aes for it instead of a copy of that helper.

Review

Codex (gpt-6.1-sol, medium effort) reviewed head 655d0f3, the hand-resolved merge of #382, against origin/main 8747f62 with quest review: round 1, no findings. 395db17 adds only a conflict-free merge of origin/main (#376, #387, #389) on top.

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

kixelated and others added 2 commits November 5, 2026 13:26
Quest-Claim: 5bc8fde9abfd8da4
Fixes the docs the audit found stale: agreement keys are no longer only
ephemeral, ChaCha20::new and rind-rustls's Ticketer say what they do, and
MIGRATING.md no longer claims every adapter function refuses an
unsupported CPU (rind-rcgen's KeyPair returns rcgen's errors) and names
agreement::Scalar. The quest now records what remains: the maintainer's
picks on the PR's decisions, and the fixes they choose.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title rind's public API is audited before 0.2.0 docs: audit rind's public API before 0.2.0 Nov 5, 2026
@kixelated

Copy link
Copy Markdown
Collaborator Author

Audit inventory 1 of 2: rind

Generated from main at f0b7931, from rustdoc JSON (RUSTC_BOOTSTRAP=1 cargo rustdoc -p rind --lib -- -Z unstable-options --output-format json), by the script in the next comment. Each line gives an item's kind, path, signature or type, and the first line of its docs; indented lines are its inherent methods, variants, public fields, and trait impls.

rind: 280 items
mod rind::doc  -- Non-API documentation
mod rind::doc::inline_assembly_safety  -- # Safety of inline assembly
mod rind::agreement  -- Ephemeral key agreement: X25519, and ECDH on P-256, P-384, and P-521.
struct rind::agreement::Algorithm  -- A key agreement algorithm: a curve and its public key encoding.
    impls: Debug
static rind::agreement::ECDH_P256: Algorithm  -- ECDH on P-256, with X9.62 uncompressed public keys.
static rind::agreement::ECDH_P384: Algorithm  -- ECDH on P-384, with X9.62 uncompressed public keys.
static rind::agreement::ECDH_P521: Algorithm  -- ECDH on P-521, with X9.62 uncompressed public keys.
struct rind::agreement::PrivateKey  -- A private key, which agrees with any number of peers, wiped on drop.
    function generate(algorithm: &'static Algorithm) -> Result<Self, Error>  -- Generates a private key for `algorithm` from the system random source.
    function from_private_key(algorithm: &'static Algorithm, scalar: &[u8]) -> Result<Self, Error>  -- Loads a private key for `algorithm` from its scalar: X25519's 32
    function from_pkcs8(algorithm: &'static Algorithm, der: &[u8]) -> Result<Self, Error>  -- Loads a PKCS#8 private key for `algorithm`.
    function from_sec1(algorithm: &'static Algorithm, der: &[u8]) -> Result<Self, Error>  -- Loads a SEC1 (RFC 5915) `ECPrivateKey` on `algorithm`'s curve, as
    function public_key(self: &Self) -> PublicKey  -- Returns the public key to send to the peer.
    function agree(self: &Self, peer: &[u8]) -> Result<SharedSecret, Error>  -- Agrees on a secret with the peer's encoded public key.
    function to_pkcs8(self: &Self) -> Pkcs8  -- Encodes the private key as PKCS#8: v1 for X25519, and for a NIST
    function to_scalar(self: &Self) -> Scalar  -- Encodes the private key as the scalar [`Self::from_private_key`] loads.
    impls: Debug, Drop
struct rind::agreement::PublicKey  -- Our public key: 32 bytes for X25519, or an X9.62 uncompressed point.
    impls: AsRef<[u8]>, Clone, Debug
struct rind::agreement::Scalar  -- A private key as its scalar, which [`PrivateKey::from_private_key`]
    impls: AsRef<[u8]>, Debug, Drop
struct rind::agreement::SharedSecret  -- The secret both parties agree on, wiped on drop.
    impls: AsRef<[u8]>, Debug, Drop
static rind::agreement::X25519: Algorithm  -- X25519, with 32-byte public keys.
mod rind::kem  -- Key encapsulation: ML-KEM-768.
struct rind::kem::Algorithm  -- A key encapsulation mechanism.
    impls: Debug
struct rind::kem::Ciphertext  -- A ciphertext carrying an encapsulated secret, to send to the key's holder.
    impls: AsRef<[u8]>, Clone, Debug
struct rind::kem::DecapsulationKey  -- A decapsulation key, used for one decapsulation and wiped on drop.
    function generate(algorithm: &'static Algorithm) -> Result<Self, Error>  -- Generates a decapsulation key for `algorithm` from the system random source.
    function public_key(self: &Self) -> EncapsulationKey  -- Returns the encapsulation key to send to the peer.
    function decapsulate(self: Self, ciphertext: &[u8]) -> Result<SharedSecret, Error>  -- Recovers the secret the peer encapsulated in `ciphertext`, consuming this key.
    impls: Debug
struct rind::kem::EncapsulationKey  -- An encapsulation key, which anyone may encapsulate a secret to.
    function new(algorithm: &'static Algorithm, bytes: &[u8]) -> Result<Self, Error>  -- Parses a peer's encapsulation key for `algorithm`.
    function encapsulate(self: &Self) -> Result<(Ciphertext, SharedSecret), Error>  -- Encapsulates a fresh random secret, returning the ciphertext to send
    impls: AsRef<[u8]>, Clone, Debug
static rind::kem::ML_KEM_768: Algorithm  -- ML-KEM-768, as standardised by FIPS-203.
struct rind::kem::SharedSecret  -- The secret both parties share, wiped on drop.
    impls: AsRef<[u8]>, Debug
mod rind::rsa  -- RSA encryption: RSA-OAEP with SHA-256, SHA-384, or SHA-512, and SHA-1
mod rind::rsa::legacy  -- RSA-OAEP with SHA-1, for protocols that still require it.
static rind::rsa::legacy::OAEP_SHA1: OaepAlgorithm  -- RSA-OAEP with SHA-1 and MGF1 with SHA-1, JWE's `RSA-OAEP`.
struct rind::rsa::Ciphertext  -- An RSA-OAEP ciphertext, as long as the modulus.
    impls: AsRef<[u8]>, Clone, Debug
struct rind::rsa::DecryptingKey  -- A two-prime RSA private key, with a modulus of 2048 to 8192 bits, bound
    function generate(algorithm: &'static OaepAlgorithm, size: RsaKeySize) -> Result<Self, Error>  -- Generates a key of `size` for `algorithm` from the system random
    function from_pkcs8(algorithm: &'static OaepAlgorithm, der: &[u8]) -> Result<Self, Error>  -- Loads a PKCS#8 v1 `rsaEncryption` private key for `algorithm`.
    function from_pkcs1(algorithm: &'static OaepAlgorithm, der: &[u8]) -> Result<Self, Error>  -- Loads a PKCS#1 `RSAPrivateKey` for `algorithm`.
    function public_key(self: &Self) -> EncryptingKey  -- Returns the public key, which encrypts to this key with its
    function decrypt(self: &Self, ciphertext: &[u8], label: &[u8]) -> Result<Plaintext, Error>  -- Decrypts `ciphertext`, which must have been encrypted with `label`.
    function to_pkcs8(self: &Self) -> Pkcs8  -- Encodes the private key as PKCS#8.
    function to_spki(self: &Self) -> Spki  -- Encodes the public key as a `SubjectPublicKeyInfo`.
    impls: Debug, Drop
struct rind::rsa::EncryptingKey  -- An RSA public key, with a modulus of 2048 to 8192 bits, bound to the one
    function new(algorithm: &'static OaepAlgorithm, der: &[u8]) -> Result<Self, Error>  -- Parses a PKCS#1 `RSAPublicKey` or a `SubjectPublicKeyInfo` for
    function from_components(algorithm: &'static OaepAlgorithm, components: &RsaPublicKeyComponents<impl AsRef>) -> Result<Self, Error>  -- Loads a key for `algorithm` from its big-endian modulus and exponent,
    function encrypt(self: &Self, message: &[u8], label: &[u8]) -> Result<Ciphertext, Error>  -- Encrypts `message` with `label`, which may be empty, returning a
    function max_message_len(self: &Self) -> usize  -- Returns the longest message this key encrypts: the modulus length,
    impls: AsRef<[u8]>, Debug
static rind::rsa::OAEP_SHA256: OaepAlgorithm  -- RSA-OAEP with SHA-256 and MGF1 with SHA-256.
static rind::rsa::OAEP_SHA384: OaepAlgorithm  -- RSA-OAEP with SHA-384 and MGF1 with SHA-384.
static rind::rsa::OAEP_SHA512: OaepAlgorithm  -- RSA-OAEP with SHA-512 and MGF1 with SHA-512.
struct rind::rsa::OaepAlgorithm  -- An RSA-OAEP algorithm: a hash, which MGF1 also uses.
    impls: Debug
struct rind::rsa::Plaintext  -- A decrypted message, wiped on drop.
    impls: AsRef<[u8]>, Debug, Drop
mod rind::signature  -- Public key signatures: ECDSA on P-256, P-384, and P-521, RSA, and Ed25519.
mod rind::signature::sign  -- Algorithms a key pair signs with.
static rind::signature::sign::ECDSA_P256_SHA256_ASN1: EcdsaSigningAlgorithm  -- ECDSA on P-256 with SHA-256, ASN.1 signatures.
static rind::signature::sign::ECDSA_P256_SHA256_FIXED: EcdsaSigningAlgorithm  -- ECDSA on P-256 with SHA-256, fixed-length `r || s` signatures (JWS's ES256).
static rind::signature::sign::ECDSA_P384_SHA384_ASN1: EcdsaSigningAlgorithm  -- ECDSA on P-384 with SHA-384, ASN.1 signatures.
static rind::signature::sign::ECDSA_P384_SHA384_FIXED: EcdsaSigningAlgorithm  -- ECDSA on P-384 with SHA-384, fixed-length `r || s` signatures (JWS's ES384).
static rind::signature::sign::ECDSA_P521_SHA512_ASN1: EcdsaSigningAlgorithm  -- ECDSA on P-521 with SHA-512, ASN.1 signatures.
static rind::signature::sign::ECDSA_P521_SHA512_FIXED: EcdsaSigningAlgorithm  -- ECDSA on P-521 with SHA-512, fixed-length `r || s` signatures (JWS's ES512).
static rind::signature::sign::RSA_PKCS1_SHA256: RsaSigningAlgorithm  -- RSASSA-PKCS1-v1_5 with SHA-256.
static rind::signature::sign::RSA_PKCS1_SHA384: RsaSigningAlgorithm  -- RSASSA-PKCS1-v1_5 with SHA-384.
static rind::signature::sign::RSA_PKCS1_SHA512: RsaSigningAlgorithm  -- RSASSA-PKCS1-v1_5 with SHA-512.
static rind::signature::sign::RSA_PSS_SHA256: RsaSigningAlgorithm  -- RSASSA-PSS with SHA-256, MGF1-SHA-256, and a 32-byte salt.
static rind::signature::sign::RSA_PSS_SHA384: RsaSigningAlgorithm  -- RSASSA-PSS with SHA-384, MGF1-SHA-384, and a 48-byte salt.
static rind::signature::sign::RSA_PSS_SHA512: RsaSigningAlgorithm  -- RSASSA-PSS with SHA-512, MGF1-SHA-512, and a 64-byte salt.
mod rind::signature::verify  -- Algorithms a public key verifies with.
mod rind::signature::verify::legacy  -- RSA algorithms with another modulus floor, or SHA-1, for old keys
static rind::signature::verify::legacy::RSA_PKCS1_1024_SHA1: RsaVerificationAlgorithm  -- RSASSA-PKCS1-v1_5 with SHA-1, for old signatures by keys with moduli down to 1024 bits.
static rind::signature::verify::legacy::RSA_PKCS1_1024_SHA256: RsaVerificationAlgorithm  -- RSASSA-PKCS1-v1_5 with SHA-256, for old keys with moduli down to 1024 bits.
static rind::signature::verify::legacy::RSA_PKCS1_1024_SHA512: RsaVerificationAlgorithm  -- RSASSA-PKCS1-v1_5 with SHA-512, for old keys with moduli down to 1024 bits.
static rind::signature::verify::legacy::RSA_PKCS1_3072_SHA384: RsaVerificationAlgorithm  -- RSASSA-PKCS1-v1_5 with SHA-384, for moduli of 3072 to 8192 bits.
static rind::signature::verify::legacy::RSA_PKCS1_SHA1: RsaVerificationAlgorithm  -- RSASSA-PKCS1-v1_5 with SHA-1, for old signatures only: SHA-1 collisions are practical.
static rind::signature::verify::ECDSA_P256_SHA256_ASN1: VerificationAlgorithm  -- ECDSA on P-256 with SHA-256, ASN.1 signatures.
static rind::signature::verify::ECDSA_P256_SHA256_FIXED: VerificationAlgorithm  -- ECDSA on P-256 with SHA-256, fixed-length `r || s` signatures (JWS's ES256).
static rind::signature::verify::ECDSA_P256_SHA384_ASN1: VerificationAlgorithm  -- ECDSA on P-256 with SHA-384, ASN.1 signatures.
static rind::signature::verify::ECDSA_P256_SHA512_ASN1: VerificationAlgorithm  -- ECDSA on P-256 with SHA-512, ASN.1 signatures.
static rind::signature::verify::ECDSA_P384_SHA256_ASN1: VerificationAlgorithm  -- ECDSA on P-384 with SHA-256, ASN.1 signatures.
static rind::signature::verify::ECDSA_P384_SHA384_ASN1: VerificationAlgorithm  -- ECDSA on P-384 with SHA-384, ASN.1 signatures.
static rind::signature::verify::ECDSA_P384_SHA384_FIXED: VerificationAlgorithm  -- ECDSA on P-384 with SHA-384, fixed-length `r || s` signatures (JWS's ES384).
static rind::signature::verify::ECDSA_P384_SHA512_ASN1: VerificationAlgorithm  -- ECDSA on P-384 with SHA-512, ASN.1 signatures.
static rind::signature::verify::ECDSA_P521_SHA256_ASN1: VerificationAlgorithm  -- ECDSA on P-521 with SHA-256, ASN.1 signatures.
static rind::signature::verify::ECDSA_P521_SHA384_ASN1: VerificationAlgorithm  -- ECDSA on P-521 with SHA-384, ASN.1 signatures.
static rind::signature::verify::ECDSA_P521_SHA512_ASN1: VerificationAlgorithm  -- ECDSA on P-521 with SHA-512, ASN.1 signatures.
static rind::signature::verify::ECDSA_P521_SHA512_FIXED: VerificationAlgorithm  -- ECDSA on P-521 with SHA-512, fixed-length `r || s` signatures (JWS's ES512).
static rind::signature::verify::ED25519: VerificationAlgorithm  -- Ed25519, with 32-byte public keys and 64-byte signatures.
static rind::signature::verify::RSA_PKCS1_SHA256: RsaVerificationAlgorithm  -- RSASSA-PKCS1-v1_5 with SHA-256, for moduli of 2048 to 8192 bits.
static rind::signature::verify::RSA_PKCS1_SHA384: RsaVerificationAlgorithm  -- RSASSA-PKCS1-v1_5 with SHA-384, for moduli of 2048 to 8192 bits.
static rind::signature::verify::RSA_PKCS1_SHA512: RsaVerificationAlgorithm  -- RSASSA-PKCS1-v1_5 with SHA-512, for moduli of 2048 to 8192 bits.
static rind::signature::verify::RSA_PSS_SHA256: RsaVerificationAlgorithm  -- RSASSA-PSS with SHA-256, MGF1-SHA-256, and a 32-byte salt, for moduli of 2048 to 8192 bits.
static rind::signature::verify::RSA_PSS_SHA256_ANY_SALT: RsaVerificationAlgorithm  -- RSASSA-PSS with SHA-256, MGF1-SHA-256, and a salt of any length, for moduli of 2048 to 8192 bits.
static rind::signature::verify::RSA_PSS_SHA384: RsaVerificationAlgorithm  -- RSASSA-PSS with SHA-384, MGF1-SHA-384, and a 48-byte salt, for moduli of 2048 to 8192 bits.
static rind::signature::verify::RSA_PSS_SHA384_ANY_SALT: RsaVerificationAlgorithm  -- RSASSA-PSS with SHA-384, MGF1-SHA-384, and a salt of any length, for moduli of 2048 to 8192 bits.
static rind::signature::verify::RSA_PSS_SHA512: RsaVerificationAlgorithm  -- RSASSA-PSS with SHA-512, MGF1-SHA-512, and a 64-byte salt, for moduli of 2048 to 8192 bits.
static rind::signature::verify::RSA_PSS_SHA512_ANY_SALT: RsaVerificationAlgorithm  -- RSASSA-PSS with SHA-512, MGF1-SHA-512, and a salt of any length, for moduli of 2048 to 8192 bits.
struct rind::signature::EcdsaKeyPair  -- An ECDSA private key and its public key, bound to one signing algorithm.
    function generate(algorithm: &'static EcdsaSigningAlgorithm) -> Result<Self, Error>  -- Generates a key pair for `algorithm` from the system random source.
    function from_pkcs8(algorithm: &'static EcdsaSigningAlgorithm, der: &[u8]) -> Result<Self, Error>  -- Loads a PKCS#8 v1 `ECPrivateKey` on `algorithm`'s curve.
    function from_sec1(algorithm: &'static EcdsaSigningAlgorithm, der: &[u8]) -> Result<Self, Error>  -- Loads a SEC1 (RFC 5915) `ECPrivateKey` on `algorithm`'s curve.
    function from_private_key_and_public_key(algorithm: &'static EcdsaSigningAlgorithm, private_key: &[u8], public_key: &[u8]) -> Result<Self, Error>  -- Loads a fixed-length big-endian private scalar, refused unless
    function public_key(self: &Self) -> PublicKey  -- Returns the public key, which verifies what this key pair signs.
    function sign(self: &Self, message: &[u8]) -> Result<Signature, Error>  -- Signs `message` with a fresh nonce.
    function sign_digest(self: &Self, digest: &Digest) -> Result<Signature, Error>  -- Signs the message `digest` hashes, with a fresh nonce.
    function to_pkcs8(self: &Self) -> Pkcs8  -- Encodes the private key as PKCS#8.
    function to_scalar(self: &Self) -> EcdsaScalar  -- Encodes the private key as a big-endian scalar exactly the curve's
    function to_spki(self: &Self) -> Spki  -- Encodes the public key as a `SubjectPublicKeyInfo`.
    impls: Debug, Drop
struct rind::signature::EcdsaScalar  -- An ECDSA private key as a big-endian scalar exactly the curve's length,
    impls: AsRef<[u8]>, Debug, Drop
struct rind::signature::EcdsaSigningAlgorithm  -- An ECDSA signing algorithm, which an [`EcdsaKeyPair`] is bound to.
    impls: Debug
struct rind::signature::Ed25519KeyPair  -- An Ed25519 private key and its public key.
    function generate() -> Result<Self, Error>  -- Generates a key pair from the system random source.
    function from_pkcs8(der: &[u8]) -> Result<Self, Error>  -- Loads a PKCS#8 Ed25519 key, refused if it carries a public key
    function from_seed_and_public_key(seed: &[u8], public_key: &[u8]) -> Result<Self, Error>  -- Loads a 32-byte seed, refused unless `public_key` is its public key.
    function public_key(self: &Self) -> PublicKey  -- Returns the public key, which verifies what this key pair signs.
    function sign(self: &Self, message: &[u8]) -> Signature  -- Signs `message`.
    function to_pkcs8(self: &Self) -> Pkcs8  -- Encodes the key pair as PKCS#8 v2 (RFC 5958).
    function to_seed(self: &Self) -> Ed25519Seed  -- Returns the private key's 32-byte seed, as a JWK's `d` holds it.
    function to_spki(self: &Self) -> Spki  -- Encodes the public key as a `SubjectPublicKeyInfo`.
    impls: Debug, Drop
struct rind::signature::Ed25519Seed  -- An Ed25519 private key as its 32-byte seed, wiped on drop.
    impls: AsRef<[u8]>, Debug, Drop
struct rind::signature::Pkcs8  -- A private key encoded as PKCS#8 DER, wiped on drop.
    impls: AsRef<[u8]>, Debug, Drop
struct rind::signature::PublicKey  -- A public key, bound to the one algorithm it verifies signatures with.
    function new(algorithm: &impl AsRef, bytes: &[u8]) -> Result<Self, Error>  -- Parses a public key for `algorithm`, any `verify` constant,
    function verify(self: &Self, message: &[u8], signature: &[u8]) -> Result<(), Error>  -- Verifies `signature` over `message`, refusing a malformed signature.
    function verify_digest(self: &Self, digest: &Digest, signature: &[u8]) -> Result<(), Error>  -- Verifies an ECDSA `signature` over the message `digest` hashes.
    impls: AsRef<[u8]>, Debug
struct rind::signature::RsaKeyPair  -- A two-prime RSA private key, with a modulus of 2048 to 8192 bits, and its public key.
    function generate(size: RsaKeySize) -> Result<Self, Error>  -- Generates a key pair of `size` from the system random source.
    function from_pkcs8(der: &[u8]) -> Result<Self, Error>  -- Loads a PKCS#8 v1 `rsaEncryption` private key.
    function from_pkcs1(der: &[u8]) -> Result<Self, Error>  -- Loads a PKCS#1 `RSAPrivateKey`.
    function public_key(self: &Self, algorithm: &RsaSigningAlgorithm) -> PublicKey  -- Returns the public key, which verifies what this key pair signs with
    function sign(self: &Self, algorithm: &RsaSigningAlgorithm, message: &[u8]) -> Result<Signature, Error>  -- Signs `message` with `algorithm`, as long as the modulus.
    function to_pkcs8(self: &Self) -> Pkcs8  -- Encodes the private key as PKCS#8.
    function to_spki(self: &Self) -> Spki  -- Encodes the public key as a `SubjectPublicKeyInfo`.
    impls: Debug, Drop
enum rind::signature::RsaKeySize  -- The modulus size of an RSA key pair to generate.
    variant Rsa2048  -- A 2048-bit modulus.
    variant Rsa3072  -- A 3072-bit modulus.
    variant Rsa4096  -- A 4096-bit modulus.
    variant Rsa6144  -- A 6144-bit modulus.
    variant Rsa8192  -- An 8192-bit modulus.
    impls: Clone, Copy, Debug, PartialEq, StructuralPartialEq
enum rind::signature::RsaPssSaltLength  -- How long an RSASSA-PSS salt is, beside the hash's length that the
    variant Max  -- The longest the modulus allows: the encoded message's length, a byte
    variant Custom  -- This many bytes, refusing a modulus too short for them.
    impls: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq
struct rind::signature::RsaPublicKeyComponents  -- An RSA public key as its big-endian modulus and exponent, as a JWK
    field n: B  -- The modulus, without leading zero bytes.
    field e: B  -- The public exponent, without leading zero bytes.
    function to_public_key(self: &Self, algorithm: &RsaVerificationAlgorithm) -> Result<PublicKey, Error>  -- Parses this key for `algorithm`.
    impls: Clone, Copy, Debug
struct rind::signature::RsaSigningAlgorithm  -- An RSA signing algorithm: a padding and a hash, for [`RsaKeyPair::sign`].
    function pss_sha256(salt_length: RsaPssSaltLength) -> Self  -- RSASSA-PSS with SHA-256, MGF1-SHA-256, and a salt of `salt_length`.
    function pss_sha384(salt_length: RsaPssSaltLength) -> Self  -- RSASSA-PSS with SHA-384, MGF1-SHA-384, and a salt of `salt_length`.
    function pss_sha512(salt_length: RsaPssSaltLength) -> Self  -- RSASSA-PSS with SHA-512, MGF1-SHA-512, and a salt of `salt_length`.
    impls: Debug
struct rind::signature::RsaVerificationAlgorithm  -- An RSA signature verification algorithm, which also parses
    function pss_sha256(salt_length: RsaPssSaltLength) -> Self  -- RSASSA-PSS with SHA-256, MGF1-SHA-256, and a salt of `salt_length`,
    function pss_sha384(salt_length: RsaPssSaltLength) -> Self  -- RSASSA-PSS with SHA-384, MGF1-SHA-384, and a salt of `salt_length`,
    function pss_sha512(salt_length: RsaPssSaltLength) -> Self  -- RSASSA-PSS with SHA-512, MGF1-SHA-512, and a salt of `salt_length`,
    impls: AsRef<VerificationAlgorithm>, Debug
struct rind::signature::Signature  -- A signature from any key pair.
    impls: AsRef<[u8]>, Clone, Copy, Debug
struct rind::signature::Spki  -- A public key encoded as a `SubjectPublicKeyInfo` in DER.
    impls: AsRef<[u8]>, Clone, Debug
struct rind::signature::VerificationAlgorithm  -- A signature verification algorithm, which a [`PublicKey`] is bound to.
    impls: AsRef<VerificationAlgorithm>, AsRef<VerificationAlgorithm>, Debug
mod rind::digest  -- Cryptographic hash functions.
mod rind::digest::legacy  -- Hash functions only legacy protocols should use.
static rind::digest::legacy::SHA1: Algorithm  -- SHA-1, for legacy protocols only: its collision resistance is broken.
struct rind::digest::Algorithm  -- A hash function, chosen by one of this module's constants.
    function output_len(self: &Self) -> usize  -- The length of this algorithm's digest, in bytes.
    impls: Debug
struct rind::digest::Context  -- An in-progress hash computation, wiped on drop.
    function new(algorithm: &'static Algorithm) -> Self  -- Starts hashing with `algorithm`.
    function update(self: &mut Self, data: &[u8])  -- Adds `data` to the message.
    function finish(self: &mut Self) -> Digest  -- Returns the digest of the message, and starts a new one with the same algorithm.
    impls: Clone, Drop
struct rind::digest::Digest  -- The output of a hash function.
    impls: AsRef<[u8]>, Clone, Debug
static rind::digest::SHA3_256: Algorithm  -- SHA3-256, from [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf).
static rind::digest::SHA3_384: Algorithm  -- SHA3-384, from [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf).
static rind::digest::SHA3_512: Algorithm  -- SHA3-512, from [FIPS 202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf).
static rind::digest::SHA256: Algorithm  -- SHA-256, from [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
static rind::digest::SHA384: Algorithm  -- SHA-384, from [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
static rind::digest::SHA512: Algorithm  -- SHA-512, from [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
static rind::digest::SHA512_256: Algorithm  -- SHA-512/256: SHA-512 with its own initial value, truncated to 256 bits, from [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
function rind::digest::digest(algorithm: &'static Algorithm, data: &[u8]) -> Digest  -- Hashes `data` in one go.
mod rind::hmac  -- Message authentication with HMAC.
mod rind::hmac::legacy  -- HMAC algorithms only legacy protocols should use.
static rind::hmac::legacy::HMAC_SHA1: Algorithm  -- HMAC-SHA1, for legacy protocols only.
struct rind::hmac::Algorithm  -- An HMAC algorithm, chosen by one of this module's constants.
    function tag_len(self: &Self) -> usize  -- The length of this algorithm's tag, in bytes.
    impls: Debug, KeyType
struct rind::hmac::Context  -- An in-progress tag computation, for a message given in pieces.
    function with_key(key: &Key) -> Self  -- Starts a tag computation under `key`.
    function update(self: &mut Self, data: &[u8])  -- Adds `data` to the message.
    function sign(self: Self) -> Tag  -- Returns the tag of the message.
    impls: Clone
static rind::hmac::HMAC_SHA256: Algorithm  -- HMAC-SHA256.
static rind::hmac::HMAC_SHA384: Algorithm  -- HMAC-SHA384.
static rind::hmac::HMAC_SHA512: Algorithm  -- HMAC-SHA512.
struct rind::hmac::Key  -- An HMAC key, keyed once and reused for every message; wiped on drop.
    function new(algorithm: &'static Algorithm, key_value: &[u8]) -> Self  -- Keys `algorithm` with `key_value`, which may be any length.
    function algorithm(self: &Self) -> &'static Algorithm  -- The algorithm this key was made for.
    impls: Clone, From<Okm<'_, &'static Algorithm>>
struct rind::hmac::Tag  -- An HMAC tag.
    impls: AsRef<[u8]>, Clone, Debug
function rind::hmac::sign(key: &Key, data: &[u8]) -> Tag  -- Returns the tag of `data` under `key`.
function rind::hmac::verify(key: &Key, data: &[u8], tag: &[u8]) -> Result<(), crate::Error>  -- Checks in constant time that `tag` is the whole tag of `data` under `key`.
mod rind::constant_time  -- Constant-time comparison, for checking a secret such as a MAC or token.
function rind::constant_time::verify(a: &[u8], b: &[u8]) -> Result<(), crate::Error>  -- Checks in constant time that `a` and `b` hold the same bytes.
mod rind::hkdf  -- Key derivation with HKDF.
mod rind::hkdf::legacy  -- HKDF algorithms only legacy protocols should use.
static rind::hkdf::legacy::HKDF_SHA1: Algorithm  -- HKDF-SHA1, for legacy protocols only.
struct rind::hkdf::Algorithm  -- An HKDF algorithm, chosen by one of this module's constants.
    impls: Debug
static rind::hkdf::HKDF_SHA256: Algorithm  -- HKDF-SHA256.
static rind::hkdf::HKDF_SHA384: Algorithm  -- HKDF-SHA384.
static rind::hkdf::HKDF_SHA512: Algorithm  -- HKDF-SHA512.
trait rind::hkdf::KeyType  -- A length of HKDF output: a plain `usize`, or the algorithm of the key it becomes.
struct rind::hkdf::Okm  -- Key material from [`Prk::expand`], sized by `L`: fill a buffer for a `usize` length, or convert it into the key an algorithm names.
    function fill(self: Self, out: &mut [u8]) -> Result<(), Error>  -- Writes the key material into `out`.
    impls: From<Okm<'_, &'static Algorithm>>, From<Okm<'_, &'static Algorithm>>, From<Okm<'_, &'static Algorithm>>
struct rind::hkdf::Prk  -- A pseudorandom key, from which [`Prk::expand`] derives any number of keys; wiped on drop.
    function expand(self: &'a Self, info: &'a [&'a [u8]], len: L) -> Okm<'a, L>  -- Derives key material for the concatenation of `info` (HKDF-Expand), as long as `len` says.
struct rind::hkdf::Salt  -- A salt, keyed once and reused for every secret it extracts from.
    function new(algorithm: &'static Algorithm, value: &[u8]) -> Self  -- Keys `algorithm` with `value`; an empty `value` is RFC 5869's absent salt.
    function extract(self: &Self, secret: &[u8]) -> Prk  -- Extracts a pseudorandom key from `secret` (HKDF-Extract).
mod rind::pbkdf2  -- Password-based key derivation with PBKDF2.
mod rind::pbkdf2::legacy  -- PBKDF2 algorithms only legacy formats should use.
static rind::pbkdf2::legacy::PBKDF2_HMAC_SHA1: Algorithm  -- PBKDF2-HMAC-SHA1, for legacy formats only.
struct rind::pbkdf2::Algorithm  -- A PBKDF2 algorithm, chosen by one of this module's constants.
    impls: Debug
static rind::pbkdf2::PBKDF2_HMAC_SHA256: Algorithm  -- PBKDF2-HMAC-SHA256.
static rind::pbkdf2::PBKDF2_HMAC_SHA384: Algorithm  -- PBKDF2-HMAC-SHA384.
static rind::pbkdf2::PBKDF2_HMAC_SHA512: Algorithm  -- PBKDF2-HMAC-SHA512.
struct rind::pbkdf2::Secret  -- A secret, such as a password, keyed once for every salt it derives with; wiped on drop.
    function new(algorithm: &'static Algorithm, secret: &[u8]) -> Self  -- Keys `algorithm` with `secret`, which may be any length.
    function derive(self: &Self, iterations: NonZeroU32, salt: &[u8], out: &mut [u8]) -> Result<(), Error>  -- Fills `out` with the key derived from `salt` over `iterations` rounds.
    function verify(self: &Self, iterations: NonZeroU32, salt: &[u8], previously_derived: &[u8]) -> Result<(), Error>  -- Checks in constant time that `previously_derived` is what [`Secret::derive`] makes for `salt` and `iterations`.
mod rind::aead  -- Authenticated encryption.
mod rind::aead::quic  -- QUIC header protection (RFC 9001 section 5.4): the mask a key derives from
constant rind::aead::quic::SAMPLE_LEN: usize  -- The length of a header-protection sample, in bytes, for every algorithm.
struct rind::aead::quic::Algorithm  -- A header-protection cipher, which fixes the key length a key must have.
    function key_len(self: &Self) -> usize  -- The length of a key, in bytes.
    impls: Debug, KeyType
static rind::aead::quic::AES_128: Algorithm  -- AES-128 header protection, which QUIC pairs with AES-128-GCM.
static rind::aead::quic::AES_256: Algorithm  -- AES-256 header protection, which QUIC pairs with AES-256-GCM.
static rind::aead::quic::CHACHA20: Algorithm  -- ChaCha20 header protection, which QUIC pairs with ChaCha20-Poly1305.
struct rind::aead::quic::HeaderProtectionKey  -- A header-protection key, expanded once for its algorithm and wiped on drop.
    function new(algorithm: &'static Algorithm, key: &[u8]) -> Result<Self, Error>  -- Expands `key` for `algorithm`, failing with [`Error::WrongLength`] if
    function mask(self: &Self, sample: &[u8; 16]) -> [u8; 5]  -- Computes the mask for `sample`: its first byte masks the packet's first
    impls: From<Okm<'_, &'static Algorithm>>
mod rind::aead::gcm  -- AES-GCM with an IV of any length and a tag of any length NIST allows, for
enum rind::aead::gcm::TagLength  -- How long an AES-GCM tag is: one of NIST SP 800-38D's lengths, named in bits.
    variant Full  -- The whole 128-bit tag.
    variant Truncated120  -- The first 120 bits of the tag.
    variant Truncated112  -- The first 112 bits of the tag.
    variant Truncated104  -- The first 104 bits of the tag.
    variant Truncated96  -- The first 96 bits of the tag.
    variant Truncated64  -- The first 64 bits of the tag.
    variant Truncated32  -- The first 32 bits of the tag.
    impls: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq
struct rind::aead::gcm::Key  -- An AES-GCM key that takes an IV of any length and makes tags of one
    function new(algorithm: &'static Algorithm, key: &[u8], tag_len: TagLength) -> Result<Self, Error>  -- Expands `key` for `algorithm`, to make tags of `tag_len`, failing with
    function tag_len(self: &Self) -> usize  -- The length of this key's tags, in bytes.
    function seal_in_place_separate_tag(self: &Self, iv: &[u8], aad: &[u8], in_out: &mut [u8]) -> Result<Tag, Error>  -- Encrypts `in_out` in place under `iv` and returns the tag.
    function seal_in_place_append_tag(self: &Self, iv: &[u8], aad: &[u8], in_out: &mut InOut) -> Result<(), Error>  -- Encrypts `in_out` in place under `iv` and appends the tag to it.
    function open_in_place(self: &Self, iv: &[u8], aad: &[u8], in_out: &'a mut [u8]) -> Result<&'a mut [u8], Error>  -- Decrypts and verifies `in_out`, the ciphertext followed by its tag of
    function open_in_place_separate_tag(self: &Self, iv: &[u8], aad: &[u8], tag: &[u8], in_out: &'a mut [u8]) -> Result<&'a mut [u8], Error>  -- Decrypts and verifies `in_out` against the separate `tag`, and returns
    impls: Drop
struct rind::aead::gcm::Tag  -- A tag [`Key`] sealed, of its [`TagLength`].
    impls: AsRef<[u8]>, Clone, Copy, Debug
struct rind::aead::Algorithm  -- An AEAD algorithm, which fixes the key length a key must have.
    function key_len(self: &Self) -> usize  -- The length of a key, in bytes.
    function tag_len(self: &Self) -> usize  -- The length of a tag, in bytes.
    function nonce_len(self: &Self) -> usize  -- The length of a nonce, in bytes.
    impls: Debug, KeyType
static rind::aead::AES_128_GCM: Algorithm  -- AES-128 in GCM mode, with a 16-byte key.
static rind::aead::AES_256_GCM: Algorithm  -- AES-256 in GCM mode, with a 32-byte key.
static rind::aead::CHACHA20_POLY1305: Algorithm  -- ChaCha20-Poly1305 from RFC 8439, with a 32-byte key.
struct rind::aead::Key  -- An AEAD key that seals with any nonce the caller gives it; wiped on drop.
    function new(algorithm: &'static Algorithm, key: &[u8]) -> Result<Self, Error>  -- Expands `key` for `algorithm`, failing with [`Error::WrongLength`] if
    function seal_in_place_separate_tag(self: &Self, nonce: Nonce, aad: &[u8], in_out: &mut [u8]) -> Result<Tag, Error>  -- Encrypts `in_out` in place and returns the tag.
    function seal_in_place_append_tag(self: &Self, nonce: Nonce, aad: &[u8], in_out: &mut InOut) -> Result<(), Error>  -- Encrypts `in_out` in place and appends the tag to it.
    function open_in_place(self: &Self, nonce: Nonce, aad: &[u8], in_out: &'a mut [u8]) -> Result<&'a mut [u8], Error>  -- Decrypts and verifies `in_out`, the ciphertext followed by its tag, and
    function open_in_place_separate_tag(self: &Self, nonce: Nonce, aad: &[u8], tag: Tag, in_out: &'a mut [u8]) -> Result<&'a mut [u8], Error>  -- Decrypts and verifies `in_out` against the separate `tag`, and returns
    impls: From<Okm<'_, &'static Algorithm>>
struct rind::aead::Nonce  -- A 96-bit nonce, which the caller promises seals only once under a key.
    function assume_unique_for_key(nonce: [u8; 12]) -> Self  -- Wraps `nonce`, which the caller promises is never reused with the same key.
struct rind::aead::Tag  -- An authentication tag: returned by sealing, or parsed from received bytes for opening.
    impls: AsRef<[u8]>, Clone, Copy, Debug, TryFrom<&[u8]>
struct rind::aead::RandomizedNonceKey  -- An XChaCha20-Poly1305 key that picks a random 192-bit nonce for every seal.
    function new(key: &[u8; 32]) -> Self  -- Makes a key from 32 bytes of key material.
    function seal_in_place_append_tag(self: &Self, aad: &[u8], in_out: &mut InOut) -> Result<RandomNonce, Error>  -- Encrypts `in_out` in place under a fresh random nonce, appends the tag,
    function open_in_place(self: &Self, nonce: RandomNonce, aad: &[u8], in_out: &'a mut [u8]) -> Result<&'a mut [u8], Error>  -- Decrypts and verifies `in_out`, the ciphertext followed by its tag,
struct rind::aead::RandomNonce  -- The 192-bit nonce a [`RandomizedNonceKey`] picked, to send with its ciphertext.
    impls: AsRef<[u8]>, Clone, Copy, Debug, From<[u8; 24]>
mod rind::cipher  -- Unauthenticated ciphers, for protocols that specify one alongside their own integrity protection.
struct rind::cipher::Aes  -- An AES key that encrypts single blocks.
    function new(algorithm: &'static Algorithm, key: &[u8]) -> Result<Self, Error>  -- Expands `key` for `algorithm`, failing with [`Error::WrongLength`] if
    function encrypt_block(self: &Self, block: &mut [u8; 16])  -- Encrypts one block in place.
struct rind::cipher::AesCtr  -- An AES key for counter mode, with a counter width fixed when it is made.
    function new(algorithm: &'static Algorithm, key: &[u8], counter_bits: u8) -> Result<Self, Error>  -- Expands `key` for `algorithm`, counting over the rightmost
    function apply_keystream(self: &Self, counter_block: &[u8; 16], inout: &mut [u8]) -> Result<(), Error>  -- XORs the keystream from `counter_block` into `inout`.
    impls: Drop
struct rind::cipher::ChaCha20  -- A ChaCha20 key, for the bare stream cipher with a 96-bit nonce and a 32-bit block counter.
    function new(key: [u8; 32]) -> Self  -- Create a new [`ChaCha20`] from 32 bytes of key material.
    function apply_keystream(self: &Self, nonce: &[u8; 12], counter: u32, inout: &mut [u8]) -> Result<(), Error>  -- XORs the keystream for `nonce`, starting at block `counter`, into `inout`.
    impls: Drop
struct rind::cipher::Algorithm  -- An AES key size, which fixes the key length a key must have.
    impls: Debug
static rind::cipher::AES_128: Algorithm  -- AES with a 16-byte key.
static rind::cipher::AES_256: Algorithm  -- AES with a 32-byte key.
mod rind::key_wrap  -- Key wrapping with AES-KW, RFC 3394, as WebCrypto's `AES-KW` and JWE's
static rind::key_wrap::AES_128: Algorithm  -- AES with a 16-byte key.
static rind::key_wrap::AES_256: Algorithm  -- AES with a 32-byte key.
struct rind::key_wrap::AesKek  -- An AES key-encryption key, which wraps and unwraps other keys with RFC
    function new(algorithm: &'static Algorithm, key: &[u8]) -> Result<Self, Error>  -- Expands `key` for `algorithm`, failing with [`Error::WrongLength`] if
    function wrap(self: &Self, key: &[u8], wrapped: &mut [u8]) -> Result<(), Error>  -- Wraps `key` into `wrapped`, which must be 8 bytes longer.
    function unwrap(self: &Self, wrapped: &[u8], key: &mut [u8]) -> Result<(), Error>  -- Unwraps `wrapped` into `key`, which must be 8 bytes shorter.
    impls: Drop
mod rind::cpu  -- CPU support.
struct rind::cpu::MissingFeature  -- A CPU feature rind requires that this CPU lacks.
    impls: Clone, Copy, Debug, Display, Eq, Error, PartialEq, StructuralPartialEq
function rind::cpu::check() -> Result<(), MissingFeature>  -- Checks that this CPU has every feature rind requires, naming the first one missing.
function rind::cpu::has_aes_hardware() -> bool  -- Reports whether rind runs AES on CPU instructions, as aws-lc's `EVP_has_aes_hardware` does.
mod rind::rand  -- Random bytes from the system's secure random source.
function rind::rand::fill(out: &mut [u8]) -> Result<(), super::Error>  -- Fills the entirety of `out` with random bytes.
enum rind::Error  -- Why a rind call failed.
    variant WrongLength  -- An input or output of fixed length, such as a symmetric key, a nonce,
    variant KeyRejected  -- A private, public, or peer's key was refused, for any reason including
    variant BadSignature  -- A signature, MAC tag, or PBKDF2 output did not verify.
    variant DecryptFailed  -- An AEAD ciphertext, its tag, or its associated data did not
    variant RngFailed  -- The system random source failed.
    variant NotEqual  -- Values compared in constant time were not equal.
    variant Fault  -- An internal consistency check failed, from a hardware fault or a rind
    variant Unsupported  -- A call was given an algorithm it does not take, such as a SHA-1
    impls: Clone, Copy, Debug, Display, Eq, Error, PartialEq, StructuralPartialEq
struct rind::KeyRejected  -- Why a key was refused, which its `Display` describes.
    impls: Clone, Copy, Debug, Display, Eq, Error, PartialEq, StructuralPartialEq

(Written by Claude Opus 5.5)

@kixelated

Copy link
Copy Markdown
Collaborator Author

Audit inventory 2 of 2: the adapters, and the script

rind-ring is generated with --features std. ring 0.17.14's own inventory, used for the name-for-name diff, comes from the same script over ring's registry source, documented as a standalone crate.

rind-rustls
mod rind_rustls::cipher_suite  -- Every cipher suite this crate supports.
static rind_rustls::cipher_suite::TLS13_AES_256_GCM_SHA384: rustls::SupportedCipherSuite  -- The TLS1.3 `TLS_AES_256_GCM_SHA384` cipher suite.
static rind_rustls::cipher_suite::TLS13_AES_128_GCM_SHA256: rustls::SupportedCipherSuite  -- The TLS1.3 `TLS_AES_128_GCM_SHA256` cipher suite.
static rind_rustls::cipher_suite::TLS13_CHACHA20_POLY1305_SHA256: rustls::SupportedCipherSuite  -- The TLS1.3 `TLS_CHACHA20_POLY1305_SHA256` cipher suite.
static rind_rustls::cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: rustls::SupportedCipherSuite  -- The TLS1.2 `TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256` cipher suite.
static rind_rustls::cipher_suite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: rustls::SupportedCipherSuite  -- The TLS1.2 `TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256` cipher suite.
static rind_rustls::cipher_suite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: rustls::SupportedCipherSuite  -- The TLS1.2 `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256` cipher suite.
static rind_rustls::cipher_suite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: rustls::SupportedCipherSuite  -- The TLS1.2 `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384` cipher suite.
static rind_rustls::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: rustls::SupportedCipherSuite  -- The TLS1.2 `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256` cipher suite.
static rind_rustls::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: rustls::SupportedCipherSuite  -- The TLS1.2 `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` cipher suite.
mod rind_rustls::kx_group  -- Every key exchange group this crate supports.
static rind_rustls::kx_group::X25519: &dyn SupportedKxGroup  -- Key exchange with X25519.
static rind_rustls::kx_group::SECP256R1: &dyn SupportedKxGroup  -- Key exchange with ECDH on P-256, also known as secp256r1.
static rind_rustls::kx_group::SECP384R1: &dyn SupportedKxGroup  -- Key exchange with ECDH on P-384, also known as secp384r1.
static rind_rustls::kx_group::SECP521R1: &dyn SupportedKxGroup  -- Key exchange with ECDH on P-521, also known as secp521r1.
static rind_rustls::kx_group::X25519MLKEM768: &dyn SupportedKxGroup  -- Hybrid key exchange with X25519 and ML-KEM-768, for TLS 1.3 only.
static rind_rustls::kx_group::SECP256R1MLKEM768: &dyn SupportedKxGroup  -- Hybrid key exchange with ECDH on P-256 and ML-KEM-768, for TLS 1.3 only.
static rind_rustls::kx_group::MLKEM768: &dyn SupportedKxGroup  -- Key exchange with ML-KEM-768 alone, for TLS 1.3 only.
mod rind_rustls::sign  -- A key provider per signing key type this crate supports.
struct rind_rustls::sign::AnyOf  -- A key provider that loads a key with each of its key providers in turn.
    pub tuple field: &'static [&'static dyn KeyProvider]
    impls: Debug, KeyProvider
static rind_rustls::sign::ANY_SUPPORTED_TYPE: &dyn KeyProvider  -- Loads RSA, ECDSA, and Ed25519 keys, as [`default_provider`](crate::default_provider) does.
static rind_rustls::sign::RSA: &dyn KeyProvider  -- Loads RSA keys from PKCS#1 or PKCS#8.
static rind_rustls::sign::ECDSA_P256: &dyn KeyProvider  -- Loads ECDSA P-256 keys from PKCS#8 or SEC1.
static rind_rustls::sign::ECDSA_P384: &dyn KeyProvider  -- Loads ECDSA P-384 keys from PKCS#8 or SEC1.
static rind_rustls::sign::ECDSA_P521: &dyn KeyProvider  -- Loads ECDSA P-521 keys from PKCS#8 or SEC1.
static rind_rustls::sign::ED25519: &dyn KeyProvider  -- Loads Ed25519 keys from PKCS#8.
mod rind_rustls::verify  -- Every signature verification algorithm this crate supports.
static rind_rustls::verify::ECDSA_P256_SHA256: &dyn SignatureVerificationAlgorithm  -- Verifies ECDSA signatures by P-256 keys over SHA-256.
static rind_rustls::verify::ECDSA_P256_SHA384: &dyn SignatureVerificationAlgorithm  -- Verifies ECDSA signatures by P-256 keys over SHA-384.
static rind_rustls::verify::ECDSA_P256_SHA512: &dyn SignatureVerificationAlgorithm  -- Verifies ECDSA signatures by P-256 keys over SHA-512.
static rind_rustls::verify::ECDSA_P384_SHA256: &dyn SignatureVerificationAlgorithm  -- Verifies ECDSA signatures by P-384 keys over SHA-256.
static rind_rustls::verify::ECDSA_P384_SHA384: &dyn SignatureVerificationAlgorithm  -- Verifies ECDSA signatures by P-384 keys over SHA-384.
static rind_rustls::verify::ECDSA_P384_SHA512: &dyn SignatureVerificationAlgorithm  -- Verifies ECDSA signatures by P-384 keys over SHA-512.
static rind_rustls::verify::ECDSA_P521_SHA256: &dyn SignatureVerificationAlgorithm  -- Verifies ECDSA signatures by P-521 keys over SHA-256.
static rind_rustls::verify::ECDSA_P521_SHA384: &dyn SignatureVerificationAlgorithm  -- Verifies ECDSA signatures by P-521 keys over SHA-384.
static rind_rustls::verify::ECDSA_P521_SHA512: &dyn SignatureVerificationAlgorithm  -- Verifies ECDSA signatures by P-521 keys over SHA-512.
static rind_rustls::verify::ED25519: &dyn SignatureVerificationAlgorithm  -- Verifies Ed25519 signatures.
static rind_rustls::verify::RSA_PSS_SHA256: &dyn SignatureVerificationAlgorithm  -- Verifies RSASSA-PSS signatures over SHA-256 by 2048- to 8192-bit RSA keys.
static rind_rustls::verify::RSA_PSS_SHA384: &dyn SignatureVerificationAlgorithm  -- Verifies RSASSA-PSS signatures over SHA-384 by 2048- to 8192-bit RSA keys.
static rind_rustls::verify::RSA_PSS_SHA512: &dyn SignatureVerificationAlgorithm  -- Verifies RSASSA-PSS signatures over SHA-512 by 2048- to 8192-bit RSA keys.
static rind_rustls::verify::RSA_PKCS1_SHA256: &dyn SignatureVerificationAlgorithm  -- Verifies RSASSA-PKCS1-v1_5 signatures over SHA-256 by 2048- to 8192-bit RSA keys.
static rind_rustls::verify::RSA_PKCS1_SHA384: &dyn SignatureVerificationAlgorithm  -- Verifies RSASSA-PKCS1-v1_5 signatures over SHA-384 by 2048- to 8192-bit RSA keys.
static rind_rustls::verify::RSA_PKCS1_SHA512: &dyn SignatureVerificationAlgorithm  -- Verifies RSASSA-PKCS1-v1_5 signatures over SHA-512 by 2048- to 8192-bit RSA keys.
static rind_rustls::verify::RSA_PKCS1_SHA256_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm  -- [`RSA_PKCS1_SHA256`] for certificates that omit RFC 4055's NULL parameters, as webpki allows.
static rind_rustls::verify::RSA_PKCS1_SHA384_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm  -- [`RSA_PKCS1_SHA384`] for certificates that omit RFC 4055's NULL parameters, as webpki allows.
static rind_rustls::verify::RSA_PKCS1_SHA512_ABSENT_PARAMS: &dyn SignatureVerificationAlgorithm  -- [`RSA_PKCS1_SHA512`] for certificates that omit RFC 4055's NULL parameters, as webpki allows.
struct rind_rustls::Ticketer  -- The default ticketer.
    function new() -> Result<Arc<dyn ProducesTickets>, Error>  -- Make a new ticketer, or fail on a CPU missing a feature rind requires.
function rind_rustls::default_provider() -> Result<rustls::crypto::CryptoProvider, rind::cpu::MissingFeature>  -- Returns a rustls [`CryptoProvider`] using cryptography from rind, or the
function rind_rustls::empty_provider() -> Result<rustls::crypto::CryptoProvider, rind::cpu::MissingFeature>  -- Returns a rustls [`CryptoProvider`] with rind's random numbers and nothing
static rind_rustls::DEFAULT_CIPHER_SUITES: &[rustls::SupportedCipherSuite]  -- The cipher suites [`default_provider`] offers, in its order where rind runs
static rind_rustls::ALL_CIPHER_SUITES: &[rustls::SupportedCipherSuite]  -- Every cipher suite this crate supports, in preference order.
static rind_rustls::DEFAULT_KX_GROUPS: &[&dyn SupportedKxGroup]  -- The key exchange groups [`default_provider`] offers, in its order.
static rind_rustls::ALL_KX_GROUPS: &[&dyn SupportedKxGroup]  -- Every key exchange group this crate supports, in preference order.
static rind_rustls::SUPPORTED_SIG_ALGS: rustls::crypto::WebPkiSupportedAlgorithms  -- Every signature verification algorithm this crate supports, in the order
rind-rcgen
struct rind_rcgen::KeyPair  -- A key pair that signs rcgen certificates and requests with one algorithm.
    function generate(algorithm: &'static SignatureAlgorithm) -> Result<Self, Error>  -- Generates a random key pair that signs with `algorithm`: ECDSA P-256 or
    function from_pkcs8(algorithm: &'static SignatureAlgorithm, der: &PrivatePkcs8KeyDer<'_>) -> Result<Self, Error>  -- Loads a PKCS#8 private key that signs with `algorithm`: ECDSA P-256 or
    function to_pkcs8(self: &Self) -> Zeroizing<PrivatePkcs8KeyDer<'static>>  -- Encodes the private key as PKCS#8, which is wiped on drop.
    impls: Debug, PublicKeyData, SigningKey
rind-dimpl
function rind_dimpl::default_provider() -> Result<dimpl::crypto::CryptoProvider, rind::cpu::MissingFeature>  -- Returns a dimpl [`CryptoProvider`] backed by rind, or the CPU feature rind
rind-jsonwebtoken
static rind_jsonwebtoken::DEFAULT_PROVIDER: jsonwebtoken::crypto::CryptoProvider  -- A jsonwebtoken [`CryptoProvider`] that signs and verifies every algorithm with rind.
rind-object-store
function rind_object_store::default_provider() -> object_store::Result<std::sync::Arc<dyn CryptoProvider>, rind::cpu::MissingFeature>  -- Returns an object_store [`CryptoProvider`] backed by rind, or the CPU
rind-ring
mod rind_ring::aead  -- Authenticated encryption with associated data.
mod rind_ring::aead::quic  -- QUIC header protection (RFC 9001).
type_alias rind_ring::aead::quic::Sample  -- A header-protection sample.
struct rind_ring::aead::quic::Algorithm  -- A header-protection cipher, chosen by one of this module's statics.
    function key_len(self: &Self) -> usize  -- The length of a key, in bytes.
    function sample_len(self: &Self) -> usize  -- The length of a sample, in bytes.
    impls: Debug, Eq, KeyType, PartialEq
static rind_ring::aead::quic::AES_128: Algorithm  -- AES-128 header protection.
static rind_ring::aead::quic::AES_256: Algorithm  -- AES-256 header protection.
static rind_ring::aead::quic::CHACHA20: Algorithm  -- ChaCha20 header protection.
struct rind_ring::aead::quic::HeaderProtectionKey  -- A header-protection key; wiped on drop.
    function new(algorithm: &'static Algorithm, key_bytes: &[u8]) -> Result<Self, error::Unspecified>  -- Expands `key_bytes` for `algorithm`, failing unless it is [`Algorithm::key_len`] bytes.
    function new_mask(self: &Self, sample: &[u8]) -> Result<[u8; 5], error::Unspecified>  -- Returns the five-byte mask for `sample`, failing unless it is a sample's length.
    function algorithm(self: &Self) -> &'static Algorithm  -- The algorithm this key was made for.
    impls: From<Okm<'_, &'static Algorithm>>
struct rind_ring::aead::Algorithm  -- An AEAD algorithm, chosen by one of this module's statics.
    function key_len(self: &Self) -> usize  -- The length of a key, in bytes.
    function tag_len(self: &Self) -> usize  -- The length of a tag, in bytes.
    function nonce_len(self: &Self) -> usize  -- The length of a nonce, in bytes.
    impls: Debug, Eq, KeyType, PartialEq
static rind_ring::aead::AES_128_GCM: Algorithm  -- AES-128 in GCM mode.
static rind_ring::aead::AES_256_GCM: Algorithm  -- AES-256 in GCM mode.
static rind_ring::aead::CHACHA20_POLY1305: Algorithm  -- ChaCha20-Poly1305, from RFC 8439.
constant rind_ring::aead::NONCE_LEN: usize  -- The length of a nonce, in bytes, for every algorithm.
constant rind_ring::aead::MAX_TAG_LEN: usize  -- The longest tag of any algorithm, in bytes.
struct rind_ring::aead::Nonce  -- A nonce, which the caller promises seals only once under a key.
    function try_assume_unique_for_key(value: &[u8]) -> Result<Self, error::Unspecified>  -- Wraps `value`, failing unless it is [`NONCE_LEN`] bytes.
    function assume_unique_for_key(value: [u8; 12]) -> Self  -- Wraps `value`, which the caller promises is never reused with the same key.
    impls: AsRef<[u8; 12]>
trait rind_ring::aead::NonceSequence  -- A source of nonces for a [`SealingKey`] or [`OpeningKey`], each used once.
    trait-item function advance(self: &mut Self) -> Result<Nonce, error::Unspecified>  -- Returns the next nonce, or fails once the sequence is exhausted.
struct rind_ring::aead::Aad  -- Associated data, authenticated but not encrypted.
    function from(aad: A) -> Self  -- Wraps `aad`.
    function empty() -> Self  -- No associated data.
    impls: AsRef<[u8]>, Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq
struct rind_ring::aead::Tag  -- An authentication tag.
    impls: AsRef<[u8]>, Clone, Copy, From<[u8; 16]>, TryFrom<&[u8]>
struct rind_ring::aead::UnboundKey  -- A key not yet bound to a nonce sequence, for a [`SealingKey`], [`OpeningKey`], or [`LessSafeKey`].
    function new(algorithm: &'static Algorithm, key_bytes: &[u8]) -> Result<Self, error::Unspecified>  -- Expands `key_bytes` for `algorithm`, failing unless it is [`Algorithm::key_len`] bytes.
    function algorithm(self: &Self) -> &'static Algorithm  -- The algorithm this key was made for.
    impls: Debug, From<Okm<'_, &'static Algorithm>>
struct rind_ring::aead::LessSafeKey  -- A key that seals or opens with any nonce the caller gives it; wiped on drop.
    function new(key: UnboundKey) -> Self  -- Wraps `key`.
    function open_in_place_separate_tag(self: &Self, nonce: Nonce, aad: Aad<A>, tag: Tag, in_out: &'in_out mut [u8], ciphertext: RangeFrom<usize>) -> Result<&'in_out mut [u8], error::Unspecified>  -- Opens `in_out[ciphertext]` against the separate `tag`, and returns the
    function open_in_place(self: &Self, nonce: Nonce, aad: Aad<A>, in_out: &'in_out mut [u8]) -> Result<&'in_out mut [u8], error::Unspecified>  -- Opens `in_out`, the ciphertext followed by its tag, and returns the plaintext.
    function open_within(self: &Self, nonce: Nonce, aad: Aad<A>, in_out: &'in_out mut [u8], ciphertext_and_tag: RangeFrom<usize>) -> Result<&'in_out mut [u8], error::Unspecified>  -- Opens `in_out[ciphertext_and_tag]`, and returns the plaintext, moved to the front of `in_out`.
    function seal_in_place_append_tag(self: &Self, nonce: Nonce, aad: Aad<A>, in_out: &mut InOut) -> Result<(), error::Unspecified>  -- Seals `in_out` in place and appends the tag to it.
    function seal_in_place_separate_tag(self: &Self, nonce: Nonce, aad: Aad<A>, in_out: &mut [u8]) -> Result<Tag, error::Unspecified>  -- Seals `in_out` in place and returns the tag.
    function algorithm(self: &Self) -> &'static Algorithm  -- The algorithm this key was made for.
    impls: Clone, Debug
trait rind_ring::aead::BoundKey  -- A key bound to a [`NonceSequence`]: a [`SealingKey`] or [`OpeningKey`].
    trait-item function new(key: UnboundKey, nonce_sequence: N) -> Self  -- Binds `key` to `nonce_sequence`.
    trait-item function algorithm(self: &Self) -> &'static Algorithm  -- The algorithm this key was made for.
struct rind_ring::aead::SealingKey  -- A key that seals with each nonce its sequence gives.
    function seal_in_place_append_tag(self: &mut Self, aad: Aad<A>, in_out: &mut InOut) -> Result<(), error::Unspecified>  -- Seals `in_out` in place under the next nonce and appends the tag to it.
    function seal_in_place_separate_tag(self: &mut Self, aad: Aad<A>, in_out: &mut [u8]) -> Result<Tag, error::Unspecified>  -- Seals `in_out` in place under the next nonce and returns the tag.
    impls: BoundKey<N>, Debug
struct rind_ring::aead::OpeningKey  -- A key that opens with each nonce its sequence gives.
    function open_in_place(self: &mut Self, aad: Aad<A>, in_out: &'in_out mut [u8]) -> Result<&'in_out mut [u8], error::Unspecified>  -- Opens `in_out`, the ciphertext followed by its tag, under the next nonce.
    function open_within(self: &mut Self, aad: Aad<A>, in_out: &'in_out mut [u8], ciphertext_and_tag: RangeFrom<usize>) -> Result<&'in_out mut [u8], error::Unspecified>  -- Opens `in_out[ciphertext_and_tag]` under the next nonce, and returns
    impls: BoundKey<N>, Debug
mod rind_ring::agreement  -- Ephemeral key agreement: X25519, and ECDH on P-256 and P-384.
struct rind_ring::agreement::Algorithm  -- A key agreement algorithm, chosen by one of this module's statics.
    impls: Debug, Eq, PartialEq
static rind_ring::agreement::X25519: Algorithm  -- X25519 (RFC 7748).
static rind_ring::agreement::ECDH_P256: Algorithm  -- ECDH on P-256, with uncompressed public keys.
static rind_ring::agreement::ECDH_P384: Algorithm  -- ECDH on P-384, with uncompressed public keys.
struct rind_ring::agreement::EphemeralPrivateKey  -- A private key used for one key agreement; wiped on drop.
    function generate(alg: &'static Algorithm, rng: &dyn rand::SecureRandom) -> Result<Self, error::Unspecified>  -- Generates a private key for `alg` from the system random source.
    function compute_public_key(self: &Self) -> Result<PublicKey, error::Unspecified>  -- Returns the public key to send to the peer.
    function algorithm(self: &Self) -> &'static Algorithm  -- The algorithm this key was made for.
    impls: Debug
struct rind_ring::agreement::PublicKey  -- Our public key: 32 bytes for X25519, or an uncompressed point.
    function algorithm(self: &Self) -> &'static Algorithm  -- The algorithm this key was made for.
    impls: AsRef<[u8]>, Clone, Debug
struct rind_ring::agreement::UnparsedPublicKey  -- A peer's encoded public key, parsed only when [`agree_ephemeral`] uses it.
    function new(algorithm: &'static Algorithm, bytes: B) -> Self  -- Wraps the peer's encoded key for `algorithm`.
    function algorithm(self: &Self) -> &'static Algorithm  -- The algorithm the key is for.
    function bytes(self: &Self) -> &B  -- The encoded key.
    impls: AsRef<[u8]>, Clone, Copy, Debug
function rind_ring::agreement::agree_ephemeral(my_private_key: EphemeralPrivateKey, peer_public_key: &UnparsedPublicKey<B>, kdf: impl FnOnce) -> Result<R, error::Unspecified>  -- Agrees on a secret with the peer's public key, consuming `my_private_key`, and returns `kdf` of it.
mod rind_ring::digest  -- Cryptographic hash functions.
struct rind_ring::digest::Algorithm  -- A hash function, chosen by one of this module's statics.
    function block_len(self: &Self) -> usize  -- The length of a block the hash compresses at a time, in bytes.
    function chaining_len(self: &Self) -> usize  -- The length of the hash's internal state, in bytes.
    function output_len(self: &Self) -> usize  -- The length of a digest, in bytes.
    impls: Debug, Eq, PartialEq
static rind_ring::digest::SHA1_FOR_LEGACY_USE_ONLY: Algorithm  -- SHA-1, for legacy protocols only: its collision resistance is broken.
static rind_ring::digest::SHA256: Algorithm  -- SHA-256.
static rind_ring::digest::SHA384: Algorithm  -- SHA-384.
static rind_ring::digest::SHA512: Algorithm  -- SHA-512.
static rind_ring::digest::SHA512_256: Algorithm  -- SHA-512/256.
constant rind_ring::digest::MAX_BLOCK_LEN: usize  -- The largest block length of any algorithm, in bytes.
constant rind_ring::digest::MAX_OUTPUT_LEN: usize  -- The largest digest length of any algorithm, in bytes.
constant rind_ring::digest::MAX_CHAINING_LEN: usize  -- The largest internal state of any algorithm, in bytes.
constant rind_ring::digest::SHA1_OUTPUT_LEN: usize  -- The length of a SHA-1 digest, in bytes.
constant rind_ring::digest::SHA256_OUTPUT_LEN: usize  -- The length of a SHA-256 digest, in bytes.
constant rind_ring::digest::SHA384_OUTPUT_LEN: usize  -- The length of a SHA-384 digest, in bytes.
constant rind_ring::digest::SHA512_OUTPUT_LEN: usize  -- The length of a SHA-512 digest, in bytes.
constant rind_ring::digest::SHA512_256_OUTPUT_LEN: usize  -- The length of a SHA-512/256 digest, in bytes.
function rind_ring::digest::digest(algorithm: &'static Algorithm, data: &[u8]) -> Digest  -- Hashes `data` in one go.
struct rind_ring::digest::Context  -- An in-progress hash computation; a clone forks it.
    function new(algorithm: &'static Algorithm) -> Self  -- Starts hashing with `algorithm`.
    function update(self: &mut Self, data: &[u8])  -- Adds `data` to the message.
    function finish(self: Self) -> Digest  -- Returns the digest of the message.
    function algorithm(self: &Self) -> &'static Algorithm  -- The algorithm this context hashes with.
    impls: Clone
struct rind_ring::digest::Digest  -- The output of a hash function.
    function algorithm(self: &Self) -> &'static Algorithm  -- The algorithm that made this digest.
    impls: AsRef<[u8]>, Clone, Copy, Debug
mod rind_ring::error  -- Error reporting.
struct rind_ring::error::Unspecified  -- An error with no details, as ring returns from most calls.
    impls: Clone, Copy, Debug, Display, Eq, Error, From<EndOfInput>, From<KeyRejected>, From<TryFromSliceError>, PartialEq, StructuralPartialEq
struct rind_ring::error::KeyRejected  -- A key was refused; its `Display` says why, in words that may change between releases.
    impls: Clone, Copy, Debug, Display, Error, From<KeyRejected>
mod rind_ring::hkdf  -- Key derivation with HKDF (RFC 5869), over any [`hmac`] algorithm.
struct rind_ring::hkdf::Algorithm  -- An HKDF algorithm, chosen by one of this module's statics.
    function hmac_algorithm(self: &Self) -> hmac::Algorithm  -- The HMAC algorithm this HKDF is built on.
    impls: Clone, Copy, Debug, Eq, KeyType, PartialEq, StructuralPartialEq
static rind_ring::hkdf::HKDF_SHA1_FOR_LEGACY_USE_ONLY: Algorithm  -- HKDF-SHA1, for legacy protocols only.
static rind_ring::hkdf::HKDF_SHA256: Algorithm  -- HKDF-SHA256.
static rind_ring::hkdf::HKDF_SHA384: Algorithm  -- HKDF-SHA384.
static rind_ring::hkdf::HKDF_SHA512: Algorithm  -- HKDF-SHA512.
struct rind_ring::hkdf::Salt  -- A salt, keyed once and reused for every secret it extracts from.
    function new(algorithm: Algorithm, value: &[u8]) -> Self  -- Keys `algorithm` with `value`; an empty `value` is RFC 5869's absent salt.
    function extract(self: &Self, secret: &[u8]) -> Prk  -- Extracts a pseudorandom key from `secret` (HKDF-Extract).
    function algorithm(self: &Self) -> Algorithm  -- The algorithm this salt was made for.
    impls: Debug, From<Okm<'_, Algorithm>>
trait rind_ring::hkdf::KeyType  -- The length of what an [`Okm`] becomes.
    trait-item function len(self: &Self) -> usize  -- The length, in bytes.
struct rind_ring::hkdf::Prk  -- A pseudorandom key, from which [`Prk::expand`] derives any number of keys.
    function new_less_safe(algorithm: Algorithm, value: &[u8]) -> Self  -- Takes `value` as the pseudorandom key itself, skipping HKDF-Extract.
    function expand(self: &'a Self, info: &'a [&'a [u8]], len: L) -> Result<Okm<'a, L>, error::Unspecified>  -- Derives key material for the concatenation of `info` (HKDF-Expand),
    impls: Clone, Debug, From<Okm<'_, Algorithm>>
struct rind_ring::hkdf::Okm  -- Key material from [`Prk::expand`], as long as `L` says, for [`Okm::fill`] or a key's `From`.
    function len(self: &Self) -> &L  -- What this key material becomes.
    function fill(self: Self, out: &mut [u8]) -> Result<(), error::Unspecified>  -- Fills `out`, failing unless it is exactly the length `L` says.
    impls: Debug, From<Okm<'_, &'static Algorithm>>, From<Okm<'_, &'static Algorithm>>, From<Okm<'_, Algorithm>>, From<Okm<'_, Algorithm>>, From<Okm<'_, Algorithm>>
mod rind_ring::hmac  -- Message authentication with HMAC.
struct rind_ring::hmac::Algorithm  -- An HMAC algorithm, chosen by one of this module's statics.
    function digest_algorithm(self: &Self) -> &'static digest::Algorithm  -- The hash function this HMAC is built on.
    impls: Clone, Copy, Debug, Eq, KeyType, PartialEq
static rind_ring::hmac::HMAC_SHA1_FOR_LEGACY_USE_ONLY: Algorithm  -- HMAC-SHA1, for legacy protocols only.
static rind_ring::hmac::HMAC_SHA256: Algorithm  -- HMAC-SHA256.
static rind_ring::hmac::HMAC_SHA384: Algorithm  -- HMAC-SHA384.
static rind_ring::hmac::HMAC_SHA512: Algorithm  -- HMAC-SHA512.
struct rind_ring::hmac::Key  -- An HMAC key, keyed once and reused for every message; wiped on drop.
    function generate(algorithm: Algorithm, rng: &dyn rand::SecureRandom) -> Result<Self, error::Unspecified>  -- Generates a key as long as the hash's output from `rng`.
    function new(algorithm: Algorithm, key_value: &[u8]) -> Self  -- Keys `algorithm` with `key_value`, which may be any length.
    function algorithm(self: &Self) -> Algorithm  -- The algorithm this key was made for.
    impls: Clone, Debug, From<Okm<'_, Algorithm>>
struct rind_ring::hmac::Context  -- An in-progress tag computation; a clone forks it.
    function with_key(signing_key: &Key) -> Self  -- Starts a tag computation under `signing_key`.
    function update(self: &mut Self, data: &[u8])  -- Adds `data` to the message.
    function sign(self: Self) -> Tag  -- Returns the tag of the message.
    impls: Clone, Debug
function rind_ring::hmac::sign(key: &Key, data: &[u8]) -> Tag  -- Returns the tag of `data` under `key`.
function rind_ring::hmac::verify(key: &Key, data: &[u8], tag: &[u8]) -> Result<(), error::Unspecified>  -- Checks in constant time that `tag` is the whole tag of `data` under `key`.
struct rind_ring::hmac::Tag  -- An HMAC tag.
    impls: AsRef<[u8]>, Clone, Copy, Debug
mod rind_ring::pbkdf2  -- Password-based key derivation with PBKDF2 (RFC 8018).
struct rind_ring::pbkdf2::Algorithm  -- A PBKDF2 algorithm, chosen by one of this module's statics.
    impls: Clone, Copy, Eq, PartialEq
static rind_ring::pbkdf2::PBKDF2_HMAC_SHA1: Algorithm  -- PBKDF2 with HMAC-SHA1.
static rind_ring::pbkdf2::PBKDF2_HMAC_SHA256: Algorithm  -- PBKDF2 with HMAC-SHA256.
static rind_ring::pbkdf2::PBKDF2_HMAC_SHA384: Algorithm  -- PBKDF2 with HMAC-SHA384.
static rind_ring::pbkdf2::PBKDF2_HMAC_SHA512: Algorithm  -- PBKDF2 with HMAC-SHA512.
function rind_ring::pbkdf2::derive(algorithm: Algorithm, iterations: core::num::NonZeroU32, salt: &[u8], secret: &[u8], out: &mut [u8])  -- Fills `out` with the key derived from `secret` and `salt` over `iterations` rounds.
function rind_ring::pbkdf2::verify(algorithm: Algorithm, iterations: core::num::NonZeroU32, salt: &[u8], secret: &[u8], previously_derived: &[u8]) -> Result<(), error::Unspecified>  -- Checks in constant time that `previously_derived` is what [`derive`] makes for the same inputs.
mod rind_ring::pkcs8  -- PKCS#8 private key documents.
struct rind_ring::pkcs8::Document  -- A PKCS#8 private key document, wiped on drop.
    impls: AsRef<[u8]>
mod rind_ring::rand  -- Random bytes from the system's secure random source.
trait rind_ring::rand::SecureRandom  -- A secure source of random bytes; only [`SystemRandom`] is one.
    trait-item function fill(self: &Self, dest: &mut [u8]) -> Result<(), error::Unspecified>  -- Fills `dest` with random bytes.
trait rind_ring::rand::RandomlyConstructable  -- A type [`generate`] can fill with random bytes: a byte array.
struct rind_ring::rand::Random  -- A randomly generated value, taken out with [`Random::expose`].
    function expose(self: Self) -> T  -- Returns the random value.
function rind_ring::rand::generate(rng: &dyn SecureRandom) -> Result<Random<T>, error::Unspecified>  -- Generates a random `T` from `rng`.
struct rind_ring::rand::SystemRandom  -- The operating system's secure random source.
    function new() -> Self  -- Returns the system random source.
    impls: Clone, Debug
mod rind_ring::rsa  -- RSA key pairs and public keys.
struct rind_ring::rsa::KeyPair  -- Signs with any [`signature::RsaEncoding`]; its modulus is 2048 to 4096 bits, a multiple of 512, as ring requires.
    function from_pkcs8(pkcs8: &[u8]) -> Result<Self, error::KeyRejected>  -- Loads a PKCS#8 `rsaEncryption` private key.
    function from_der(input: &[u8]) -> Result<Self, error::KeyRejected>  -- Loads a PKCS#1 `RSAPrivateKey`.
    function public(self: &Self) -> &PublicKey  -- The public key.
    function public_modulus_len(self: &Self) -> usize  -- The length of the modulus, and of every signature, in bytes.
    function sign(self: &Self, padding_alg: &'static dyn signature::RsaEncoding, rng: &dyn rand::SecureRandom, msg: &[u8], signature: &mut [u8]) -> Result<(), error::Unspecified>  -- Signs `msg` with `padding_alg` into `signature`, which must be [`Self::public_modulus_len`] bytes.
    impls: Debug, KeyPair
struct rind_ring::rsa::PublicKey  -- An RSA public key, whose bytes are its PKCS#1 `RSAPublicKey` DER.
    function modulus_len(self: &Self) -> usize  -- The length of the modulus, in bytes.
    impls: AsRef<[u8]>, Clone, Debug, From<&PublicKey>
struct rind_ring::rsa::PublicKeyComponents  -- An RSA public key as its big-endian modulus and exponent, without leading zero bytes.
    field n: B  -- The modulus.
    field e: B  -- The public exponent.
    function verify(self: &Self, params: &RsaParameters, message: &[u8], signature: &[u8]) -> Result<(), error::Unspecified>  -- Verifies `signature` over `message` with this key and `params`.
    impls: Clone, Copy, Debug, From<&PublicKey>
struct rind_ring::rsa::RsaParameters  -- An RSA verification algorithm: a padding, a hash, and the smallest modulus it accepts, up to 8192 bits.
    impls: Debug, VerificationAlgorithm
mod rind_ring::signature  -- Public key signatures: ECDSA on P-256 and P-384, RSA, and Ed25519.
struct rind_ring::signature::RsaPublicKeyComponents  -- An RSA public key as its big-endian modulus and exponent, without leading zero bytes.
    (see above)
struct rind_ring::signature::RsaParameters  -- An RSA verification algorithm: a padding, a hash, and the smallest modulus it accepts, up to 8192 bits.
    (see above)
static rind_ring::signature::RSA_PKCS1_SHA256: Padding  -- PKCS#1 v1.5 signatures with SHA-256.
static rind_ring::signature::RSA_PKCS1_SHA384: Padding  -- PKCS#1 v1.5 signatures with SHA-384.
static rind_ring::signature::RSA_PKCS1_SHA512: Padding  -- PKCS#1 v1.5 signatures with SHA-512.
static rind_ring::signature::RSA_PSS_SHA256: Padding  -- PSS signatures with SHA-256, MGF1, and a 32-byte random salt.
static rind_ring::signature::RSA_PSS_SHA384: Padding  -- PSS signatures with SHA-384, MGF1, and a 48-byte random salt.
static rind_ring::signature::RSA_PSS_SHA512: Padding  -- PSS signatures with SHA-512, MGF1, and a 64-byte random salt.
trait rind_ring::signature::RsaEncoding  -- An RSA signature encoding, a padding and a hash, for [`super::KeyPair::sign`].
static rind_ring::signature::RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY: RsaParameters  -- PKCS#1 v1.5 with SHA-1 and a modulus of 1024 to 8192 bits, for legacy protocols only.
static rind_ring::signature::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY: RsaParameters  -- PKCS#1 v1.5 with SHA-256 and a modulus of 1024 to 8192 bits, for legacy protocols only.
static rind_ring::signature::RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY: RsaParameters  -- PKCS#1 v1.5 with SHA-512 and a modulus of 1024 to 8192 bits, for legacy protocols only.
static rind_ring::signature::RSA_PKCS1_2048_8192_SHA1_FOR_LEGACY_USE_ONLY: RsaParameters  -- PKCS#1 v1.5 with SHA-1 and a modulus of 2048 to 8192 bits, for legacy protocols only.
static rind_ring::signature::RSA_PKCS1_2048_8192_SHA256: RsaParameters  -- PKCS#1 v1.5 with SHA-256 and a modulus of 2048 to 8192 bits.
static rind_ring::signature::RSA_PKCS1_2048_8192_SHA384: RsaParameters  -- PKCS#1 v1.5 with SHA-384 and a modulus of 2048 to 8192 bits.
static rind_ring::signature::RSA_PKCS1_2048_8192_SHA512: RsaParameters  -- PKCS#1 v1.5 with SHA-512 and a modulus of 2048 to 8192 bits.
static rind_ring::signature::RSA_PKCS1_3072_8192_SHA384: RsaParameters  -- PKCS#1 v1.5 with SHA-384 and a modulus of 3072 to 8192 bits.
static rind_ring::signature::RSA_PSS_2048_8192_SHA256: RsaParameters  -- PSS with SHA-256, MGF1, a 32-byte salt, and a modulus of 2048 to 8192 bits.
static rind_ring::signature::RSA_PSS_2048_8192_SHA384: RsaParameters  -- PSS with SHA-384, MGF1, a 48-byte salt, and a modulus of 2048 to 8192 bits.
static rind_ring::signature::RSA_PSS_2048_8192_SHA512: RsaParameters  -- PSS with SHA-512, MGF1, a 64-byte salt, and a modulus of 2048 to 8192 bits.
type_alias rind_ring::signature::RsaKeyPair  -- An RSA key pair, for signing.
struct rind_ring::signature::Signature  -- A signature from an ECDSA or Ed25519 key pair.
    impls: AsRef<[u8]>, Clone, Copy
trait rind_ring::signature::KeyPair  -- A key pair, whose public key verifies what it signs.
    trait-item assoc_type PublicKey  -- The public key's type.
    trait-item function public_key(self: &Self) -> &<..>::PublicKey  -- Returns the public key.
trait rind_ring::signature::VerificationAlgorithm  -- A signature verification algorithm.
    trait-item function verify(self: &Self, public_key: untrusted::Input<'_>, msg: untrusted::Input<'_>, signature: untrusted::Input<'_>) -> Result<(), error::Unspecified>  -- Verifies `signature` over `msg` with the encoded `public_key`.
struct rind_ring::signature::UnparsedPublicKey  -- A peer's encoded public key, parsed only when it verifies.
    function new(algorithm: &'static dyn VerificationAlgorithm, bytes: B) -> Self  -- Wraps the encoded key for `algorithm`.
    function verify(self: &Self, message: &[u8], signature: &[u8]) -> Result<(), error::Unspecified>  -- Verifies `signature` over `message`, failing for a malformed key or signature.
    impls: AsRef<[u8]>, Clone, Copy, Debug
struct rind_ring::signature::EcdsaVerificationAlgorithm  -- An ECDSA verification algorithm: a curve, a hash, and a signature encoding.
    impls: Debug, VerificationAlgorithm
static rind_ring::signature::ECDSA_P256_SHA256_ASN1: EcdsaVerificationAlgorithm  -- ECDSA on P-256 with SHA-256, ASN.1 DER signatures.
static rind_ring::signature::ECDSA_P256_SHA256_FIXED: EcdsaVerificationAlgorithm  -- ECDSA on P-256 with SHA-256, `r || s` signatures.
static rind_ring::signature::ECDSA_P256_SHA384_ASN1: EcdsaVerificationAlgorithm  -- ECDSA on P-256 with SHA-384, ASN.1 DER signatures.
static rind_ring::signature::ECDSA_P384_SHA256_ASN1: EcdsaVerificationAlgorithm  -- ECDSA on P-384 with SHA-256, ASN.1 DER signatures.
static rind_ring::signature::ECDSA_P384_SHA384_ASN1: EcdsaVerificationAlgorithm  -- ECDSA on P-384 with SHA-384, ASN.1 DER signatures.
static rind_ring::signature::ECDSA_P384_SHA384_FIXED: EcdsaVerificationAlgorithm  -- ECDSA on P-384 with SHA-384, `r || s` signatures.
struct rind_ring::signature::EcdsaSigningAlgorithm  -- An ECDSA signing algorithm, which an [`EcdsaKeyPair`] is bound to.
    impls: Debug, Eq, PartialEq
static rind_ring::signature::ECDSA_P256_SHA256_ASN1_SIGNING: EcdsaSigningAlgorithm  -- ECDSA on P-256 with SHA-256, ASN.1 DER signatures.
static rind_ring::signature::ECDSA_P256_SHA256_FIXED_SIGNING: EcdsaSigningAlgorithm  -- ECDSA on P-256 with SHA-256, `r || s` signatures.
static rind_ring::signature::ECDSA_P384_SHA384_ASN1_SIGNING: EcdsaSigningAlgorithm  -- ECDSA on P-384 with SHA-384, ASN.1 DER signatures.
static rind_ring::signature::ECDSA_P384_SHA384_FIXED_SIGNING: EcdsaSigningAlgorithm  -- ECDSA on P-384 with SHA-384, `r || s` signatures.
struct rind_ring::signature::EcdsaKeyPair  -- An ECDSA private key and its public key, bound to one signing algorithm.
    function generate_pkcs8(alg: &'static EcdsaSigningAlgorithm, rng: &dyn rand::SecureRandom) -> Result<pkcs8::Document, error::Unspecified>  -- Generates a key pair for `alg` and returns it as PKCS#8.
    function from_pkcs8(alg: &'static EcdsaSigningAlgorithm, pkcs8: &[u8], rng: &dyn rand::SecureRandom) -> Result<Self, error::KeyRejected>  -- Loads a PKCS#8 `ECPrivateKey` on `alg`'s curve, refused unless it
    function from_private_key_and_public_key(alg: &'static EcdsaSigningAlgorithm, private_key: &[u8], public_key: &[u8], rng: &dyn rand::SecureRandom) -> Result<Self, error::KeyRejected>  -- Loads a big-endian private scalar, refused unless `public_key`, an
    function sign(self: &Self, rng: &dyn rand::SecureRandom, message: &[u8]) -> Result<Signature, error::Unspecified>  -- Signs `message` with a fresh random nonce.
    impls: Debug, KeyPair
struct rind_ring::signature::EdDSAParameters  -- Ed25519 verification.
    impls: Debug, VerificationAlgorithm
static rind_ring::signature::ED25519: EdDSAParameters  -- Ed25519 verification, with 32-byte public keys.
constant rind_ring::signature::ED25519_PUBLIC_KEY_LEN: usize  -- The length of an Ed25519 public key, in bytes.
struct rind_ring::signature::Ed25519KeyPair  -- An Ed25519 private key and its public key.
    function generate_pkcs8(rng: &dyn rand::SecureRandom) -> Result<pkcs8::Document, error::Unspecified>  -- Generates a key pair and returns it as PKCS#8 v2, with its public key.
    function from_pkcs8(pkcs8: &[u8]) -> Result<Self, error::KeyRejected>  -- Loads a PKCS#8 v2 key, refused unless its public key matches.
    function from_pkcs8_maybe_unchecked(pkcs8: &[u8]) -> Result<Self, error::KeyRejected>  -- Loads a PKCS#8 v1 key, or a v2 key, refused unless its public key matches.
    function from_seed_and_public_key(seed: &[u8], public_key: &[u8]) -> Result<Self, error::KeyRejected>  -- Loads a 32-byte seed, refused unless `public_key` is its public key.
    function from_seed_unchecked(seed: &[u8]) -> Result<Self, error::KeyRejected>  -- Loads a 32-byte seed, computing its public key.
    function sign(self: &Self, msg: &[u8]) -> Signature  -- Signs `msg`.
    impls: Debug, KeyPair
rind_ring::cpu  [external re-export of rind::cpu]
inventory.py
import json, sys

def first_line(docs):
    if not docs:
        return "<NO DOC>"
    for l in docs.strip().splitlines():
        l = l.strip()
        if l:
            return l
    return "<NO DOC>"

def fn_sig(it, idx):
    f = it["inner"]["function"]
    s = f["sig"]
    args = []
    for name, ty in s["inputs"]:
        args.append(name + ": " + ty_str(ty))
    out = ""
    if s.get("output") is not None:
        out = " -> " + ty_str(s["output"])
    return "(" + ", ".join(args) + ")" + out

def ty_str(t):
    if t is None: return "()"
    if isinstance(t, str): return t
    k, v = next(iter(t.items()))
    if k == "primitive": return v
    if k == "generic": return v
    if k == "resolved_path":
        name = v["path"]
        args = v.get("args")
        a = ""
        if args and "angle_bracketed" in args:
            parts = []
            for x in args["angle_bracketed"]["args"]:
                if "type" in x: parts.append(ty_str(x["type"]))
                elif "lifetime" in x: parts.append(x["lifetime"])
                elif "const" in x: parts.append(str(x["const"].get("expr")))
            if parts: a = "<" + ", ".join(parts) + ">"
        return name + a
    if k == "borrowed_ref":
        return "&" + (v.get("lifetime") + " " if v.get("lifetime") else "") + ("mut " if v["is_mutable"] else "") + ty_str(v["type"])
    if k == "slice": return "[" + ty_str(v) + "]"
    if k == "array": return "[" + ty_str(v["type"]) + "; " + v["len"] + "]"
    if k == "tuple": return "(" + ", ".join(ty_str(x) for x in v) + ")"
    if k == "impl_trait":
        return "impl " + " + ".join(b.get("trait_bound", {}).get("trait", {}).get("path", "?") for b in v)
    if k == "qualified_path": return "<..>::" + v["name"]
    if k == "dyn_trait": return "dyn " + " + ".join(x["trait"]["path"] for x in v["traits"])
    if k == "raw_pointer": return "*" + ("mut " if v["is_mutable"] else "const ") + ty_str(v["type"])
    if k == "function_pointer": return "fn(..)"
    return k

def main(path, crate):
    d = json.load(open(path))
    idx = d["index"]
    root = d["root"]
    seen = set()
    out = []
    def item_of(id_):
        return idx.get(str(id_))
    def walk(mid, prefix):
        m = item_of(mid)
        for cid in m["inner"]["module"]["items"]:
            it = item_of(cid)
            if it is None: continue
            emit(it, prefix)
    def emit(it, prefix, alias=None):
        inner = it["inner"]
        kind = next(iter(inner))
        if kind == "use":
            u = inner["use"]
            target = item_of(u["id"]) if u.get("id") is not None else None
            if target is None:
                out.append(f"{prefix}::{u['name']}  [external re-export of {u['source']}]")
                return
            if u["is_glob"]:
                if "module" in target["inner"]:
                    walk(target["id"], prefix)
                return
            emit(target, prefix, alias=u["name"])
            return
        name = alias or it["name"]
        if it.get("visibility") != "public" and kind != "use":
            return
        if kind == "impl":
            return
        p = f"{prefix}::{name}"
        doc = first_line(it.get("docs"))
        if kind == "module":
            out.append(f"mod {p}  -- {doc}")
            walk(it["id"], p)
            return
        sig = ""
        if kind == "function":
            sig = fn_sig(it, idx)
        if kind == "constant" or kind == "static":
            t = inner[kind].get("type")
            sig = ": " + ty_str(t)
        out.append(f"{kind} {p}{sig}  -- {doc}")
        if kind in ("struct", "enum", "union", "trait"):
            key = (it["id"])
            if key in seen:
                out.append(f"    (see above)")
                return
            seen.add(key)
            if kind == "enum":
                for vid in inner["enum"]["variants"]:
                    v = item_of(vid)
                    out.append(f"    variant {v['name']}  -- {first_line(v.get('docs'))}")
            if kind == "struct":
                sk = inner["struct"]["kind"]
                if isinstance(sk, dict) and "plain" in sk:
                    for fid in sk["plain"]["fields"]:
                        f = item_of(fid)
                        if f and f.get("visibility") == "public":
                            out.append(f"    field {f['name']}: {ty_str(f['inner']['struct_field'])}  -- {first_line(f.get('docs'))}")
                elif isinstance(sk, dict) and "tuple" in sk:
                    for fid in sk["tuple"]:
                        if fid is None: continue
                        f = item_of(fid)
                        if f and f.get("visibility") == "public":
                            out.append(f"    pub tuple field: {ty_str(f['inner']['struct_field'])}")
            if kind == "trait":
                for mid_ in inner["trait"]["items"]:
                    m = item_of(mid_)
                    mk = next(iter(m["inner"]))
                    s = fn_sig(m, idx) if mk == "function" else ""
                    out.append(f"    trait-item {mk} {m['name']}{s}  -- {first_line(m.get('docs'))}")
            impls = inner[kind].get("impls", []) if kind != "trait" else []
            traits = []
            for iid in impls:
                im = item_of(iid)
                if im is None: continue
                ii = im["inner"]["impl"]
                if ii.get("is_synthetic") or ii.get("blanket_impl"):
                    continue
                if ii["trait"] is None:
                    for mid_ in ii["items"]:
                        m = item_of(mid_)
                        if m.get("visibility") != "public": continue
                        mk = next(iter(m["inner"]))
                        s = fn_sig(m, idx) if mk == "function" else (": " + ty_str(m["inner"][mk].get("type")) if mk == "constant" else "")
                        out.append(f"    {mk} {m['name']}{s}  -- {first_line(m.get('docs'))}")
                else:
                    tn = ty_str({"resolved_path": ii["trait"]})
                    traits.append(tn)
            if traits:
                out.append("    impls: " + ", ".join(sorted(traits)))
    walk(root, crate)
    print("\n".join(out))

main(sys.argv[1], sys.argv[2])

(Written by Claude Opus 5.5)

@kixelated

Copy link
Copy Markdown
Collaborator Author

The maintainer picked the decisions on 2026-11-05:

  • ✅ D1: a new rind::encoding module holds Pkcs8 and Spki (not the crate root this PR recommended).
  • ✅ D2: rsa::KeySize and rsa::PublicKeyComponents.
  • ✅ D3: signature::PublicKey::from_components(&alg, &c), dropping to_public_key.
  • ✅ D4: the loaders become from_scalar (agreement) and from_scalar_and_public_key (ECDSA).
  • ✅ D5: a Debug that shows the algorithm only, never key bytes, on the 16 types.
  • ✅ D6: kem::DecapsulationKey::decapsulate(&self).
  • ✅ D7: aead::gcm::Iv.
  • ✅ D9: cipher::ChaCha20::new(&[u8; 32]).
  • ✅ D8, D10, D11, D12: kept as they are.

All of them land in this PR.

(Written by Claude Opus 5.5)

kixelated and others added 2 commits November 5, 2026 14:01
The maintainer's picks on the audit (#383):

- `signature::{Pkcs8, Spki}` move to a new `encoding` module.
- `signature::RsaKeySize` is `rsa::KeySize`, and
  `signature::RsaPublicKeyComponents` is `rsa::PublicKeyComponents`.
- `components.to_public_key(alg)` is `PublicKey::from_components(alg, &components)`.
- `agreement::PrivateKey::from_private_key` is `from_scalar`, and
  `EcdsaKeyPair::from_private_key_and_public_key` is
  `from_scalar_and_public_key`.
- The 16 symmetric key and keyed-state types gain a `Debug` that shows
  the algorithm only.
- `kem::DecapsulationKey::decapsulate` borrows the key.
- `aead::gcm::Key` takes a `gcm::Iv`, which refuses an empty IV and is not
  `Clone`.
- `cipher::ChaCha20::new` takes `&[u8; 32]`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated and others added 2 commits November 5, 2026 16:51
# Conflicts:
#	proofs/Rind/Aarch64/P256Signature.lean
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title docs: audit rind's public API before 0.2.0 feat!: audit rind's public API, and apply its decisions, before 0.2.0 Nov 6, 2026
@kixelated
kixelated marked this pull request as ready for review November 6, 2026 00:58
@pullfrog

pullfrog Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Your OpenCode Go account is out of credit. Top it up, then re-trigger Pullfrog.

OpenCode Go's response
provider error: Upstream request failed: Insufficient account funds

Top up OpenCode Go →

Pullfrog  | Rerun failed job ➔ | View workflow run | via Pullfrog | Using glm-5.3

@coderabbitai

coderabbitai Bot commented Nov 6, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 59 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 19adaa89-6366-4afd-8200-4695b3f3c9e8
Commits

Reviewing files that changed from the base of the PR and between 0ad76c6 and b2981a8.

Files selected for processing: 58

  • MIGRATING.md
  • README.md
  • fuzz/fuzzer/keys.rs
  • fuzz/fuzzer/kx.rs
  • proofs/README.md
  • proofs/Rind/Aarch64/Axioms.lean
  • proofs/Rind/Aarch64/EcdsaDispatch.lean
  • proofs/Rind/Aarch64/P256.lean
  • proofs/Rind/Aarch64/P256Signature.lean
  • proofs/Rind/X86_64/Axioms.lean
  • proofs/Rind/X86_64/Dispatch.lean
  • proofs/Rind/X86_64/SignatureDispatch.lean
  • proofs/Rind/X86_64/X25519.lean
  • quest/m1/README.md
  • quest/m1/api-audit.md
  • quest/m1/release-0.2.md
  • rind-bench/benches/mlkem768.rs
  • rind-bench/benches/p256.rs
  • rind-bench/benches/p384.rs
  • rind-bench/benches/p521.rs
  • rind-bench/benches/rsa_gen.rs
  • rind-bench/benches/x25519.rs
  • rind-jsonwebtoken/src/lib.rs
  • rind-ring/src/pkcs8.rs
  • rind-ring/src/rsa.rs
  • rind-ring/src/signature.rs
  • rind-rustls/src/ticketer.rs
  • rind/src/aead.rs
  • rind/src/aead/gcm.rs
  • rind/src/aead/quic.rs
  • rind/src/cipher.rs
  • rind/src/high/agreement.rs
  • rind/src/high/digest.rs
  • rind/src/high/hkdf.rs
  • rind/src/high/hmac.rs
  • rind/src/high/kem.rs
  • rind/src/high/oaep.rs
  • rind/src/high/pbkdf2.rs
  • rind/src/high/signature.rs
  • rind/src/lib.rs
  • rind/src/low/aarch64/aes.rs
  • rind/src/low/aarch64/vpaes_armv8.rs
  • rind/src/low/arm/aes.rs
  • rind/src/low/arm/aesv8_armx.rs
  • rind/src/low/x86_64/aes.rs
  • rind/src/low/x86_64/aes_nohw.rs
  • rind/src/low/x86_64/vpaes_x86_64.rs
  • rind/src/mid/aes.rs
  • rind/src/mid/aes_cbc.rs
  • rind/src/mid/aes_gcm.rs
  • rind/src/mid/aes_kw.rs
  • rind/src/mid/arm/aes_gcm.rs
  • rind/src/mid/chacha20.rs
  • rind/src/mid/mlkem768.rs
  • rind/tests/crosschecks.rs
  • rind/tests/debug.rs
  • rind/tests/wycheproof.rs
  • rind/tests/zeroing.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed head: b2981a8

  • Findings: no actionable defect found in the inspected changes. The RSA constructor move retains parsing and algorithm checks, the new GCM IV wrapper validates before dispatch, and the added Debug implementations expose algorithm metadata rather than key material.
  • Direction: the changes match the recorded API decisions and are appropriately grouped before 0.2.0. No architectural revision requested. A small non-blocking test improvement would exercise multiple decapsulations, including malformed-then-valid input, on one retained ML-KEM key to pin the newly reusable contract.
  • Verification limits: GitHub-only static review of the 58-file diff and relevant implementation/test context. I did not run tests, cross-target builds, benchmarks, or Lean proofs; the PR's reported local passes are not independently verified. The head's visible prove run is still in progress and the returned Queue runs are skipped, so this is not a CI-pass claim.

kixelated and others added 2 commits November 5, 2026 22:33
Ports #382's key formats to the audit's names: `Sec1` joins `Pkcs8` and
`Spki` in `rind::encoding`, and #382's tests, fuzzers, and Lean quotes use
`from_scalar`, `from_components`, `rsa::KeySize`, and
`rsa::PublicKeyComponents`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated added this pull request to the merge queue Nov 6, 2026

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed head: 395db17

Incremental review since the previous review at b2981a8, focused on integrating #382 with the API audit.

  • Findings: no actionable defect found in this integration delta. rind/src/lib.rs moves the newly merged Sec1 export into encoding alongside Pkcs8 and Spki; its existing redacted Debug and zeroizing Drop remain intact. The added agreement tests, crosschecks, and key-fuzzer call sites use from_scalar, while the merged key-format constructors and exporters retain their implementations. README and MIGRATING.md describe the new SEC1 location.
  • Direction: extending the recorded encoding-module decision to SEC1 is consistent with the audited API and belongs in this pre-0.2.0 break. No additional API or architectural revision identified.
  • Verification limits: GitHub-only static comparison of the old and current PR diffs, merge history, and relevant key-format implementation/test context. This is not a fresh audit of the unrelated SHA changes merged from main. I did not run builds, tests, fuzzers, benchmarks, or Lean proofs, and the PR's reported local passes are not independently verified. The visible prove run for this head is in progress and the returned Queue runs are skipped; this is not a CI-pass claim.

Merged via the queue into main with commit 17eff88 Nov 6, 2026
7 of 8 checks passed
@moq-bot moq-bot Bot mentioned this pull request Nov 6, 2026
This was referenced Nov 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant