Updating to draft-krawczyk-cfrg-opaque-06, reworking envelope construction and removing AEAD (#14)

Updating to draft-krawczyk-cfrg-opaque-06, reworking envelope construction and removing AEAD
This commit is contained in:
Kevin Lewi
2020-07-02 12:24:53 -07:00
committed by GitHub
parent 4a638b8a22
commit 6d02c72aae
11 changed files with 340 additions and 571 deletions
+17 -32
View File
@@ -5,14 +5,13 @@
//! An implementation of the OPAQUE asymmetric password authentication key exchange protocol
//!
//! Note: This implementation is in sync with [draft-krawczyk-cfrg-opaque-05](https://tools.ietf.org/html/draft-krawczyk-cfrg-opaque-05),
//! Note: This implementation is in sync with [draft-krawczyk-cfrg-opaque-06](https://tools.ietf.org/html/draft-krawczyk-cfrg-opaque-06),
//! but this specification is subject to change, until the final version published by the IETF.
//!
//! # Overview
//!
//! OPAQUE is a protocol between a client and a server. They must first agree on a collection of primitives
//! to be kept consistent throughout protocol execution. These include:
//! * an authenticated encryption scheme,
//! * a finite cyclic group along with a point representation,
//! * a keypair type, and
//! * a slow hashing function.
@@ -22,7 +21,6 @@
//! use opaque_ke::ciphersuite::CipherSuite;
//! struct Default;
//! impl CipherSuite for Default {
//! type Aead = chacha20poly1305::ChaCha20Poly1305;
//! type Group = curve25519_dalek::ristretto::RistrettoPoint;
//! type KeyFormat = opaque_ke::keypair::X25519KeyPair;
//! type SlowHash = opaque_ke::slow_hash::NoOpHash;
@@ -43,7 +41,6 @@
//! # use opaque_ke::ciphersuite::CipherSuite;
//! # struct Default;
//! # impl CipherSuite for Default {
//! # type Aead = chacha20poly1305::ChaCha20Poly1305;
//! # type Group = curve25519_dalek::ristretto::RistrettoPoint;
//! # type KeyFormat = opaque_ke::keypair::X25519KeyPair;
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
@@ -75,7 +72,6 @@
//! # use opaque_ke::ciphersuite::CipherSuite;
//! # struct Default;
//! # impl CipherSuite for Default {
//! # type Aead = chacha20poly1305::ChaCha20Poly1305;
//! # type Group = curve25519_dalek::ristretto::RistrettoPoint;
//! # type KeyFormat = opaque_ke::keypair::X25519KeyPair;
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
@@ -104,7 +100,6 @@
//! # use opaque_ke::ciphersuite::CipherSuite;
//! # struct Default;
//! # impl CipherSuite for Default {
//! # type Aead = chacha20poly1305::ChaCha20Poly1305;
//! # type Group = curve25519_dalek::ristretto::RistrettoPoint;
//! # type KeyFormat = opaque_ke::keypair::X25519KeyPair;
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
@@ -125,7 +120,7 @@
//!
//! In the third step (client registration finish), the client takes as input the `r2` message from the server, along
//! with the server's static public key `server_kp.public()`, and uses `client_state` from the first step to run
//! `finish` and produce a message `r3` along with the key derivation key `kd_key_registration`:
//! `finish` and produce a message `r3` along with the export key `export_key_registration`:
//! ```
//! # use opaque_ke::{
//! # errors::ProtocolError,
@@ -136,7 +131,6 @@
//! # use opaque_ke::ciphersuite::CipherSuite;
//! # struct Default;
//! # impl CipherSuite for Default {
//! # type Aead = chacha20poly1305::ChaCha20Poly1305;
//! # type Group = curve25519_dalek::ristretto::RistrettoPoint;
//! # type KeyFormat = opaque_ke::keypair::X25519KeyPair;
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
@@ -151,11 +145,11 @@
//! # let mut server_rng = OsRng;
//! let (r2, server_state) = ServerRegistration::<Default>::start(r1, &mut server_rng)?;
//! # let server_kp = Default::generate_random_keypair(&mut server_rng)?;
//! let (r3, kd_key_registration) =
//! let (r3, export_key_registration) =
//! client_state.finish(r2, server_kp.public(), &mut client_rng)?;
//! # Ok::<(), ProtocolError>(())
//! ```
//! `r3` is sent to the server, and the client can optionally use `kd_key_registration` for applications that choose to
//! `r3` is sent to the server, and the client can optionally use `export_key_registration` for applications that choose to
//! process user information beyond the OPAQUE functionality (e.g., additional secrets or credentials).
//!
//! In the fourth step of registration, the server takes as input the `r3` message from the client and uses
@@ -170,7 +164,6 @@
//! # use opaque_ke::ciphersuite::CipherSuite;
//! # struct Default;
//! # impl CipherSuite for Default {
//! # type Aead = chacha20poly1305::ChaCha20Poly1305;
//! # type Group = curve25519_dalek::ristretto::RistrettoPoint;
//! # type KeyFormat = opaque_ke::keypair::X25519KeyPair;
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
@@ -185,7 +178,7 @@
//! # let mut server_rng = OsRng;
//! let (r2, server_state) = ServerRegistration::<Default>::start(r1, &mut server_rng)?;
//! # let server_kp = Default::generate_random_keypair(&mut server_rng)?;
//! # let (r3, kd_key_registration) = client_state.finish(r2, server_kp.public(), &mut client_rng)?;
//! # let (r3, export_key_registration) = client_state.finish(r2, server_kp.public(), &mut client_rng)?;
//! let password_file = server_state.finish(r3)?;
//! # Ok::<(), ProtocolError>(())
//! ```
@@ -212,7 +205,6 @@
//! # use opaque_ke::ciphersuite::CipherSuite;
//! # struct Default;
//! # impl CipherSuite for Default {
//! # type Aead = chacha20poly1305::ChaCha20Poly1305;
//! # type Group = curve25519_dalek::ristretto::RistrettoPoint;
//! # type KeyFormat = opaque_ke::keypair::X25519KeyPair;
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
@@ -241,7 +233,6 @@
//! # use opaque_ke::ciphersuite::CipherSuite;
//! # struct Default;
//! # impl CipherSuite for Default {
//! # type Aead = chacha20poly1305::ChaCha20Poly1305;
//! # type Group = curve25519_dalek::ristretto::RistrettoPoint;
//! # type KeyFormat = opaque_ke::keypair::X25519KeyPair;
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
@@ -256,7 +247,7 @@
//! # let mut server_rng = OsRng;
//! let (r2, server_state) = ServerRegistration::<Default>::start(r1, &mut server_rng)?;
//! # let server_kp = Default::generate_random_keypair(&mut server_rng)?;
//! # let (r3, kd_key_registration) = client_state.finish(r2, server_kp.public(), &mut client_rng)?;
//! # let (r3, export_key_registration) = client_state.finish(r2, server_kp.public(), &mut client_rng)?;
//! # let password_file_bytes = server_state.finish(r3)?.to_bytes();
//! # let (l1, client_state) = ClientLogin::<Default>::start(
//! # b"password",
@@ -274,7 +265,7 @@
//!
//! In the third step (client login finish), the client takes as input the `l2` message from the server, along with the
//! server's static public key `server_kp.public()`, and uses `client_state` from the first step to run `finish` and produce
//! a message `l3`, the shared secret `client_shared_secret`, and the key derivation key `kd_key_login`:
//! a message `l3`, the shared secret `client_shared_secret`, and the export key `export_key_login`:
//! ```
//! # use opaque_ke::{
//! # errors::ProtocolError,
@@ -285,7 +276,6 @@
//! # use opaque_ke::ciphersuite::CipherSuite;
//! # struct Default;
//! # impl CipherSuite for Default {
//! # type Aead = chacha20poly1305::ChaCha20Poly1305;
//! # type Group = curve25519_dalek::ristretto::RistrettoPoint;
//! # type KeyFormat = opaque_ke::keypair::X25519KeyPair;
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
@@ -300,7 +290,7 @@
//! # let mut server_rng = OsRng;
//! let (r2, server_state) = ServerRegistration::<Default>::start(r1, &mut server_rng)?;
//! # let server_kp = Default::generate_random_keypair(&mut server_rng)?;
//! # let (r3, kd_key_registration) = client_state.finish(r2, server_kp.public(), &mut client_rng)?;
//! # let (r3, export_key_registration) = client_state.finish(r2, server_kp.public(), &mut client_rng)?;
//! # let password_file_bytes = server_state.finish(r3)?.to_bytes();
//! # let (l1, client_state) = ClientLogin::<Default>::start(
//! # b"password",
@@ -314,20 +304,20 @@
//! # )?;
//! # let (l2, server_state) =
//! # ServerLogin::start(password_file, &server_kp.private(), l1, &mut server_rng)?;
//! let (l3, client_shared_secret, kd_key_login) = client_state.finish(
//! let (l3, client_shared_secret, export_key_login) = client_state.finish(
//! l2,
//! &server_kp.public(),
//! &mut client_rng,
//! )?;
//! assert_eq!(kd_key_registration, kd_key_login);
//! assert_eq!(export_key_registration, export_key_login);
//! # Ok::<(), ProtocolError>(())
//! ```
//! Note that if the client supplies a tuple (password, pepper, server public key) that does not match the tuple
//! used to create the password file, then at this point the `finish` algorithm outputs the error `InvalidLoginError`.
//!
//! If `finish` completes successfully, then `l3` is sent to the server, and (similarly to registration) the client
//! can use `kd_key_login` for applications that can take advantage of the fact that this key is identical to
//! `kd_key_registration`.
//! can use `export_key_login` for applications that can take advantage of the fact that this key is identical to
//! `export_key_registration`.
//!
//! In the fourth step of login, the server takes as input the `l3` message from the client and uses `server_state` from
//! the second step to run `finish`:
@@ -341,7 +331,6 @@
//! # use opaque_ke::ciphersuite::CipherSuite;
//! # struct Default;
//! # impl CipherSuite for Default {
//! # type Aead = chacha20poly1305::ChaCha20Poly1305;
//! # type Group = curve25519_dalek::ristretto::RistrettoPoint;
//! # type KeyFormat = opaque_ke::keypair::X25519KeyPair;
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
@@ -356,7 +345,7 @@
//! # let mut server_rng = OsRng;
//! let (r2, server_state) = ServerRegistration::<Default>::start(r1, &mut server_rng)?;
//! # let server_kp = Default::generate_random_keypair(&mut server_rng)?;
//! # let (r3, kd_key) = client_state.finish(r2, server_kp.public(), &mut client_rng)?;
//! # let (r3, export_key) = client_state.finish(r2, server_kp.public(), &mut client_rng)?;
//! # let password_file_bytes = server_state.finish(r3)?.to_bytes();
//! # let (l1, client_state) = ClientLogin::<Default>::start(
//! # b"password",
@@ -370,7 +359,7 @@
//! # )?;
//! # let (l2, server_state) =
//! # ServerLogin::start(password_file, &server_kp.private(), l1, &mut server_rng)?;
//! # let (l3, client_shared_secret, kd_key) = client_state.finish(
//! # let (l3, client_shared_secret, export_key) = client_state.finish(
//! # l2,
//! # &server_kp.public(),
//! # &mut client_rng,
@@ -385,20 +374,16 @@
// Error types
pub mod errors;
// High-level API
pub mod opaque;
pub mod ciphersuite;
// Your choice of RKR encryption
mod rkr_encryption;
// Your choice of KE
mod envelope;
mod group;
mod key_exchange;
pub mod keypair;
// Low-level API contains OPRF stuff
mod oprf;
// Technical module for your choice of cyclic subgroup to
// do the oprf on
mod group;
pub mod slow_hash;
#[cfg(test)]