Expand description
§reallyme-crypto
Umbrella crate that re-exports the ReallyMe cryptographic primitives, dispatch and signer abstractions behind one dependency and a consistent feature set.
§Platform lanes
Rust exposes two backend lanes selected by Cargo feature and target:
native (portable Rust) and wasm (package-owned Rust compiled for
WebAssembly with target-appropriate entropy support).
Swift and Kotlin provider selection lives in their package facades; those
facades call this Rust workspace through FFI/JNI only for algorithms whose
provider policy explicitly selects Rust. A lane never silently falls back to
another backend.
The canonical contract is not the Rust API by itself. It is the shared set of protobuf/enums, package algorithm identifiers, typed error taxonomy, provider manifest, and conformance vectors. Rust is the reference implementation and the shared implementation for selected primitives; native platform routes are interchangeable only when vectors and typed-error tests prove identical input, output, failure, and edge-case behavior.
§Security posture
#![forbid(unsafe_code)] here; secret material is returned in zeroizing
wrappers; signature verification fails closed; and cross-implementation
conformance vectors pin the Rust output against an independent oracle.
See SECURITY.md and SECURITY_MEMORY_MODEL.md at the repository root.
Compile-checked usage examples live in the crate README so tests remain separate from production implementation files.
§reallyme-crypto
ReallyMe Crypto is the Rust facade for a cross-platform cryptography workspace spanning Rust, Swift, Kotlin, Android, and TypeScript. It exposes typed operation owners, explicit provider routing, and the package surfaces used by the native and WASM adapters.
The protobuf schema is the source of truth for executable structured requests,
responses, algorithm identifiers, and wire errors. Generated bindings feed a
single Rust operation boundary. provider_manifest.json fixes the provider
selected for each SDK lane, and positive and negative vectors prove the byte
and failure contract. Missing providers and unsupported algorithms fail closed.
§Install
§Rust
cargo add reallyme-crypto --features native,dispatch,ed25519The Rust crates require Rust 1.96.0 or newer. That MSRV is intentional:
ReallyMe Crypto tracks current stable Rust so the public packages can use the
compiler, dependency, lint, and target support expected by the conformance wall.
When default features are disabled, enable one backend lane and each algorithm surface your crate calls:
reallyme-crypto = { version = "0.3.8", default-features = false, features = [
"native",
"ed25519",
"p256",
"secp256k1",
"sha2",
] }Messaging-focused consumers can use the narrow primitive bundle instead of the default feature set:
reallyme-crypto = { version = "0.3.8", default-features = false, features = [
"native",
"messaging-primitives",
] }messaging-primitives enables only ChaCha20-Poly1305/XChaCha20-Poly1305,
HKDF, HMAC, ML-KEM-768, SHA-2, and X25519. The ML-KEM-768 and X25519 algorithm
features require the typed router, so this bundle also enables dispatch; it
does not enable signer.
Dispatch and signer surfaces are feature-gated by algorithm, so enabling the router does not pull in unrelated primitives unless the matching algorithm feature is also selected.
The native and wasm features select the Rust backend lane. They do not, by
themselves, enable every primitive. Algorithm features such as ed25519,
p256, or sha2 enable the root modules and re-exports. This keeps
no-default consumers from pulling unused cryptography while still forwarding
the selected backend into every enabled primitive crate. The wasm lane is for
wasm32 builds; host builds should use native.
Some Rust helper APIs are intentionally lane-scoped. P-256 raw scalar import is
available in both native and wasm lanes through
p256::generate_p256_keypair_from_secret_key; it validates an existing private
scalar and is not random key generation. P-384 and P-521 ECDH are available
in both Rust lanes; the Swift, Kotlin, and TypeScript facades expose their
manifest-declared provider-backed P-384/P-521 ECDH surfaces.
For standalone X25519 and secp256k1 random key generation, prefer
try_generate_x25519_keypair and try_generate_secp256k1_keypair. These
return typed errors when operating-system entropy is unavailable. The legacy
infallible functions remain for compatibility; the dispatch API uses the
fallible path.
The Swift package also includes a P-256 ECDH Secure Enclave / Keychain API for applications that need non-exportable private-key residency, such as JOSE/JWE decryption with platform-held keys. That API uses explicit handles and is separate from raw private-key bytes.
§Examples
Fixed keys, nonces, and auxiliary randomness below are public test fixtures. Applications must supply secret keys and enforce nonce uniqueness for each AEAD key; never use these fixed values to protect real data.
// This example requires the `ed25519` feature.
use reallyme_crypto::Algorithm;
use reallyme_crypto::operations::signature::{generate_key_pair, sign, verify};
let key_pair = generate_key_pair(Algorithm::Ed25519)?;
let signature = sign(Algorithm::Ed25519, &key_pair.secret_key, b"message")?;
verify(Algorithm::Ed25519, &key_pair.public_key, b"message", &signature)?;BIP-340 uses an x-only secp256k1 public key and requires callers to provide a 32-byte message representative and 32 bytes of auxiliary randomness explicitly:
// This example requires the `secp256k1` feature.
use reallyme_crypto::operations::signature::{
generate_bip340_key_pair, sign_bip340, verify_bip340,
};
let key_pair = generate_bip340_key_pair()?;
let message32 = [0x42u8; 32];
let aux_rand32 = [0x24u8; 32];
let signature = sign_bip340(&key_pair.secret_key, &message32, &aux_rand32)?;
verify_bip340(&signature, &message32, &key_pair.public_key)?;Hashing is owned by the semantic operation layer. Adapters should call this surface instead of selecting a primitive independently:
// This example requires the `sha2` feature.
use reallyme_crypto::HashAlgorithm;
use reallyme_crypto::operations::hash;
let digest = hash::digest(HashAlgorithm::Sha2_256, b"abc")?;
assert_eq!(
digest,
[
0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad,
],
);HMAC authentication and fail-closed verification share the same semantic operation owner across Rust, structured protobuf, and C ABI adapters:
// This example requires the `hmac` feature.
use reallyme_crypto::MacAlgorithm;
use reallyme_crypto::operations::mac;
let key = [0x42u8; 32];
let message = b"authenticated message";
let tag = mac::authenticate(MacAlgorithm::HmacSha256, &key, message)?;
mac::verify(MacAlgorithm::HmacSha256, &key, message, &tag)?;Authenticated encryption uses the same operation owner for algorithm selection, typed failures, and zeroizing recovered plaintext:
// This example requires the `aes` feature.
use reallyme_crypto::operations::aead;
use reallyme_crypto::AeadAlgorithm;
let key = [0x42u8; 32];
let nonce = [0x24u8; 12];
let plaintext = b"authenticated plaintext";
let ciphertext = aead::seal(
AeadAlgorithm::Aes256Gcm,
&key,
&nonce,
b"context",
plaintext,
)?;
let opened = aead::open(
AeadAlgorithm::Aes256Gcm,
&key,
&nonce,
b"context",
&ciphertext,
)?;
assert_eq!(opened.as_slice(), plaintext);MLS and HPKE derive nonces from their protocol key schedules. The focused AES-256-GCM facade therefore accepts an explicit typed nonce and deliberately does not offer a random-nonce overload:
// This example requires the `aes` feature.
use reallyme_crypto::aes256_gcm::{
aes256_gcm_decrypt, aes256_gcm_encrypt, Aes256GcmKey, Aes256GcmNonce,
};
let key = Aes256GcmKey::from_slice(&[0x42; 32])?;
// In MLS or HPKE, this value comes from the protocol key schedule.
let nonce = Aes256GcmNonce::from_slice(&[0x24; 12])?;
let ciphertext = aes256_gcm_encrypt(&key, nonce, b"context", b"payload")?;
let plaintext = aes256_gcm_decrypt(&key, nonce, b"context", &ciphertext)?;
assert_eq!(plaintext, b"payload");The HPKE facade exposes explicit registry identifiers and derives its nonce internally; seal/open requests have no caller-supplied nonce field:
// This example requires the `hpke` and `native` features.
use reallyme_crypto::hpke::{
derive_keypair, open_base, seal_base, HpkeOpenRequest, HpkeSealRequest,
HPKE_DHKEM_P256_HKDF_SHA256_AES256GCM,
};
let suite = HPKE_DHKEM_P256_HKDF_SHA256_AES256GCM;
let recipient = derive_keypair(suite, &[0x5a; 32])?;
let sealed = seal_base(&HpkeSealRequest {
suite,
recipient_public_key: &recipient.public_key,
info: b"reallyme/example/v0.3",
aad: b"message metadata",
plaintext: b"confidential payload",
})?;
let opened = open_base(&HpkeOpenRequest {
suite,
encapsulated_key: &sealed.encapsulated_key,
recipient_private_key: recipient.private_key(),
info: b"reallyme/example/v0.3",
aad: b"message metadata",
ciphertext: &sealed.ciphertext,
})?;
assert_eq!(opened.plaintext.as_slice(), b"confidential payload");AES-KW uses the operation owner for suite selection and returns unwrapped key material in a zeroizing owner:
// This example requires the `aes-kw` feature.
use reallyme_crypto::operations::key_wrap;
use reallyme_crypto::KeyWrapAlgorithm;
let kek = [
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
];
let key_data = [
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
];
let wrapped = key_wrap::wrap_key(KeyWrapAlgorithm::Aes128Kw, &kek, &key_data)?;
let unwrapped = key_wrap::unwrap_key(
KeyWrapAlgorithm::Aes128Kw,
&kek,
wrapped.as_bytes(),
)?;
assert_eq!(unwrapped.as_bytes(), key_data);Signature verification fails closed: an invalid signature returns an error rather than a boolean that can be accidentally ignored.
§Protobuf
Enable operation-response to use
reallyme_crypto::operation_contract::process_operation_response(request_bytes).
It accepts an encoded CryptoOperationRequest and returns binary
CryptoOperationResponse bytes containing a typed result or error. The
ProtoJSON entrypoint accepts only non-secret request selectors and still returns
binary protobuf. Secret-bearing operations must use binary protobuf.
See the protobuf contract for schemas, generated SDK adapters, limits, and JSON restrictions.
§Documentation
See the repository overview for the complete algorithm list and other SDKs. The provider policy, memory model, and conformance instructions define the shared guarantees and validation requirements.
§License
Licensed under either the MIT License or the Apache License, Version 2.0, at your option. See LICENSE. Third-party components retain their own licenses and notices.
Re-exports§
pub use crypto_core as core;pub use envelopes_jwk as jwk;pub use envelopes_jwk_multikey as jwk_multikey;
Modules§
- aes
- AES-GCM authenticated encryption primitives and their typed key/nonce wrappers and length constants. AES-GCM facade routes backed by the semantic AEAD operation owner.
- aes256_
gcm - AES-256-GCM authenticated encryption with typed key and nonce boundaries. Focused AES-256-GCM facade with typed key and nonce boundaries.
- aes_
gcm_ siv - AES-256-GCM-SIV nonce-misuse-resistant authenticated encryption primitive and its typed key/nonce wrappers and length constants. AES-256-GCM-SIV facade routes backed by the semantic AEAD operation owner.
- aes_kw
- AES-128, AES-192, and AES-256 Key Wrap (RFC 3394) for compact key material. AES-KW facade routes backed by the semantic key-wrap operation owner.
- argon2id
- Argon2id password-based key derivation, including platform-tuned cost profiles and typed salt/secret/derived-key wrappers. Argon2id facade routes backed by the semantic KDF operation owner.
- chacha20_
poly1305 - ChaCha20-Poly1305 and XChaCha20-Poly1305 authenticated encryption primitives with typed key and nonce wrappers. ChaCha20-Poly1305 facade routes backed by the semantic AEAD operation owner.
- concat_
kdf - JWA ECDH-ES Concat KDF over SHA-256 for deriving content-encryption keys from an ECDH shared secret. JWA Concat KDF facade routes backed by the semantic KDF operation owner.
- csprng
- OS-backed cryptographically secure randomness and typed generators for AEAD nonces and Argon2 salts.
- dispatch
- Algorithm-selected dispatch: keygen, sign/verify, key agreement, KEM, AEAD,
hashing, and multikey binding routed by an
core::Algorithmselector. Root dispatch facade. - ed25519
- Ed25519 signatures: keypair generation, sign/verify, and public-key encoding. Ed25519 root facade routed through the signature operation layer.
- hkdf
- HKDF (RFC 5869) extract-and-expand key derivation over the SHA-2/SHA-3 suites, with domain-separated key derivation helpers. HKDF facade routes backed by the semantic KDF operation owner.
- hmac
- HMAC authentication tags over SHA-256, SHA-384, and SHA-512. HMAC facade routes backed by the semantic MAC operation owner.
- hpke
- RFC 9180 HPKE Base-mode encryption over supported DHKEM/HKDF/AEAD suites. Typed HPKE identifiers, suites, key management, encryption, and exporters.
- kmac
- KMAC256 key derivation for protocols using NIST SP 800-108 and SP 800-185. KMAC facade routes backed by the semantic KDF operation owner.
- ml_
dsa_ 44 - ML-DSA-44 (FIPS 204) post-quantum signatures: keygen, sign/verify, and public-key encoding. ML-DSA-44 root facade routed through the signature operation layer.
- ml_
dsa_ 65 - ML-DSA-65 (FIPS 204) post-quantum signatures: keygen, sign/verify, and public-key encoding. ML-DSA-65 root facade routed through the signature operation layer.
- ml_
dsa_ 87 - ML-DSA-87 (FIPS 204) post-quantum signatures: keygen, sign/verify, and public-key encoding. ML-DSA-87 root facade routed through the signature operation layer.
- ml_
kem_ 512 - ML-KEM-512 (FIPS 203) post-quantum key encapsulation: keygen, encapsulate, and decapsulate. ML-KEM-512 root facade routed through the KEM operation layer.
- ml_
kem_ 768 - ML-KEM-768 (FIPS 203) post-quantum key encapsulation: keygen, encapsulate, and decapsulate. ML-KEM-768 root facade routed through the KEM operation layer.
- ml_
kem_ 1024 - ML-KEM-1024 (FIPS 203) post-quantum key encapsulation: keygen, encapsulate, and decapsulate. ML-KEM-1024 root facade routed through the KEM operation layer.
- operations
- Operation-layer domain conventions shared by Rust and adapter boundaries. Semantic operation-layer conventions.
- p256
- NIST P-256 (secp256r1) ECDSA over pre-hashed messages, with public-key compression and Secure Enclave handle encoding. P-256 root facade with signature and key agreement routed through operations.
- p384
- NIST P-384 (secp384r1) ECDSA and ECDH, with public-key compression/decompression helpers. P-384 root facade with signature and key agreement routed through operations.
- p521
- NIST P-521 (secp521r1) ECDSA and ECDH, with public-key compression/decompression helpers. P-521 root facade with signature and key agreement routed through operations.
- pbkdf2
- PBKDF2 password-based key derivation conforming to RFC 8018. PBKDF2 facade routes backed by the semantic KDF operation owner.
- rsa
- RSA signature verification for PKCS#1 v1.5 and PSS. RSA signature verification facade over the semantic operation owner.
- secp256k1
- secp256k1 ECDSA signs SHA-256(message) once, returns compact low-S
r || s, and uses compressed SEC1 public keys as the canonical API representation. secp256k1 root facade with ECDSA routed through the operation layer. - secret_
material - Typed ownership, retention, export, and destruction contracts for secrets. Typed secret-material ownership and cleanup contracts.
- sha2
- SHA-2-256 hashing and its fixed-length digest wrapper. SHA-2 facade routes backed by the semantic hash operation owner.
- sha3
- SHA-3-256 hashing and its fixed-length digest wrapper. SHA-3 facade routes backed by the semantic hash operation owner.
- signer
- Signer/verifier traits and dispatch-backed implementations for producing and checking detached signatures.
- slh_dsa
- SLH-DSA-SHA2-128s (FIPS 205) hash-based post-quantum signatures. SLH-DSA-SHA2-128s root facade routed through the signature operation layer.
- x25519
- X25519 Diffie–Hellman key agreement and public-key encoding. X25519 root facade with key agreement routed through the operation layer.
- x_wing
- X-Wing hybrid KEM over X25519 plus ML-KEM-768. X-Wing root facade routed through the KEM operation layer.
Enums§
- Aead
Algorithm - Authenticated encryption (AEAD) algorithm identifiers.
- Algorithm
- Asymmetric algorithm identifiers used for signatures and key agreement.
- Crypto
Error - Typed error taxonomy for all crypto operations in the workspace.
- Hash
Algorithm - Hash algorithm identifiers.
- KeyWrap
Algorithm - Key-wrapping algorithm identifier.
- MacAlgorithm
- Message authentication code algorithm identifiers.