eciesrs
Elliptic Curve Integrated Encryption Scheme for secp256k1/x25519 in Rust, based on pure-Rust secp256k1/x25519 implementation.
ECIES functionalities are built upon AES-256-GCM/XChaCha20-Poly1305 and HKDF-SHA256.
This is the Rust version of eciespy.
This library can be compiled to the WASM target at your option, see WASM compatibility.
Quick Start
no_std is enabled by default. You can enable std with std feature.
= { = "0.2", = ["std"]}
use ;
const MSG: &str = "helloworld🌍";
let = generate_keypair;
let = ;
let = ;
let msg = MSG.as_bytes;
assert_eq!;
Optional x25519 Support
You can choose to use x25519 (key exchange function on curve25519) instead of secp256k1:
= { = "0.2", = false, = ["x25519"]}
Optional pure Rust AES backend
You can choose to use OpenSSL implementation or pure Rust implementation of AES-256-GCM:
= { = "0.2", = false, = ["pure"]}
Due to some performance problem, OpenSSL is the default backend.
Pure Rust implementation is sometimes useful, such as building on WASM:
If you select the pure Rust backend on modern x86 CPUs, consider building with
RUSTFLAGS="-Ctarget-cpu=sandybridge -Ctarget-feature=+aes,+sse2,+sse4.1,+ssse3"
It can speed up AES encryption/decryption. This would be no longer necessary when aes-gcm supports automatic CPU detection.
On ARM CPUs, consider building with
RUSTFLAGS="--cfg aes_armv8" # Rust 1.61+
WASM compatibility
It's also possible to build to the wasm32-unknown-unknown target (or wasm32-wasip2) with the pure Rust backend. Check out this repo for more details.
Configuration
You can enable 12 bytes nonce by aes-12bytes-nonce feature on OpenSSL or pure Rust AES backend.
= { = "0.2", = ["aes-12bytes-nonce"]} # it also works with "pure"
You can also enable a pure Rust XChaCha20-Poly1305 backend.
= { = "0.2", = false, = ["xchacha20"]}
Secp256k1-specific configuration
Other behaviors can be configured by global static variable:
On is_ephemeral_key_compressed: true, the payload would be like: 33 Bytes + AES instead of 65 Bytes + AES.
On is_hkdf_key_compressed: true, the hkdf key would be derived from ephemeral public key (compressed) + shared public key (compressed) instead of ephemeral public key (uncompressed) + shared public key (uncompressed).
use ;
update_config;
For compatibility, make sure different applications share the same configuration. Normally configuration is only updated once on initialization, if not, beware of race condition.
Security
Why AES-256-GCM and HKDF-SHA256
AEAD scheme like AES-256-GCM should be your first option for symmetric ciphers, with unique IVs in each encryption.
For key derivation functions on shared points between two asymmetric keys, HKDFs are proven to be more secure than simple hash functions like SHA256.
Why XChaCha20-Poly1305 instead of AES-256-GCM
XChaCha20-Poly1305 is a competitive alternative to AES-256-GCM because it's fast and constant-time without hardware acceleration (resistant to cache-timing attacks). It also has longer nonce length to alleviate the risk of birthday attacks when nonces are generated randomly.
Cross-language compatibility
All functionalities are mutually checked among different languages: Python, Rust, JavaScript and Golang.
Security audit
Following dependencies are audited:
Benchmark
On MacBook Pro Mid 2015 (15-inch, 2.8 GHz Quad-Core Intel Core i7) on July 19, 2023.
AES backend (OpenSSL)
)
)
)
)
)
)
AES backend (Pure Rust)
)
)
)
)
)
)
XChaCha20 backend
)
)
)
)
)
)
)
Changelog
See CHANGELOG.md.