Module vodozemac::ecies

source ·
Expand description

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§

Enums§

  • The Error type for the ECIES submodule.
  • The error type for the ECIES message decoding failures.