Skip to main content

reallyme_crypto/
lib.rs

1// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
2//
3// SPDX-License-Identifier: Apache-2.0
4
5//! # reallyme-crypto
6//!
7//! Umbrella crate that re-exports the ReallyMe cryptographic primitives,
8//! codecs, dispatch, and signer abstractions behind one dependency and a
9//! consistent feature set.
10//!
11//! ## Platform lanes
12//!
13//! Every primitive is available through four backend lanes selected by
14//! Cargo feature and target: `native` (portable Rust), `wasm` (browser
15//! bindings), `swift` (Apple CryptoKit / Secure Enclave), and `kotlin`
16//! (Android Keystore). Selecting a platform lane compiles against that
17//! platform's crypto; a lane never silently falls back to native Rust —
18//! an Apple/Android build without the corresponding link cfg fails to
19//! compile rather than substituting a different backend.
20//!
21//! ## Security posture
22//!
23//! `#![forbid(unsafe_code)]` here; secret material is returned in zeroizing
24//! wrappers; signature verification fails closed; and cross-implementation
25//! conformance vectors pin the Rust output against an independent oracle.
26//! See `SECURITY.md` and `SECURITY_MEMORY_MODEL.md` at the repository root.
27//!
28//! ## Example: sign then verify
29//!
30//! A detached signature round-trip through [`dispatch`] (requires the
31//! `dispatch` and `ed25519` features, both on by default). Verification
32//! fails closed — tampering with the message yields `Err`, never `Ok(false)`.
33//!
34//! ```
35//! # #[cfg(all(feature = "dispatch", feature = "ed25519"))]
36//! # fn main() -> Result<(), reallyme_crypto::dispatch::AlgorithmError> {
37//! use reallyme_crypto::core::Algorithm;
38//! use reallyme_crypto::dispatch::{generate_keypair, sign, verify};
39//!
40//! let (public, secret) = generate_keypair(Algorithm::Ed25519)?;
41//! let message = b"attested payload";
42//!
43//! let signature = sign(Algorithm::Ed25519, &secret, message)?;
44//! verify(Algorithm::Ed25519, &public, message, &signature)?;
45//!
46//! // A signature never covers a different message: verify returns Err.
47//! assert!(verify(Algorithm::Ed25519, &public, b"tampered", &signature).is_err());
48//! # Ok(())
49//! # }
50//! # #[cfg(not(all(feature = "dispatch", feature = "ed25519")))]
51//! # fn main() {}
52//! ```
53
54#![forbid(unsafe_code)]
55
56pub use crypto_core as core;
57
58/// JSON Web Key envelope types and public-key conversion helpers.
59#[cfg(feature = "jwk")]
60pub use envelopes_jwk as jwk;
61
62/// Bidirectional conversion between JWK and Multikey public-key envelopes.
63#[cfg(feature = "jwk-multikey")]
64pub use envelopes_jwk_multikey as jwk_multikey;
65
66/// Algorithm-selected dispatch: keygen, sign/verify, key agreement, KEM, AEAD,
67/// hashing, and multikey binding routed by an [`core::Algorithm`] selector.
68#[cfg(feature = "dispatch")]
69pub mod dispatch {
70    pub use crypto_dispatch::{
71        aead_decrypt, aead_encrypt, derive_shared_secret, generate_keypair,
72        generate_multikey_keypair, hash_digest, kem_decapsulate, kem_encapsulate, mac_authenticate,
73        mac_verify, public_key_to_multikey, sign, validate_verification_method_multikey, verify,
74        AeadParams, AlgorithmError, GeneratedKeypair, MacParams,
75    };
76}
77
78/// Signer/verifier traits and dispatch-backed implementations for producing and
79/// checking detached signatures.
80#[cfg(feature = "signer")]
81pub mod signer {
82    pub use crypto_signer::{
83        DispatchSigner, DispatchVerifier, Signer, SignerError, SignerFailureKind, Verifier,
84        VerifierError, VerifierFailureKind,
85    };
86}
87
88/// AES-256-GCM authenticated encryption primitive and its typed key/nonce
89/// wrappers and length constants.
90#[cfg(feature = "aes")]
91pub mod aes {
92    pub use crypto_aes256_gcm::{
93        decrypt, encrypt, Aes256GcmKey, Aes256GcmNonce, CiphertextWithTag, DecryptRequest,
94        EncryptRequest, AES_256_GCM_KEY_LENGTH, AES_256_GCM_NONCE_LENGTH, AES_256_GCM_TAG_LENGTH,
95    };
96}
97
98/// AES-256 Key Wrap (RFC 3394) for wrapping compact key material.
99#[cfg(feature = "aes-kw")]
100pub mod aes_kw {
101    pub use crypto_aes_kw::{
102        unwrap_key, wrap_key, Aes256KwKek, AesKwKeyData, AesKwWrappedKey, AES_256_KW_KEK_LENGTH,
103        AES_KW_BLOCK_LENGTH, AES_KW_INTEGRITY_CHECK_LENGTH, AES_KW_MAX_KEY_DATA_LENGTH,
104        AES_KW_MIN_KEY_DATA_LENGTH, AES_KW_MIN_WRAPPED_KEY_LENGTH,
105    };
106}
107
108/// AES-256-GCM-SIV nonce-misuse-resistant authenticated encryption primitive and
109/// its typed key/nonce wrappers and length constants.
110#[cfg(feature = "aes-gcm-siv")]
111pub mod aes_gcm_siv {
112    pub use crypto_aes256_gcm_siv::{
113        decrypt, encrypt, Aes256GcmSivKey, Aes256GcmSivNonce, CiphertextWithTag, DecryptRequest,
114        EncryptRequest, AES_256_GCM_SIV_KEY_LENGTH, AES_256_GCM_SIV_NONCE_LENGTH,
115        AES_256_GCM_SIV_TAG_LENGTH,
116    };
117}
118
119/// ChaCha20-Poly1305 and XChaCha20-Poly1305 authenticated encryption
120/// primitives with typed key and nonce wrappers.
121#[cfg(feature = "chacha20-poly1305")]
122pub mod chacha20_poly1305 {
123    pub use crypto_chacha20_poly1305::{
124        decrypt, decrypt_xchacha20_poly1305, encrypt, encrypt_xchacha20_poly1305,
125        ChaCha20Poly1305Key, ChaCha20Poly1305Nonce, CiphertextWithTag, DecryptRequest,
126        EncryptRequest, XChaCha20Poly1305DecryptRequest, XChaCha20Poly1305EncryptRequest,
127        XChaCha20Poly1305Nonce, CHACHA20_POLY1305_KEY_LENGTH, CHACHA20_POLY1305_NONCE_LENGTH,
128        CHACHA20_POLY1305_TAG_LENGTH, XCHACHA20_POLY1305_NONCE_LENGTH,
129    };
130}
131
132/// Argon2id password-based key derivation, including platform-tuned cost
133/// profiles and typed salt/secret/derived-key wrappers.
134#[cfg(feature = "argon2id")]
135pub mod argon2id {
136    pub use crypto_argon2id::{
137        derive_key, derive_key_for_version, resolve_mobile_profile_for_unlock,
138        resolve_profile_params_for_platform, resolve_profile_params_with_caps, Argon2Caps,
139        Argon2KdfVersion, Argon2ParamsProfile, Argon2PlatformClass, Argon2Profile, Argon2Salt,
140        Argon2Secret, Argon2idDerivedKey, DeriveKeyRequest, ARGON2ID_DERIVED_KEY_LENGTH,
141        ARGON2ID_SALT_MAX_LENGTH, ARGON2ID_SALT_MIN_LENGTH, ARGON2ID_V1_LANES,
142        ARGON2ID_V1_MEMORY_COST_KIB, ARGON2ID_V1_TIME_COST, ARGON2ID_V2_LANES,
143        ARGON2ID_V2_MEMORY_COST_KIB, ARGON2ID_V2_TIME_COST,
144    };
145}
146
147/// Constant-time (non-short-circuiting) byte-slice equality checks.
148#[cfg(feature = "constant-time")]
149pub mod constant_time {
150    pub use crypto_constant_time::{ct_eq, ct_eq_fixed, require_ct_eq};
151}
152
153/// OS-backed cryptographically secure randomness and typed generators for AEAD
154/// nonces and Argon2 salts.
155#[cfg(feature = "csprng")]
156pub mod csprng {
157    pub use crypto_csprng::{
158        generate_aead_nonce_12, generate_argon2_salt_16, generate_argon2_salt_32, generate_bytes,
159        AeadNonce12, Argon2Salt16, Argon2Salt32, OsSecureRandom, RandomBytes, SecureRandom,
160        AEAD_NONCE_12_LENGTH, ARGON2_SALT_16_LENGTH, ARGON2_SALT_32_LENGTH,
161    };
162}
163
164/// Ed25519 signatures: keypair generation, sign/verify, and public-key encoding.
165#[cfg(feature = "ed25519")]
166pub mod ed25519 {
167    pub use crypto_ed25519::{
168        assert_public_key, decode_public_key, encode_public_key, generate_ed25519_keypair,
169        generate_ed25519_keypair_from_seed, sign_ed25519, verify_ed25519,
170    };
171}
172
173/// HMAC authentication tags over SHA-256 and SHA-512.
174#[cfg(feature = "hmac")]
175pub mod hmac {
176    pub use crypto_hmac::{
177        authenticate, verify, HmacKey, HmacTag, HMAC_MAX_KEY_LENGTH, HMAC_SHA256_TAG_LENGTH,
178        HMAC_SHA512_TAG_LENGTH,
179    };
180}
181
182/// NIST P-256 (secp256r1) ECDSA over pre-hashed messages, with public-key
183/// compression and Secure Enclave handle encoding.
184#[cfg(feature = "p256")]
185pub mod p256 {
186    pub use crypto_p256::{
187        compress_public_key, decode_se_handle, decompress_public_key, derive_p256_shared_secret,
188        encode_se_handle, generate_p256_keypair, generate_p256_keypair_from_secret_key,
189        p256_ecdsa_der_to_jose_signature, p256_ecdsa_der_to_jose_signature_permissive,
190        p256_ecdsa_jose_signature_to_der, sign_p256_der_prehash, verify_p256_der_prehash,
191        P256_ECDSA_JOSE_SIGNATURE_LEN, SE_HANDLE_PREFIX,
192    };
193}
194
195/// NIST P-384 (secp384r1) ECDSA over pre-hashed messages, with public-key
196/// compression/decompression helpers.
197#[cfg(feature = "p384")]
198pub mod p384 {
199    pub use crypto_p384::{
200        compress_p384, decompress_p384, generate_p384_keypair,
201        generate_p384_keypair_from_secret_key, sign_p384_der_prehash, verify_p384_der_prehash,
202        P384_PUBLIC_KEY_COMPRESSED_LEN, P384_PUBLIC_KEY_RAW_LEN, P384_PUBLIC_KEY_UNCOMPRESSED_LEN,
203        P384_SECRET_KEY_LEN, P384_SIGNATURE_DER_MAX_LEN,
204    };
205}
206
207/// NIST P-521 (secp521r1) ECDSA over pre-hashed messages, with public-key
208/// compression/decompression helpers.
209#[cfg(feature = "p521")]
210pub mod p521 {
211    pub use crypto_p521::{
212        compress_p521, decompress_p521, generate_p521_keypair,
213        generate_p521_keypair_from_secret_key, sign_p521_der_prehash, verify_p521_der_prehash,
214        P521_PUBLIC_KEY_COMPRESSED_LEN, P521_PUBLIC_KEY_RAW_LEN, P521_PUBLIC_KEY_UNCOMPRESSED_LEN,
215        P521_SECRET_KEY_LEN, P521_SIGNATURE_DER_MAX_LEN,
216    };
217}
218
219/// PBKDF2 (RFC 8018) for legacy password-based key derivation.
220#[cfg(feature = "pbkdf2")]
221pub mod pbkdf2 {
222    pub use crypto_pbkdf2::{
223        derive_key, Pbkdf2Iterations, Pbkdf2Output, Pbkdf2Password, Pbkdf2Prf, Pbkdf2Request,
224        Pbkdf2Salt, PBKDF2_MAX_OUTPUT_LENGTH, PBKDF2_MAX_PASSWORD_LENGTH, PBKDF2_MAX_SALT_LENGTH,
225        PBKDF2_MIN_ITERATIONS, PBKDF2_MIN_OUTPUT_LENGTH, PBKDF2_MIN_PASSWORD_LENGTH,
226        PBKDF2_MIN_SALT_LENGTH,
227    };
228}
229
230/// RSA signature verification for PKCS#1 v1.5 and PSS.
231#[cfg(feature = "rsa")]
232pub mod rsa {
233    pub use crypto_rsa::{
234        verify_rsa_pkcs1v15, verify_rsa_pss, RsaHash, RsaPssParams, RsaPublicKeyDerEncoding,
235        RSA_MAX_MODULUS_BITS, RSA_MIN_MODULUS_BITS, RSA_PUBLIC_KEY_DER_MAX_LEN,
236        RSA_SIGNATURE_MAX_LEN,
237    };
238}
239
240/// secp256k1 ECDSA signs SHA-256(message) once, returns compact low-S `r || s`,
241/// and uses compressed SEC1 public keys as the canonical API representation.
242#[cfg(feature = "secp256k1")]
243pub mod secp256k1 {
244    pub use crypto_secp256k1::{
245        decode_bip340_schnorr_public_key, decode_public_key, decompress_public_key,
246        derive_bip340_schnorr_public_key, encode_bip340_schnorr_public_key, encode_public_key,
247        generate_secp256k1_keypair, generate_secp256k1_keypair_from_secret_key,
248        secp256k1_ecdsa_der_to_jose_signature, secp256k1_ecdsa_der_to_jose_signature_permissive,
249        secp256k1_ecdsa_jose_signature_to_der, sign_bip340_schnorr, sign_secp256k1,
250        verify_bip340_schnorr, verify_secp256k1, BIP340_SCHNORR_AUX_RAND_LEN,
251        BIP340_SCHNORR_MESSAGE_LEN, BIP340_SCHNORR_PUBLIC_KEY_LEN, BIP340_SCHNORR_SIGNATURE_LEN,
252        SECP256K1_ECDSA_JOSE_SIGNATURE_LEN, SECP256K1_SECRET_KEY_LEN,
253    };
254}
255
256/// X25519 Diffie–Hellman key agreement and public-key encoding.
257#[cfg(feature = "x25519")]
258pub mod x25519 {
259    pub use crypto_x25519::{
260        decode_public_key, derive_x25519_shared_secret, encode_public_key, generate_x25519_keypair,
261        generate_x25519_keypair_from_seed,
262    };
263}
264
265/// X-Wing hybrid KEM suites over X25519 plus ML-KEM-768 or ML-KEM-1024.
266#[cfg(feature = "x-wing")]
267pub mod x_wing {
268    pub use crypto_x_wing::{
269        generate_x_wing_1024_keypair, generate_x_wing_1024_keypair_derand,
270        generate_x_wing_768_keypair, generate_x_wing_768_keypair_derand, x_wing_1024_decapsulate,
271        x_wing_1024_encapsulate, x_wing_1024_encapsulate_derand, x_wing_768_decapsulate,
272        x_wing_768_encapsulate, x_wing_768_encapsulate_derand, X_WING_1024_CIPHERTEXT_LEN,
273        X_WING_1024_PUBLIC_KEY_LEN, X_WING_768_CIPHERTEXT_LEN, X_WING_768_PUBLIC_KEY_LEN,
274        X_WING_ENCAPS_SEED_LEN, X_WING_SECRET_KEY_LEN, X_WING_SHARED_SECRET_LEN,
275    };
276}
277
278/// RFC 9180 HPKE Base-mode encryption over supported DHKEM/HKDF/AEAD suites.
279#[cfg(feature = "hpke")]
280pub mod hpke {
281    pub use crypto_hpke::{
282        open_base, seal_base, HpkeError, HpkeOpenOutput, HpkeOpenRequest, HpkePrivateKeyBytes,
283        HpkeSealOutput, HpkeSealRequest, HpkeSuite, HPKE_AEAD_AES_256_GCM,
284        HPKE_AEAD_CHACHA20_POLY1305, HPKE_AEAD_TAG_LEN, HPKE_ENCAPSULATED_KEY_MAX_LEN,
285        HPKE_KDF_HKDF_SHA256, HPKE_KEM_DHKEM_P256_HKDF_SHA256, HPKE_KEM_DHKEM_X25519_HKDF_SHA256,
286        HPKE_P256_PRIVATE_KEY_LEN, HPKE_P256_PUBLIC_KEY_LEN, HPKE_X25519_PRIVATE_KEY_LEN,
287        HPKE_X25519_PUBLIC_KEY_LEN,
288    };
289}
290
291/// HKDF (RFC 5869) extract-and-expand key derivation over the SHA-2/SHA-3 suites,
292/// with domain-separated key derivation helpers.
293#[cfg(feature = "hkdf")]
294pub mod hkdf {
295    pub use crypto_hkdf::{
296        derive, derive_domain_key_32, DeriveRequest, DomainKeyPurpose, DomainTag, HkdfInfo,
297        HkdfInputKeyMaterial, HkdfOutput, HkdfSalt, HkdfSuite,
298    };
299}
300
301/// ML-DSA-44 (FIPS 204) post-quantum signatures: keygen, sign/verify, and
302/// public-key encoding.
303#[cfg(feature = "ml-dsa-44")]
304pub mod ml_dsa_44 {
305    pub use crypto_ml_dsa_44::{
306        decode_public_key, encode_public_key, generate_ml_dsa_44_keypair,
307        generate_ml_dsa_44_keypair_from_seed, sign_ml_dsa_44, verify_ml_dsa_44,
308    };
309}
310
311/// ML-DSA-65 (FIPS 204) post-quantum signatures: keygen, sign/verify, and
312/// public-key encoding.
313#[cfg(feature = "ml-dsa-65")]
314pub mod ml_dsa_65 {
315    pub use crypto_ml_dsa_65::{
316        decode_public_key, encode_public_key, generate_ml_dsa_65_keypair,
317        generate_ml_dsa_65_keypair_from_seed, sign_ml_dsa_65, verify_ml_dsa_65,
318    };
319}
320
321/// ML-DSA-87 (FIPS 204) post-quantum signatures: keygen, sign/verify, and
322/// public-key encoding.
323#[cfg(feature = "ml-dsa-87")]
324pub mod ml_dsa_87 {
325    pub use crypto_ml_dsa_87::{
326        decode_public_key, encode_public_key, generate_ml_dsa_87_keypair,
327        generate_ml_dsa_87_keypair_from_seed, sign_ml_dsa_87, verify_ml_dsa_87,
328    };
329}
330
331/// SLH-DSA-SHA2-128s (FIPS 205) hash-based post-quantum signatures.
332#[cfg(feature = "slh-dsa")]
333pub mod slh_dsa {
334    pub use crypto_slh_dsa::{
335        decode_slh_dsa_sha2_128s_public_key, derive_slh_dsa_sha2_128s_keypair,
336        encode_slh_dsa_sha2_128s_public_key, generate_slh_dsa_sha2_128s_keypair,
337        sign_slh_dsa_sha2_128s, verify_slh_dsa_sha2_128s, SLH_DSA_SHA2_128S_KEYGEN_SEED_LEN,
338        SLH_DSA_SHA2_128S_PUBLIC_KEY_LEN, SLH_DSA_SHA2_128S_SECRET_KEY_LEN,
339        SLH_DSA_SHA2_128S_SIGNATURE_LEN,
340    };
341}
342
343/// ML-KEM-512 (FIPS 203) post-quantum key encapsulation: keygen, encapsulate,
344/// and decapsulate.
345#[cfg(feature = "ml-kem-512")]
346pub mod ml_kem_512 {
347    pub use crypto_ml_kem_512::{
348        generate_ml_kem_512_keypair, generate_ml_kem_512_keypair_from_seed, ml_kem_512_decapsulate,
349        ml_kem_512_encapsulate, ml_kem_512_encapsulate_derand,
350    };
351}
352
353/// ML-KEM-768 (FIPS 203) post-quantum key encapsulation: keygen, encapsulate,
354/// and decapsulate.
355#[cfg(feature = "ml-kem-768")]
356pub mod ml_kem_768 {
357    pub use crypto_ml_kem_768::{
358        generate_ml_kem_768_keypair, generate_ml_kem_768_keypair_from_seed, ml_kem_768_decapsulate,
359        ml_kem_768_encapsulate, ml_kem_768_encapsulate_derand,
360    };
361}
362
363/// ML-KEM-1024 (FIPS 203) post-quantum key encapsulation: keygen, encapsulate,
364/// and decapsulate.
365#[cfg(feature = "ml-kem-1024")]
366pub mod ml_kem_1024 {
367    pub use crypto_ml_kem_1024::{
368        generate_ml_kem_1024_keypair, generate_ml_kem_1024_keypair_from_seed,
369        ml_kem_1024_decapsulate, ml_kem_1024_encapsulate, ml_kem_1024_encapsulate_derand,
370    };
371}
372
373/// SHA-2-256 hashing and its fixed-length digest wrapper.
374#[cfg(feature = "sha2")]
375pub mod sha2 {
376    pub use crypto_sha2::{
377        digest_sha2_384, digest_sha2_512, Sha2_384Digest, Sha2_512Digest, SHA2_384_DIGEST_LENGTH,
378        SHA2_512_DIGEST_LENGTH,
379    };
380    pub use crypto_sha2_256::{digest, Sha2_256Digest, SHA2_256_DIGEST_LENGTH};
381}
382
383/// SHA-3-256 hashing and its fixed-length digest wrapper.
384#[cfg(feature = "sha3")]
385pub mod sha3 {
386    pub use crypto_sha3::{
387        digest_sha3_224, digest_sha3_384, digest_sha3_512, Sha3_224Digest, Sha3_384Digest,
388        Sha3_512Digest, SHA3_224_DIGEST_LENGTH, SHA3_384_DIGEST_LENGTH, SHA3_512_DIGEST_LENGTH,
389    };
390    pub use crypto_sha3_256::{digest, Sha3_256Digest, SHA3_256_DIGEST_LENGTH};
391}
392
393/// Encoding and serialization codecs: base64, base64url, DAG-CBOR, JCS,
394/// multibase, multicodec, and multikey.
395#[cfg(feature = "codec")]
396pub mod codec {
397    /// Standard (RFC 4648) base64 encode/decode.
398    #[cfg(feature = "codec-base64")]
399    pub mod base64 {
400        pub use codec_base64::{base64_to_bytes, bytes_to_base64, Base64Error};
401    }
402
403    /// URL-safe (RFC 4648 §5) base64 encode/decode without padding.
404    #[cfg(feature = "codec-base64url")]
405    pub mod base64url {
406        pub use codec_base64url::{
407            base64url_bytes_to_bytes, base64url_to_bytes, bytes_to_base64url, Base64UrlError,
408        };
409    }
410
411    /// DAG-CBOR encode/decode and content-identifier (CID) computation and
412    /// verification.
413    #[cfg(feature = "codec-cbor")]
414    pub mod cbor {
415        pub use codec_cbor::{
416            compute_cid_dag_cbor, dag_cbor_multihash, decode_dag_cbor, encode_dag_cbor,
417            is_valid_cid_string, sha2_256_content_hash, try_parse_cid, verify_dag_cbor_cid,
418            CborError, CborValue, ContentHash, DagCborMultihash, DAG_CBOR_CODEC,
419        };
420    }
421
422    /// JSON Canonicalization Scheme (RFC 8785) serialization.
423    #[cfg(feature = "codec-jcs")]
424    pub mod jcs {
425        pub use codec_jcs::{canonicalize_json, JcsError};
426    }
427
428    /// Multibase self-describing base encodings (base58btc and base64url).
429    #[cfg(feature = "codec-multibase")]
430    pub mod multibase {
431        pub use codec_multibase::{
432            base58btc_decode, base58btc_encode, bytes_to_multibase58btc,
433            bytes_to_multibase_base64url, multibase_to_bytes, Base58Error, MultibaseError,
434        };
435    }
436
437    /// Multicodec varint prefix lookup and stripping.
438    #[cfg(feature = "codec-multicodec")]
439    pub mod multicodec {
440        pub use codec_multicodec::{
441            lookup_codec_prefix, strip_codec_prefix, CodecLookupResult, CodecSpec, MULTICODEC_TABLE,
442        };
443    }
444
445    /// Multikey encoding/parsing that binds an algorithm to its public-key bytes.
446    #[cfg(feature = "codec-multikey")]
447    pub mod multikey {
448        pub use codec_multikey::{
449            binding_type_matches_codec, encode_multikey, parse_multikey, validate_key_binding,
450            KeyBindingInput, MultikeyError, ParsedMultikey,
451        };
452    }
453}