Repository: facebook/opaque-ke (language: rust)

Issue:
Argon2 support
Right now only support for scrypt is implemented. Is Argon2 support in scope of this project?

I have an implementation ready that is based on https://crates.io/crates/argon2, I was wondering what I should PR against, `master` or `0.6`?


Discussion / hints:
Sure, feel free to PR against `master` (I will be merging them soon anyway)! scrypt support is gated behind a feature, and it seems like argon2 support should also be behind a feature as well.

Fix patch:
diff --git a/Cargo.lock b/Cargo.lock
index 10b95e9c..25e6bc3c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -17,6 +17,16 @@ version = "1.0.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
 
+[[package]]
+name = "argon2"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d60f5f3113c903294dc81dd8cf0012963ed4dda8bc931c864e12e175356ff98b"
+dependencies = [
+ "blake2",
+ "password-hash",
+]
+
 [[package]]
 name = "atty"
 version = "0.2.14"
@@ -40,6 +50,12 @@ version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
 
+[[package]]
+name = "base64ct"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5"
+
 [[package]]
 name = "bincode"
 version = "1.3.3"
@@ -70,6 +86,17 @@ version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
 
+[[package]]
+name = "blake2"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10a5720225ef5daecf08657f23791354e1685a8c91a4c60c7f3d3b2892f978f4"
+dependencies = [
+ "crypto-mac 0.8.0",
+ "digest",
+ "opaque-debug",
+]
+
 [[package]]
 name = "block-buffer"
 version = "0.9.0"
@@ -273,6 +300,16 @@ dependencies = [
  "lazy_static",
 ]
 
+[[package]]
+name = "crypto-mac"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
+dependencies = [
+ "generic-array",
+ "subtle",
+]
+
 [[package]]
 name = "crypto-mac"
 version = "0.10.0"
@@ -449,7 +486,7 @@ version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15"
 dependencies = [
- "crypto-mac",
+ "crypto-mac 0.10.0",
  "digest",
 ]
 
