dcrypt API (api)
The api crate defines the public Application Programming Interface for the dcrypt cryptographic ecosystem. It establishes the core traits, error handling mechanisms, and fundamental types that are used consistently across all dcrypt libraries.
The primary goal of this crate is to provide a stable and ergonomic interface for users of dcrypt, abstracting away the specific implementation details of the underlying cryptographic algorithms.
Core Components
-
Traits (
dcrypt_docs/api/traits/README.md): Defines the essential traits that cryptographic primitives must implement. These traits ensure a consistent interface for various operations:Kem: For Key Encapsulation Mechanisms.Signature: For Digital Signature schemes.SymmetricCipher: For symmetric encryption algorithms, including builder patterns forEncryptOperationandDecryptOperation.Serialize: For objects that can be serialized to and from byte arrays.- Marker Traits:
BlockCipher,StreamCipher,AuthenticatedCipher,KeyDerivationFunction,HashAlgorithmto categorize algorithms and define their core properties (like block size, tag size, etc.).
-
Error Handling (
dcrypt_docs/api/error/README.md): Provides a unified error handling system:Error(enum): The primary error type for all dcrypt operations, with variants for common cryptographic failures (e.g.,InvalidKey,InvalidSignature,DecryptionFailed,InvalidLength).Result<T>: A type alias forcore::result::Result<T, api::Error>.ResultExt(trait): Extension methods forResulttypes to easily add context or wrap errors.SecureErrorHandling(trait): For handling errors in constant-time operations, integrating withErrorRegistry.ErrorRegistry: A global (or thread-local) mechanism to record errors occurring within constant-time code paths without immediate branching.validate(module): Utility functions for common input validations (e.g., length checks, parameter conditions).
-
Types (
dcrypt_docs/api/types.rs): Defines fundamental, security-conscious data types:SecretBytes<const N: usize>: A fixed-size array for sensitive data, guaranteeing zeroization on drop and providing constant-time equality.SecretVec: A variable-length vector for sensitive data, also with zeroization on drop.Key: A wrapper for cryptographic key data, ensuring zeroization.PublicKey: A wrapper for public key data.Ciphertext: A wrapper for ciphertext data.- These types often implement
AsRef<[u8]>,AsMut<[u8]>,Zeroize,Serialize, and sometimesPartialEq(with constant-time comparison for secret types).
Design Philosophy
- Consistency: Provides a uniform way to interact with different cryptographic algorithms.
- Type Safety: Leverages Rust's type system to prevent common errors, such as using a key with an incompatible algorithm or providing data of incorrect length.
- Ergonomics: Aims for an API that is easy to use correctly and hard to misuse. Builder patterns for operations like encryption and decryption enhance this.
- Security by Default: Secure practices, like zeroization of sensitive data and constant-time comparisons, are built into the core types and traits where appropriate.
no_stdCompatibility: Designed to be usable inno_stdenvironments, with features like heap allocations (alloc) being optional.
How It Fits in dcrypt
The api crate serves as the contract between the users of the dcrypt library and the underlying algorithm implementations (primarily found in dcrypt-algorithms). Higher-level crates like dcrypt-symmetric, dcrypt-kem, and dcrypt-sign implement the traits defined in api to expose their functionalities.
Example: Using the SymmetricCipher Trait
A typical AEAD cipher in dcrypt-algorithms or dcrypt-symmetric would implement api::SymmetricCipher and api::AuthenticatedCipher.
use ;
use SecretBytes; // Assuming Nonce type from api::types or algorithms::types
use Nonce; // Example, actual Nonce would be defined
use ;
use Zeroize;
// Hypothetical AEAD Cipher struct
// Implementing the operation traits (simplified)
// ... (EncryptOperation methods) ...
// ... (DecryptOperation similarly) ...
// fn main() {
// let mut rng = rand::rngs::OsRng;
// let key = MyAeadCipher::generate_key(&mut rng).unwrap();
// let cipher = MyAeadCipher { key_material: SecretBytes::from_slice(key.as_ref()).unwrap() };
// let nonce = MyAeadCipher::generate_nonce(&mut rng).unwrap();
// let ciphertext = cipher.encrypt()
// .with_nonce(&nonce)
// .encrypt(b"hello")
// .unwrap();
// // ...
// }
This structure allows users to work with a consistent set of traits and types, regardless of the specific cryptographic algorithm being used, promoting safer and more maintainable cryptographic code.