ECIES X25519
Elliptic Curve Integrated Encryption Scheme (ECIES) implemented in Rust using X25519, AES-256-GCM, and HKDF-SHA256.
Overview
This crate provides a straightforward implementation of ECIES, a hybrid encryption scheme allowing encryption of data using a recipient's X25519 public key. The data can only be decrypted by the corresponding private key holder.
It uses the following cryptographic primitives:
- Key Agreement: X25519 (via
x25519-dalek) - Key Derivation Function (KDF): HKDF-SHA256 (via
hkdfandsha2) - Data Encryption: AES-256-GCM (Authenticated Encryption via
aes-gcm)
The implementation aims for simplicity and security, using well-vetted underlying cryptographic libraries and providing efficient key parsing for standard formats.
Features
- ECIES encryption and decryption using X25519 / AES-256-GCM / HKDF-SHA256.
- Generation of X25519 key pairs in OpenSSL-compatible DER formats (PKCS#8 v1, SubjectPublicKeyInfo).
- Parsing of X25519 and Ed25519 keys from PEM and DER formats.
- Ed25519 keys are automatically converted to their corresponding X25519 representation.
- Requires
std(due to dependencies likepem).
Installation
Add the crate to your Cargo.toml:
[]
= "0.2.0" # Use the latest version from crates.io
= "0.9" # Required for RNG traits (ensure compatibility)
# Add an RNG implementation like rand, OsRng, or rand_chacha
= "0.9" # Example using the rand crate
Or run:
Usage Example
use ;
use OsRng; // Cryptographically secure random number generator
use ; // Required traits for the RNG
Key Concepts
- Hybrid Encryption: Combines asymmetric (X25519) and symmetric (AES-256-GCM) cryptography.
- Ephemeral Key: A temporary X25519 keypair is generated by the sender for each encryption. Only the public part is sent with the ciphertext. This provides forward secrecy.
- ECDH: Elliptic Curve Diffie-Hellman is used between the sender's ephemeral private key and the recipient's static public key (for encryption) or the sender's ephemeral public key and the recipient's static private key (for decryption) to establish a shared secret.
- HKDF: The ECDH shared secret, concatenated with the involved public keys (
[ephemeral_pk | shared_secret]for encryption,[recipient_pk | shared_secret]for decryption), and a fixed context string ("ecies_x25519"), is fed into HKDF-SHA256 to derive a robust 32-byte AES key. - AES-GCM: The derived key is used with AES-256-GCM to encrypt the plaintext. AES-GCM provides both confidentiality (encryption) and integrity/authenticity (via a 16-byte MAC tag). It requires a unique 12-byte nonce (IV) for each encryption with the same key, which is generated randomly by this library.
- Ciphertext Format: The output of
encryptis the concatenation:[ephemeral_public_key (32 bytes) || nonce (12 bytes) || AES ciphertext || auth_tag (16 bytes)].
API Reference
The public API is primarily exposed from the crate root (ecies_25519::).
ECIES Operations:
EciesX25519::new() -> Self: Creates a new ECIES instance.EciesX25519::encrypt(...) -> Result<Vec<u8>, Error>: Encrypts data forreceiver_pubusingrng.EciesX25519::decrypt(...) -> Result<Vec<u8>, Error>: Decrypts data usingreceiver_sk.
Key Handling:
generate_keypair<T>(csprng: &mut T) -> KeyPairDer: Generates a new X25519 key pair (DER encoded). RequiresRngCore + CryptoRng.parse_public_key(pem_or_der_bytes: &[u8]) -> Result<PublicKey, KeyParsingError>: Parses PEM/DER public key (X25519/Ed25519).parse_private_key(pem_or_der_bytes: &[u8]) -> Result<StaticSecret, KeyParsingError>: Parses PEM/DER private key (X25519/Ed25519).
Core Types:
PublicKey: (x25519_dalek::PublicKey) X25519 public key.StaticSecret: (x25519_dalek::StaticSecret) X25519 private key.KeyPairDer: Struct holding.public_der: Vec<u8>(SPKI) and.private_der: Vec<u8>(PKCS#8). Has.public_to_pem()and.private_to_pem()methods.Error: Enum for ECIESencrypt/decrypterrors.KeyParsingError: Enum for key parsing errors (re-exported fromparser).
Security Considerations
- RNG: Always use a cryptographically secure random number generator (CSPRNG) like
rand::rngs::OsRng. The security of the ephemeral keys and AES nonces depends critically on the RNG quality. - Private Key Security: The recipient's X25519 private key (
StaticSecret) must be kept confidential. - HKDF Info: This implementation uses a fixed info string (
"ecies_x25519"). For better domain separation in complex applications using the same keys for multiple purposes, consider modifying the library or using distinct keys. - Authenticated Encryption: AES-GCM provides authenticity. The
decryptfunction must be checked for errors. AnErr(Error::DecryptionFailed)indicates potential tampering or use of the wrong key. - Internal
unwrap(): Note that the current implementation ofEciesX25519::encryptusesunwrap()internally when parsing the generated ephemeral keys. While key generation should produce valid keys, this could theoretically panic if the underlyingparsermodule had a bug related to generation output. Robust applications might prefer generating/parsing keys separately and handling potential parsing errors explicitly before calling encryption/decryption methods.
Contributing
Contributions (bug reports, pull requests, feature suggestions) are welcome! Please open an issue to discuss significant changes before submitting a PR.
License
Licensed under the Mozilla Public License Version 2.0 (LICENSE or https://opensource.org/licenses/MPL-2.0).