@@ -570,6 +607,7 @@ name = "opaque-ke"
 version = "0.5.1-pre.1"
 dependencies = [
  "anyhow",
+ "argon2",
  "base64",
  "bincode",
  "chacha20poly1305",
@@ -586,7 +624,6 @@ dependencies = [
  "proptest",
  "rand 0.8.3",
  "rustyline",
- "scrypt",
  "serde",
  "serde_json",
  "sha2",
@@ -596,12 +633,14 @@ dependencies = [
 ]
 
 [[package]]
-name = "pbkdf2"
-version = "0.6.0"
+name = "password-hash"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3b8c0d71734018084da0c0354193a5edfb81b20d2d57a92c5b154aefc554a4a"
+checksum = "c1a5d4e9c205d2c1ae73b84aab6240e98218c0e72e63b50422cfb2d1ca952282"
 dependencies = [
- "crypto-mac",
+ "base64ct",
+ "rand_core 0.6.2",
+ "subtle",
 ]
 
 [[package]]
@@ -905,15 +944,6 @@ version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
 
-[[package]]
-name = "salsa20"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "399f290ffc409596022fce5ea5d4138184be4784f2b28c62c59f0d8389059a15"
-dependencies = [
- "cipher",
-]
-
 [[package]]
 name = "same-file"
 version = "1.0.6"
@@ -929,22 +959,6 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 
-[[package]]
-name = "scrypt"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8da492dab03f925d977776a0b7233d7b934d6dc2b94faead48928e2e9bacedb9"
-dependencies = [
- "base64",
- "hmac",
- "pbkdf2",
- "rand 0.7.3",
- "rand_core 0.5.1",
- "salsa20",
- "sha2",
- "subtle",
-]
-
 [[package]]
 name = "semver"
 version = "0.9.0"
diff --git a/Cargo.toml b/Cargo.toml
index 5a5b17a6..e228ce64 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,13 +11,14 @@ readme = "README.md"
 
 [features]
 default = ["u64_backend", "serialize"]
-slow-hash = ["scrypt"]
+slow-hash = ["argon2"]
 bench = []
 u64_backend = ["curve25519-dalek/u64_backend"]
 u32_backend = ["curve25519-dalek/u32_backend"]
 serialize = ["serde", "base64"]
 
 [dependencies]
+argon2 = { version = "0.2", optional = true }
 base64 = { version = "0.13", optional = true }
 curve25519-dalek = { version = "3.0.0", default-features = false, features = ["std"] }
 digest = "0.9.0"
@@ -27,7 +28,6 @@ generic-bytes = { version = "0.1.0" }
 hkdf = "0.10.0"
 hmac = "0.10.1"
 rand = "0.8"
-scrypt = { version = "0.5.0", optional = true }
 serde = { version = "1", optional = true }
 subtle = { version = "2.3.0", default-features = false }
 thiserror = "1.0.22"
diff --git a/src/lib.rs b/src/lib.rs
index 0d162a1a..18a7b390 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -32,7 +32,7 @@
 //! for a working example of a simple password-based login using OPAQUE.
 //!
 //! 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`,
+//! that the tests execute quickly. A real application should use an actual slow hashing function, such as `Argon2`,
 //! which can be enabled through the `slow-hash` feature. See more details in the [features](#features) section.
 //!
 //! ## Setup
@@ -700,7 +700,7 @@
 //!
 //! # Features
 //!
-//! - The `slow-hash` feature, when enabled, introduces a dependency on `scrypt` and implements the `SlowHash` trait for `scrypt`
+//! - The `slow-hash` feature, when enabled, introduces a dependency on `argon2` and implements the `SlowHash` trait for `Argon2`
 //! with a set of default parameters. In general, secure instantiations should choose to invoke a memory-hard password
 //! hashing function when the client's password is expected to have low entropy, instead of relying on [slow_hash::NoOpHash]
 //! as done in the above example. The more computationally intensive the `SlowHash` function is, the more resistant the server's
diff --git a/src/slow_hash.rs b/src/slow_hash.rs
index 1e0c726e..5596406c 100644
--- a/src/slow_hash.rs
+++ b/src/slow_hash.rs
@@ -31,22 +31,20 @@ impl<D: Hash> SlowHash<D> for NoOpHash {
 }
 
 #[cfg(feature = "slow-hash")]
-const DEFAULT_SCRYPT_LOG_N: u8 = 15u8;
-#[cfg(feature = "slow-hash")]
-const DEFAULT_SCRYPT_R: u32 = 8u32;
-#[cfg(feature = "slow-hash")]
-const DEFAULT_SCRYPT_P: u32 = 1u32;
-
-#[cfg(feature = "slow-hash")]
-impl<D: Hash> SlowHash<D> for scrypt::ScryptParams {
+impl<D: Hash> SlowHash<D> for argon2::Argon2<'_> {
     fn hash(
         input: GenericArray<u8, <D as Digest>::OutputSize>,
     ) -> Result<Vec<u8>, InternalPakeError> {
-        let params =
-            scrypt::ScryptParams::new(DEFAULT_SCRYPT_LOG_N, DEFAULT_SCRYPT_R, DEFAULT_SCRYPT_P)
-                .map_err(|_| InternalPakeError::SlowHashError)?;
+        let params = argon2::Argon2::default();
         let mut output = vec![0u8; <D as Digest>::OutputSize::to_usize()];
-        scrypt::scrypt(&input, &[], &params, &mut output)
+        params
+            .hash_password_into(
+                argon2::Algorithm::Argon2id,
+                &input,
+                &[0; argon2::MIN_SALT_LENGTH],
+                &[],
+                &mut output,
+            )
             .map_err(|_| InternalPakeError::SlowHashError)?;
         Ok(output)
     }


Test patch: