Skip to content
moq-devPublic

About

High quality, fast and easy to build cryptography for Rust

Resources

Contributing

Stars

6 stars

Watchers

0 watching

Forks

Latest commit

 

History

1,155 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rind: a curled strip of green graviola peel forms the r, followed by ind

Cryptography slop. Fast, somewhat formally verified, and in pure Rust.
A drop-in for ring, aws-lc-rs, and rustls.

Latest release Documentation Build Status

  • 🏎️ As fast as aws-lc-rs and ring. rind matches or beats both on nearly every operation TLS and QUIC run, from the handshake to each packet's AEAD.
  • 🛡️ Verified where it counts. On x86_64 and aarch64, rind's elliptic-curve, RSA, and ML-KEM arithmetic builds on s2n-bignum's formally verified assembly, and rind's own Lean proofs carry X25519 and Ed25519 from its API down to it, as Verified code lists.
  • 🦀 No C toolchain. rind's assembly lives in Rust source: no C compiler, cmake, nasm, or perl, for the host or a cross target. A rustls client builds faster over rind than over aws-lc-rs or ring.

Every benchmark, on every CPU

Time over the fastest library's, by operation, library, and host

Each row is an operation and each column a library, with one square per machine: x86_64 from Haswell to Zen 3 and Arrow Lake, and an Apple M4. Green is the fastest library on that machine, or within 10% of it, and red is over 8× slower. A shield marks formally verified code. Where another library leads, mostly at short messages on Apple silicon, where rind alone sets DIT around each call, Known gaps says why and what closes it. BENCHMARKS.md has every time, build time, and binary size.

The launch post tells why rind exists and what building it cost in AI tokens.

Switch in one line

rind is new, so exercise due caution.

[dependencies]
# A rustls CryptoProvider: turn off rustls's default features, which compile aws-lc-rs.
rind-rustls = "0.23"
rustls = { version = "0.23", default-features = false, features = ["std", "tls12"] }

# Or keep your code, and rename the dependency: ring and aws-lc-rs's APIs, name for name.
ring = { package = "rind-ring", version = "0.17" }
aws-lc-rs = { package = "rind-aws-lc-rs", version = "1" }

# Or use rind's own API.
rind = "0.3"

With rustls

Install rind-rustls at startup, then use rustls as normal:

rind_rustls::default_provider().install_default().unwrap();

With an agent

Paste this into your coding agent, in your repository:

Move this repository from ring or aws-lc-rs to rind, following
https://raw.githubusercontent.com/moq-dev/rind/main/MIGRATE.md

It migrates on a local branch, reports the build time, binary size, benchmarks, and tests before and after, and asks before opening a PR or filing an issue. To migrate by hand, MIGRATING.md maps each ring and aws-lc-rs item to rind's.

Directly

The rind crate's own API covers AES-GCM, ChaCha20-Poly1305, and XChaCha20-Poly1305, QUIC header protection, X25519 and ECDH, ML-KEM-768, HPKE, ECDSA, Ed25519, and RSA signatures, RSA-OAEP, SHA-1, SHA-2, and SHA-3, HMAC, HKDF, PBKDF2, and AES key wrap. Each algorithm is a constant and each key type has one role, so misuse fails to compile:

use rind::signature::{EcdsaKeyPair, PublicKey, sign, verify};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // An error naming the missing CPU feature, rather than a panic later.
    rind::cpu::check()?;

    let key_pair = EcdsaKeyPair::generate(&sign::ECDSA_P256_SHA256_ASN1)?;
    let signature = key_pair.sign(b"hello")?;

    let encoded = key_pair.public_key();
    let public_key = PublicKey::new(&verify::ECDSA_P256_SHA256_ASN1, encoded.as_ref())?;
    public_key.verify(b"hello", signature.as_ref())?;
    Ok(())
}

docs.rs documents every module, and ARCHITECTURE.md describes the API's shape.

Adapters

Each crate's README shows its setup.

Crate For
rind-ring ring 0.17's API, name for name
rind-aws-lc-rs aws-lc-rs 1.x's API, name for name, for every item rind backs
rind-dimpl DTLS 1.2 and 1.3 through dimpl
rind-str0m WebRTC through str0m
rind-jsonwebtoken JWTs through jsonwebtoken
rind-object-store S3, Azure, and GCS request signing through object_store
rind-rcgen certificates through rcgen
rind-dart Dart and Flutter, through FFI: the rind package, unpublished until its first pub.dev release
rind-python Python, as the pyrind package on PyPI, with rind's own API
pyrind-cryptography Python, pyca/cryptography's hazmat API on pyrind, unpublished until its first PyPI release

Wiping keys

rind wipes keys, keyed state, and heap scratch derived from a private key on drop only under its wipe feature, as RustCrypto does with zeroize; aws-lc-rs always wipes, and ring never does. The benefit of wiping is to avoid unused keys being leaked in a heap dump, like with Heartbleed. But IMO, you have bigger issues at that point, and it's not worth the perf hit by default. Enable it on rind itself, and Cargo turns it on beneath every adapter too. rind-aws-lc-rs also has its own wipe, which turns on rind's and wipes the adapter's own copies of secrets.

[dependencies]
rind = { version = "0.3", features = ["wipe"] }

Data-independent timing

On Apple silicon, each rind call that handles a secret turns on DIT (data-independent timing) at entry and back off on return. From the M3, DIT turns off the data memory-dependent prefetcher that GoFetch leaks keys from constant-time code through, and clearing it on return leaves the rest of the thread as the application set it. The M1 and M2 have no such switch, so they pay the toggle's cost without that protection. Arm says DIT changes nothing on its current cores, so rind sets it only on Apple's platforms; aws-lc-rs and ring never set it.

DIT is a second layer, not the constant-time guarantee: on every platform, rind's secret-handling code avoids branches, memory indices, and variable-time instructions that depend on a secret, and TESTING.md lists the check each primitive gets.

Turning DIT on and off costs about 45-60 ns a call on Apple's M1 and M4, a fifth of sealing a 1350-byte packet. A loop of small calls, such as sealing a batch of QUIC packets, holds a guard around the batch to pay it once:

let _dit = rind::cpu::Dit::hold();

The guard covers every rind call its thread makes, including those through rind-rustls and the other adapters, and does nothing off Apple's platforms.

Platforms

rind has assembly for x86_64, aarch64, and 32-bit arm from ARMv7 on, and runs portable Rust on any other architecture (on 32-bit x86, only with Rust 1.94 rather than its 1.90 MSRV). CI tests Linux (glibc and musl), macOS, and Windows on x86_64 and aarch64, Linux and Windows on 32-bit x86, iOS in the simulator, Android on aarch64, armv7, ARMv5TE, x86_64, and 32-bit x86, and Linux on armv7, ARMv6, big-endian s390x, riscv64gc (glibc and musl), loongarch64, powerpc64le, and big-endian powerpc64 and powerpc. Any x86_64 CPU runs it, little-endian aarch64 needs NEON, and every operation panics on a CPU missing a feature rind requires: call rind::cpu::check() at startup to get an error naming it instead. PLATFORMS.md lists what each architecture runs without each feature.

Contributing

AI reviews and contributions are welcome. rind plans its work as quests, Markdown files under quest/, with skills for Claude Code and Codex. With quest installed, have your agent run /quest-plan to propose a change or report a finding, or /quest-start to take a quest from the backlog. CONTRIBUTING.md covers building, testing, and how a PR lands.

Learn more

  • ALGORITHMS.md: whose code runs each algorithm on each CPU, what of it is formally verified, its sources and their licenses, and how the main paths work.
  • PLATFORMS.md: the CPU features each architecture requires, and what runs without the optional ones.
  • ARCHITECTURE.md: the API's design, its modules, and the layers beneath them.
  • BENCHMARKS.md: every operation's time, build time, and binary size, against the other libraries.

Built on great work

rind began as a fork of Graviola by Joe Birr-Pixton, and no longer tracks it. Graviola is an outstanding project: a fast, carefully designed cryptography library with a refreshingly simple Rust-only build. rind owes it its starting point, much of its code, and the example it follows. If Graviola covers your needs, please give it a look and support its authors.

aws-lc-rs is excellent, too. It is the library we would use if we did not need to build without C. AWS-LC supplies many of rind's implementations, and aws-lc-rs is our reference for behavior, differential tests, and performance.

The credit for the underlying algorithms, implementations, and proofs belongs to their authors, including s2n-bignum, HACL*, libcrux, fiat-crypto, and the other projects ALGORITHMS.md lists. rind's contribution is to distill and integrate their work.

The rind logo is a tribute to Graviola's fruit illustration, reimagined as a curled strip of its protective rind. A wordmark for dark backgrounds starts white ind beneath the curl and extends it to the right.

License

rind's own code is licensed under Apache-2.0 OR ISC OR MIT-0. Code copied from other projects keeps its source's license, which LICENSE lists.

About

High quality, fast and easy to build cryptography for Rust

Resources

Contributing

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages