Adding password hashing functionality

This commit is contained in:
Kevin Lewi
2020-06-08 21:02:01 -07:00
parent 88696763cc
commit 57e152b028
7 changed files with 256 additions and 45 deletions
+60 -23
View File
@@ -18,8 +18,12 @@
//! use chacha20poly1305::ChaCha20Poly1305;
//! use curve25519_dalek::ristretto::RistrettoPoint;
//! use opaque_ke::keypair::X25519KeyPair;
//! use opaque_ke::slow_hash::NoOpHash;
//! ```
//!
//! Note that our choice of slow hashing function in this example, `NoOpHash`, is selected only to ensure
//! that the tests execute quickly. A real application should use an actual slow hashing function, such as `Scrypt`.
//!
//! This implementation is in sync with [draft-krawczyk-cfrg-opaque-05](https://tools.ietf.org/html/draft-krawczyk-cfrg-opaque-05),
//! with a concrete instantiation of the authenticated key exchange protocol using 3DH. In the future, we plan to
//! add support for other KE protocols as well.
@@ -48,8 +52,12 @@
//! In the first step (client registration start), the client chooses a registration password and an optional "pepper", and
//! runs `ClientRegistration::start` to produce a message `r1`:
//! ```
//! # use opaque_ke::{opaque::{ClientRegistration, ServerRegistration}, keypair::{KeyPair, X25519KeyPair, SizedBytes}};
//! # use opaque_ke::errors::ProtocolError;
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # slow_hash::NoOpHash,
//! # };
//! # use curve25519_dalek::ristretto::RistrettoPoint;
//! # use chacha20poly1305::ChaCha20Poly1305;
//! use rand_core::{OsRng, RngCore};
@@ -67,8 +75,12 @@
//! In the second step (server registration start), the server takes as input the `r1` message from the client and runs
//! `ServerRegistration::start` to produce `r2`:
//! ```
//! # use opaque_ke::{opaque::{ClientRegistration, ServerRegistration}, keypair::{KeyPair, X25519KeyPair, SizedBytes}};
//! # use opaque_ke::errors::ProtocolError;
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # slow_hash::NoOpHash,
//! # };
//! # use curve25519_dalek::ristretto::RistrettoPoint;
//! # use chacha20poly1305::ChaCha20Poly1305;
//! # use rand_core::{OsRng, RngCore};
@@ -93,8 +105,12 @@
//! 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`:
//! ```
//! # use opaque_ke::{opaque::{ClientRegistration, ServerRegistration}, keypair::{KeyPair, X25519KeyPair, SizedBytes}};
//! # use opaque_ke::errors::ProtocolError;
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # slow_hash::NoOpHash,
//! # };
//! # use curve25519_dalek::ristretto::RistrettoPoint;
//! # use chacha20poly1305::ChaCha20Poly1305;
//! # use rand_core::{OsRng, RngCore};
@@ -112,7 +128,7 @@
//! # )?;
//! # let server_kp = X25519KeyPair::generate_random(&mut server_rng)?;
//! let (r3, kd_key_registration) =
//! client_state.finish::<_, X25519KeyPair>(r2, server_kp.public(), &mut client_rng)?;
//! client_state.finish::<_, X25519KeyPair, NoOpHash>(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
@@ -121,8 +137,12 @@
//! In the fourth step of registration, the server takes as input the `r3` message from the client and uses
//! `server_state` from the second step to run `finish` and produce `password_file`:
//! ```
//! # use opaque_ke::{opaque::{ClientRegistration, ServerRegistration}, keypair::{KeyPair, X25519KeyPair, SizedBytes}};
//! # use opaque_ke::errors::ProtocolError;
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # slow_hash::NoOpHash,
//! # };
//! # use curve25519_dalek::ristretto::RistrettoPoint;
//! # use chacha20poly1305::ChaCha20Poly1305;
//! # use rand_core::{OsRng, RngCore};
@@ -140,7 +160,7 @@
//! # )?;
//! # let server_kp = X25519KeyPair::generate_random(&mut server_rng)?;
//! # let (r3, kd_key_registration) =
//! # client_state.finish::<_, X25519KeyPair>(r2, server_kp.public(), &mut client_rng)?;
//! # client_state.finish::<_, X25519KeyPair, NoOpHash>(r2, server_kp.public(), &mut client_rng)?;
//! let password_file = server_state.finish(r3)?;
//! # Ok::<(), ProtocolError>(())
//! ```
@@ -158,8 +178,12 @@
//! In the first step (client login start), the client chooses a registration password and an optional "pepper", and runs
//! `ClientLogin::start` to produce a message `l1`:
//! ```
//! # use opaque_ke::{opaque::{ClientRegistration, ServerRegistration, ClientLogin, ServerLogin, LoginThirdMessage}, keypair::{KeyPair, X25519KeyPair, SizedBytes}};
//! # use opaque_ke::errors::ProtocolError;
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration, ClientLogin, ServerLogin, LoginThirdMessage},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # slow_hash::NoOpHash,
//! # };
//! # use curve25519_dalek::ristretto::RistrettoPoint;
//! # use chacha20poly1305::ChaCha20Poly1305;
//! # use rand_core::{OsRng, RngCore};
@@ -177,8 +201,12 @@
//! private key `server_kp.private()`, along with a serialized version of the password file, `password_file_bytes`, and
//! runs `ServerLogin::start` to produce `l2`:
//! ```
//! # use opaque_ke::{opaque::{ClientRegistration, ServerRegistration, ClientLogin, ServerLogin, LoginThirdMessage}, keypair::{KeyPair, X25519KeyPair, SizedBytes}};
//! # use opaque_ke::errors::ProtocolError;
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration, ClientLogin, ServerLogin, LoginThirdMessage},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # slow_hash::NoOpHash,
//! # };
//! # use curve25519_dalek::ristretto::RistrettoPoint;
//! # use chacha20poly1305::ChaCha20Poly1305;
//! # use rand_core::{OsRng, RngCore};
@@ -196,7 +224,7 @@
//! # )?;
//! # let server_kp = X25519KeyPair::generate_random(&mut server_rng)?;
//! # let (r3, kd_key_registration) =
//! # client_state.finish::<_, X25519KeyPair>(r2, server_kp.public(), &mut client_rng)?;
//! # client_state.finish::<_, X25519KeyPair, NoOpHash>(r2, server_kp.public(), &mut client_rng)?;
//! # let password_file_bytes = server_state.finish(r3)?.to_bytes();
//! # let (l1, client_state) = ClientLogin::<ChaCha20Poly1305, RistrettoPoint, X25519KeyPair>::start(
//! # b"password",
@@ -219,8 +247,12 @@
//! 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`:
//! ```
//! # use opaque_ke::{opaque::{ClientRegistration, ServerRegistration, ClientLogin, ServerLogin, LoginThirdMessage}, keypair::{KeyPair, X25519KeyPair, SizedBytes}};
//! # use opaque_ke::errors::ProtocolError;
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration, ClientLogin, ServerLogin, LoginThirdMessage},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # slow_hash::NoOpHash,
//! # };
//! # use curve25519_dalek::ristretto::RistrettoPoint;
//! # use chacha20poly1305::ChaCha20Poly1305;
//! # use rand_core::{OsRng, RngCore};
@@ -238,7 +270,7 @@
//! # )?;
//! # let server_kp = X25519KeyPair::generate_random(&mut server_rng)?;
//! # let (r3, kd_key_registration) =
//! # client_state.finish::<_, X25519KeyPair>(r2, server_kp.public(), &mut client_rng)?;
//! # client_state.finish::<_, X25519KeyPair, NoOpHash>(r2, server_kp.public(), &mut client_rng)?;
//! # let password_file_bytes = server_state.finish(r3)?.to_bytes();
//! # let (l1, client_state) = ClientLogin::<ChaCha20Poly1305, RistrettoPoint, X25519KeyPair>::start(
//! # b"password",
@@ -252,7 +284,7 @@
//! # )?;
//! # 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, kd_key_login) = client_state.finish::<_, NoOpHash>(
//! l2,
//! &server_kp.public(),
//! &mut client_rng,
@@ -270,8 +302,12 @@
//! 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`:
//! ```
//! # use opaque_ke::{opaque::{ClientRegistration, ServerRegistration, ClientLogin, ServerLogin, LoginThirdMessage}, keypair::{KeyPair, X25519KeyPair, SizedBytes}};
//! # use opaque_ke::errors::ProtocolError;
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration, ClientLogin, ServerLogin, LoginThirdMessage},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # slow_hash::NoOpHash,
//! # };
//! # use curve25519_dalek::ristretto::RistrettoPoint;
//! # use chacha20poly1305::ChaCha20Poly1305;
//! # use rand_core::{OsRng, RngCore};
@@ -289,7 +325,7 @@
//! # )?;
//! # let server_kp = X25519KeyPair::generate_random(&mut server_rng)?;
//! # let (r3, kd_key) =
//! # client_state.finish::<_, X25519KeyPair>(r2, server_kp.public(), &mut client_rng)?;
//! # client_state.finish::<_, X25519KeyPair, NoOpHash>(r2, server_kp.public(), &mut client_rng)?;
//! # let password_file_bytes = server_state.finish(r3)?.to_bytes();
//! # let (l1, client_state) = ClientLogin::<ChaCha20Poly1305, RistrettoPoint, X25519KeyPair>::start(
//! # b"password",
@@ -303,7 +339,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, kd_key) = client_state.finish::<_, NoOpHash>(
//! # l2,
//! # &server_kp.public(),
//! # &mut client_rng,
@@ -331,6 +367,7 @@ mod oprf;
// Technical module for your choice of cyclic subgroup to
// do the oprf on
mod group;
pub mod slow_hash;
#[cfg(test)]
mod tests;