Expand description
Implementation of an integrated encryption scheme.
This module implements ECIES, the elliptic curve variant of the Integrated Encryption Scheme. This is a hybrid encryption scheme, using elliptic curve Diffie-Hellman for shared secret establishment and a symmetric algorithm for encryption of individual messages. It is instantiated with X25519 (Curve25519-based Diffie-Hellman), HMAC-SHA256 as the KDF and ChaCha20-Poly1305 for symmetric encryption.
ECIES allows a party (the initiator) to establish a communication channel toward another party (the recipient) given knowledge of only its public key. We assume that this key was obtained in a secure way. This implies that the initiator side is able to tell for sure whether there is an active MITM attack in progress once the channel is established.
On the other hand, the initiator’s key pair is ephemeral and generated anew for each new channel. This implies the initiator must send their ephemeral public key to the recipient unauthenticated so that the recipient can complete the channel establishment on its end. From this it follows that the recipient has no way of knowing who is contacting them, allowing for active MITM attacks on the recipient side.
In order to close this vector, an out-of-band confirmation is required to be
sent from the initiator device to the recipient device, after which the
channel is considered secure. The module provides the CheckCode
facility which can be used for this purpose.
Throughout this document, we use a naming convention which designates the device initiating an ECIES channel as device S, while the device on the other side (towards which the channel is opened) is designated device G.
§Examples
use vodozemac::ecies::{Ecies, InboundCreationResult, OutboundCreationResult};
let plaintext = b"It's a secret to everybody";
let alice = Ecies::new();
let bob = Ecies::new();
let OutboundCreationResult { ecies: mut alice, message } = alice
.establish_outbound_channel(bob.public_key(), plaintext)?;
let InboundCreationResult { mut ecies, message } = bob
.establish_inbound_channel(&message)
.expect("We should be able to create an inbound channel");
assert_eq!(
message, plaintext,
"The decrypted plaintext should match our initial plaintext"
);
// We now exchange the check code out-of-band and compare it.
if alice.check_code() != ecies.check_code() {
panic!("The check code must match; possible active MITM attack in progress");
}
let message = ecies.encrypt(b"Another plaintext");
let decrypted = alice.decrypt(&message)?;
assert_eq!(decrypted, b"Another plaintext");
Structs§
- A check code that can be used to confirm that two
EstablishedEcies
objects share the same secret. This is supposed to be shared out-of-band to protect against active MITM attacks. - An unestablished ECIES session.
- An established ECIES session.
- The result of an inbound ECIES channel establishment.
- The initial message, sent by the ECIES channel establisher.
- An encrypted message a
EstablishedEcies
channel has sent. - The result of an outbound ECIES channel establishment.
Enums§
- The Error type for the ECIES submodule.
- The error type for the ECIES message decoding failures.