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:
+17
-32
@@ -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)]
|
||||
|
||||
Reference in New Issue
Block a user