diff --git a/Cargo.lock b/Cargo.lock index 1dc1e2b..bb82f8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,6 +19,7 @@ dependencies = [ "curve25519-dalek", "password-hash", "postcard", + "rand", "rand_core", "scrypt", "serde", @@ -56,11 +57,11 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "96eb4cdd6cf1b31d671e9efe75c5d1ec614776856cefbe109ca373554a6d514f" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -75,12 +76,24 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "chacha20" +version = "0.10.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3585020fc6766ef7ff5c58d69819dbca16a19008ae347bb5d3e4e145c495eb38" +dependencies = [ + "cfg-if", + "cpufeatures", + "rand_core", +] + [[package]] name = "cipher" -version = "0.4.4" +version = "0.5.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "155e4a260750fa4f7754649f049748aacc31db238a358d85fd721002f230f92f" dependencies = [ + "block-buffer", "crypto-common", "inout", ] @@ -94,6 +107,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "const-oid" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dabb6555f92fb9ee4140454eb5dcd14c7960e1225c6d1a6cc361f032947713e" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -109,21 +128,44 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.2.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "919bd05924682a5480aec713596b9e2aabed3a0a6022fab6847f85a99e5f190a" dependencies = [ - "generic-array", - "typenum", + "hybrid-array", ] [[package]] name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +version = "5.0.0-pre.1" +source = "git+https://github.com/dalek-cryptography/curve25519-dalek?branch=rand_core%2Fv0.10-rc#07744fd3fc2671c5f24d9436b3aa01118afca745" dependencies = [ "cfg-if", "cpufeatures", @@ -150,40 +192,38 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.7" +version = "0.11.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "ea390c940e465846d64775e55e3115d5dc934acb953de6f6e6360bc232fe2bf7" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] [[package]] -name = "fiat-crypto" -version = "0.2.9" +name = "either" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] -name = "generic-array" -version = "0.14.7" +name = "fiat-crypto" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "getrandom" -version = "0.2.16" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "wasi", + "r-efi", + "wasip2", ] [[package]] @@ -223,29 +263,38 @@ checksum = "e712f64ec3850b98572bffac52e2c6f282b29fe6c5fa6d42334b30be438d95c1" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.13.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "cfbb4225acf2b5cc4e12d384672cd6d1f0cb980ff5859ffcf144db25b593a24d" dependencies = [ "hmac", ] [[package]] name = "hmac" -version = "0.12.1" +version = "0.13.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "f1c597ac7d6cc8143e30e83ef70915e7f883b18d8bec2e2b2bce47f5bbb06d57" dependencies = [ "digest", ] +[[package]] +name = "hybrid-array" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f471e0a81b2f90ffc0cb2f951ae04da57de8baa46fa99112b062a5173a5088d0" +dependencies = [ + "typenum", +] + [[package]] name = "inout" -version = "0.1.4" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "c7357b6e7aa75618c7864ebd0634b115a7218b0615f4cb1df33ac3eca23943d4" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -299,9 +348,9 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.5.0" +version = "0.6.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +checksum = "a7d47a2d1aee5a339aa6c740d9128211a8a3d2bdf06a13e01b3f8a0b5c49b9db" dependencies = [ "base64ct", "rand_core", @@ -310,9 +359,9 @@ dependencies = [ [[package]] name = "pbkdf2" -version = "0.12.2" +version = "0.13.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +checksum = "5f4c07efb9394d8d0057793c35483868c2b8102e287e9d2d4328da0da36bcb4d" dependencies = [ "digest", "hmac", @@ -329,15 +378,6 @@ dependencies = [ "serde", ] -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - [[package]] name = "proc-macro2" version = "1.0.103" @@ -356,34 +396,47 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "rand" -version = "0.8.5" +version = "0.10.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "9e7d245ced4538f0406b1579d3d4a6515a2ff1bdf20733492e2e4fc90a648769" dependencies = [ - "libc", - "rand_chacha", + "chacha20", + "getrandom", "rand_core", ] [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "rand_core" +version = "0.10.0-rc-2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "104a23e4e8b77312a823b6b5613edbac78397e2f34320bc7ac4277013ec4478e" + +[[package]] +name = "rayon" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ - "ppv-lite86", - "rand_core", + "either", + "rayon-core", ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "rayon-core" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ - "getrandom", + "crossbeam-deque", + "crossbeam-utils", ] [[package]] @@ -397,10 +450,11 @@ dependencies = [ [[package]] name = "salsa20" -version = "0.10.2" +version = "0.11.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +checksum = "06522a356e94a02a1f83d699a1d84dd2ba613fbb20b211153bd5a75de9ccdc92" dependencies = [ + "cfg-if", "cipher", ] @@ -412,12 +466,13 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scrypt" -version = "0.11.0" +version = "0.12.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" +checksum = "506c46bd50cae340ff3f2cfe8f08ee378a24e230a1221cbf9d570afe6b697212" dependencies = [ "password-hash", "pbkdf2", + "rayon", "salsa20", "sha2", ] @@ -469,9 +524,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.6" +version = "0.11.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "aa1ae819b9870cadc959a052363de870944a1646932d274a4e270f64bf79e5ef" dependencies = [ "cfg-if", "cpufeatures", @@ -480,9 +535,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.9" +version = "0.11.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "19d43dc0354d88b791216bb5c1bfbb60c0814460cc653ae0ebd71f286d0bd927" dependencies = [ "cfg-if", "cpufeatures", @@ -498,6 +553,7 @@ dependencies = [ "hex", "hkdf", "num-bigint", + "rand", "rand_core", "sha2", ] @@ -516,7 +572,6 @@ name = "srp" version = "0.7.0-pre" dependencies = [ "digest", - "generic-array", "hex-literal", "lazy_static", "num-bigint", @@ -583,36 +638,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "zerocopy" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "zerocopy-derive", + "wit-bindgen", ] [[package]] -name = "zerocopy-derive" -version = "0.8.27" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "zeroize" diff --git a/Cargo.toml b/Cargo.toml index 7f261cf..01e70bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,7 @@ members = [ [profile.dev] opt-level = 2 + +[patch.crates-io.curve25519-dalek] +git = "https://github.com/dalek-cryptography/curve25519-dalek" +branch = "rand_core/v0.10-rc" diff --git a/aucpace/Cargo.toml b/aucpace/Cargo.toml index 8071312..6566036 100644 --- a/aucpace/Cargo.toml +++ b/aucpace/Cargo.toml @@ -15,41 +15,34 @@ edition = "2024" rust-version = "1.85" [dependencies] -curve25519-dalek = { version = "4", default-features = false, features = [ - "digest", - "rand_core", -] } -password-hash = { version = "0.5", default-features = false, features = [ - "rand_core", -] } -rand_core = { version = "0.6", default-features = false } -serde = { version = "1.0.184", default-features = false, optional = true, features = [ - "derive", -] } -serde-byte-array = { version = "0.1", optional = true } +curve25519-dalek = { version = "5.0.0-pre.1", default-features = false, features = ["digest", "rand_core"] } +password-hash = { version = "0.6.0-rc.2", default-features = false, features = ["rand_core"] } +rand_core = { version = "0.10.0-rc.2", default-features = false } subtle = { version = "2.4", default-features = false } -scrypt = { version = "0.11", default-features = false, optional = true, features = [ - "simple", -] } -sha2 = { version = "0.10", default-features = false, optional = true } + +# optional dependencies +rand = { version = "0.10.0-rc.1", optional = true } +serde = { version = "1.0.184", default-features = false, optional = true, features = ["derive"] } +serde-byte-array = { version = "0.1", optional = true } +scrypt = { version = "0.12.0-rc.3", default-features = false, optional = true, features = ["simple"] } +sha2 = { version = "0.11.0-rc.3", default-features = false, optional = true } [dev-dependencies] bincode = "1" -curve25519-dalek = { version = "4", features = ["digest", "rand_core"] } -password-hash = { version = "0.5", features = ["rand_core"] } +curve25519-dalek = { version = "5.0.0-pre.1", features = ["digest", "rand_core"] } +password-hash = { version = "0.6.0-rc.2", features = ["rand_core"] } postcard = "1" -rand_core = "0.6" -scrypt = { version = "0.11", features = ["simple"] } -sha2 = "0.10" +scrypt = { version = "0.12.0-rc.3", features = ["simple"] } +sha2 = "0.11.0-rc.3" [features] -default = ["scrypt", "sha2", "getrandom"] +default = ["rand", "scrypt", "sha2"] alloc = [] + partial_augmentation = [] +serde = ["dep:serde", "serde-byte-array", "curve25519-dalek/serde"] strong_aucpace = [] zeroize = ["curve25519-dalek/zeroize"] -serde = ["dep:serde", "serde-byte-array", "curve25519-dalek/serde"] -getrandom = ["rand_core/getrandom"] [[example]] name = "key_agreement" diff --git a/aucpace/examples/key_agreement.rs b/aucpace/examples/key_agreement.rs index 735f437..c63025b 100644 --- a/aucpace/examples/key_agreement.rs +++ b/aucpace/examples/key_agreement.rs @@ -1,7 +1,8 @@ -use aucpace::{Client, ClientMessage, Database, Result, Server, ServerMessage}; +use aucpace::{ + Client, ClientMessage, Database, OsRng, Result, Server, ServerMessage, rand_core::TryRngCore, +}; use curve25519_dalek::ristretto::RistrettoPoint; use password_hash::{ParamsString, SaltString}; -use rand_core::OsRng; use scrypt::{Params, Scrypt}; use sha2::Sha512; use sha2::digest::Output; @@ -37,8 +38,11 @@ fn main() -> Result<()> { // the server socket address to bind to let server_socket: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 25519); + // random number generator from OS + let mut rng = OsRng.unwrap_err(); + // register the user in the database - let mut base_client = Client::new(OsRng); + let mut base_client = Client::new(rng); let mut database: SingleUserDatabase = Default::default(); let params = Params::recommended(); @@ -66,7 +70,7 @@ fn main() -> Result<()> { // buffer for receiving packets let mut buf = [0u8; 1024]; - let mut base_server = Server::new(OsRng); + let mut base_server = Server::new(rng); // ===== SSID Establishment ===== let (server, message) = base_server.begin(); @@ -84,7 +88,7 @@ fn main() -> Result<()> { // ===== Augmentation Layer ===== client_message = recv!(stream, buf); let (server, message) = if let ClientMessage::Username(username) = client_message { - server.generate_client_info(username, &database, OsRng) + server.generate_client_info(username, &database, rng) } else { panic!("Received invalid client message {:?}", client_message); }; @@ -179,7 +183,7 @@ fn main() -> Result<()> { let r = pbkdf_params.get_str("r").unwrap().parse().unwrap(); let p = pbkdf_params.get_str("p").unwrap().parse().unwrap(); - Params::new(log_n, r, p, scrypt::Params::RECOMMENDED_LEN).unwrap() + Params::new(log_n, r, p).unwrap() }; client.generate_cpace_alloc(x_pub, &salt, params, Scrypt)? } else { @@ -188,7 +192,7 @@ fn main() -> Result<()> { // ===== CPace substep ===== let ci = TcpChannelIdentifier::new(stream.local_addr().unwrap(), server_socket).unwrap(); - let (client, message) = client.generate_public_key(ci, &mut OsRng); + let (client, message) = client.generate_public_key(ci, &mut rng); let bytes_sent = send!(stream, message); CLIENT_BYTES_SENT.fetch_add(bytes_sent, Ordering::SeqCst); println!( @@ -231,7 +235,7 @@ fn main() -> Result<()> { let server_key: Output = server_thread.join().unwrap().unwrap(); assert_eq!(client_key, server_key); println!( - "Negotiation finished, both parties arrived at a key of: {:X}", + "Negotiation finished, both parties arrived at a key of: {:?}", client_key ); println!( diff --git a/aucpace/examples/key_agreement_no_std.rs b/aucpace/examples/key_agreement_no_std.rs index e930c53..5235d5f 100644 --- a/aucpace/examples/key_agreement_no_std.rs +++ b/aucpace/examples/key_agreement_no_std.rs @@ -4,10 +4,11 @@ extern crate std; use std::{println, time::Instant}; -use aucpace::{Client, ClientMessage, Database, Result, Server, ServerMessage}; +use aucpace::{ + Client, ClientMessage, Database, OsRng, Result, Server, ServerMessage, rand_core::TryRngCore, +}; use curve25519_dalek::ristretto::RistrettoPoint; use password_hash::{ParamsString, SaltString}; -use rand_core::OsRng; use scrypt::{Params, Scrypt}; /// function like macro to wrap sending data over a tcp stream, returns the number of bytes sent @@ -29,9 +30,12 @@ fn main() -> Result<()> { const USERNAME: &[u8] = b"adira.tal"; const PASSWORD: &[u8] = b"4d1rA_aND-Gr4Y_aRe_tH3-b3sT <3"; + // get system random number generator + let mut rng = OsRng.unwrap_err(); + // register the user in the database - let mut base_server = Server::new(OsRng); - let mut base_client = Client::new(OsRng); + let mut base_server = Server::new(rng); + let mut base_client = Client::new(rng); let mut database: SingleUserDatabase<100> = Default::default(); let start = Instant::now(); @@ -111,7 +115,7 @@ fn main() -> Result<()> { // server receives the username then looks up client_message = recv!(client_buf); let (server, message) = if let ClientMessage::Username(username) = client_message { - server.generate_client_info(username, &database, OsRng) + server.generate_client_info(username, &database, rng) } else { panic!("Received invalid client message {:?}", client_message); }; @@ -137,7 +141,7 @@ fn main() -> Result<()> { let r = pbkdf_params.get_str("r").unwrap().parse().unwrap(); let p = pbkdf_params.get_str("p").unwrap().parse().unwrap(); - Params::new(log_n, r, p, scrypt::Params::RECOMMENDED_LEN).unwrap() + Params::new(log_n, r, p).unwrap() }; client.generate_cpace::<&SaltString, 100>(x_pub, &salt, params, Scrypt)? } else { @@ -156,7 +160,7 @@ fn main() -> Result<()> { ); // now generate the client's public key and send it - let (client, message) = client.generate_public_key(CI, &mut OsRng); + let (client, message) = client.generate_public_key(CI, &mut rng); let bytes_sent = send!(client_buf, message); client_bytes_sent += bytes_sent; println!( @@ -223,7 +227,7 @@ fn main() -> Result<()> { // assert that both threads arrived at the same key assert_eq!(client_key, server_key); println!( - "Negotiation finished, both parties arrived at a key of: {:X}", + "Negotiation finished, both parties arrived at a key of: {:?}", client_key ); diff --git a/aucpace/examples/key_agreement_partial_aug.rs b/aucpace/examples/key_agreement_partial_aug.rs index 08bf9fd..330c536 100644 --- a/aucpace/examples/key_agreement_partial_aug.rs +++ b/aucpace/examples/key_agreement_partial_aug.rs @@ -1,10 +1,11 @@ +use aucpace::rand_core::TryRngCore; use aucpace::{ - Client, ClientMessage, Database, Error, PartialAugDatabase, Result, Server, ServerMessage, + Client, ClientMessage, Database, Error, OsRng, PartialAugDatabase, Result, Server, + ServerMessage, }; use curve25519_dalek::ristretto::RistrettoPoint; use curve25519_dalek::scalar::Scalar; use password_hash::{ParamsString, SaltString}; -use rand_core::OsRng; use scrypt::{Params, Scrypt}; use sha2::Sha512; use sha2::digest::Output; @@ -40,9 +41,12 @@ fn main() -> Result<()> { // the server socket address to bind to let server_socket: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 25519); + // random number generator from OS + let mut rng = OsRng.unwrap_err(); + // register the user in the database - let mut base_client = Client::new(OsRng); - let mut base_server = Server::new(OsRng); + let mut base_client = Client::new(rng); + let mut base_server = Server::new(rng); let mut database: SingleUserDatabase = Default::default(); let params = Params::recommended(); @@ -92,7 +96,7 @@ fn main() -> Result<()> { client_message = recv!(stream, buf); let (server, message) = if let ClientMessage::Username(username) = client_message { // This is the only difference from the non-augmented protocol flow - server.generate_client_info_partial_aug(username, &database, OsRng) + server.generate_client_info_partial_aug(username, &database, rng) } else { panic!("Received invalid client message {:?}", client_message); }; @@ -187,7 +191,7 @@ fn main() -> Result<()> { let r = pbkdf_params.get_str("r").unwrap().parse().unwrap(); let p = pbkdf_params.get_str("p").unwrap().parse().unwrap(); - Params::new(log_n, r, p, scrypt::Params::RECOMMENDED_LEN).unwrap() + Params::new(log_n, r, p).unwrap() }; client.generate_cpace_alloc(x_pub, &salt, params, Scrypt)? } else { @@ -196,7 +200,7 @@ fn main() -> Result<()> { // ===== CPace substep ===== let ci = TcpChannelIdentifier::new(stream.local_addr().unwrap(), server_socket).unwrap(); - let (client, message) = client.generate_public_key(ci, &mut OsRng); + let (client, message) = client.generate_public_key(ci, &mut rng); let bytes_sent = send!(stream, message); CLIENT_BYTES_SENT.fetch_add(bytes_sent, Ordering::SeqCst); println!( @@ -239,7 +243,7 @@ fn main() -> Result<()> { let server_key: Output = server_thread.join().unwrap().unwrap(); assert_eq!(client_key, server_key); println!( - "Negotiation finished, both parties arrived at a key of: {:X}", + "Negotiation finished, both parties arrived at a key of: {:?}", client_key ); println!( diff --git a/aucpace/examples/key_agreement_strong.rs b/aucpace/examples/key_agreement_strong.rs index 1ae06ee..23a6d34 100644 --- a/aucpace/examples/key_agreement_strong.rs +++ b/aucpace/examples/key_agreement_strong.rs @@ -1,8 +1,10 @@ -use aucpace::{Client, ClientMessage, Result, Server, ServerMessage, StrongDatabase}; +use aucpace::{ + Client, ClientMessage, OsRng, Result, Server, ServerMessage, StrongDatabase, + rand_core::TryRngCore, +}; use curve25519_dalek::ristretto::RistrettoPoint; use curve25519_dalek::scalar::Scalar; use password_hash::ParamsString; -use rand_core::OsRng; use scrypt::{Params, Scrypt}; use sha2::Sha512; use sha2::digest::Output; @@ -38,8 +40,11 @@ fn main() -> Result<()> { // the server socket address to bind to let server_socket: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 25519); + // random number generator from OS + let mut rng = OsRng.unwrap_err(); + // register the user in the database - let mut base_client = Client::new(OsRng); + let mut base_client = Client::new(rng); let mut database: SingleUserDatabase = Default::default(); let params = Params::recommended(); @@ -67,7 +72,7 @@ fn main() -> Result<()> { // buffer for receiving packets let mut buf = [0u8; 1024]; - let mut base_server = Server::new(OsRng); + let mut base_server = Server::new(rng); // ===== SSID Establishment ===== let (server, message) = base_server.begin(); @@ -87,7 +92,7 @@ fn main() -> Result<()> { let (server, message) = if let ClientMessage::StrongUsername { username, blinded } = client_message { server - .generate_client_info_strong(username, blinded, &database, OsRng) + .generate_client_info_strong(username, blinded, &database, rng) .unwrap() } else { panic!("Received invalid client message {:?}", client_message); @@ -161,7 +166,7 @@ fn main() -> Result<()> { }; // ===== Augmentation Layer ===== - let (client, message) = client.start_augmentation_strong(USERNAME, PASSWORD, &mut OsRng); + let (client, message) = client.start_augmentation_strong(USERNAME, PASSWORD, &mut rng); let bytes_sent = send!(stream, message); CLIENT_BYTES_SENT.fetch_add(bytes_sent, Ordering::SeqCst); println!( @@ -183,7 +188,7 @@ fn main() -> Result<()> { let r = pbkdf_params.get_str("r").unwrap().parse().unwrap(); let p = pbkdf_params.get_str("p").unwrap().parse().unwrap(); - Params::new(log_n, r, p, scrypt::Params::RECOMMENDED_LEN).unwrap() + Params::new(log_n, r, p).unwrap() }; client.generate_cpace_alloc(x_pub, blinded_salt, params, Scrypt)? } else { @@ -192,7 +197,7 @@ fn main() -> Result<()> { // ===== CPace substep ===== let ci = TcpChannelIdentifier::new(stream.local_addr().unwrap(), server_socket).unwrap(); - let (client, message) = client.generate_public_key(ci, &mut OsRng); + let (client, message) = client.generate_public_key(ci, &mut rng); let bytes_sent = send!(stream, message); CLIENT_BYTES_SENT.fetch_add(bytes_sent, Ordering::SeqCst); println!( @@ -235,7 +240,7 @@ fn main() -> Result<()> { let server_key: Output = server_thread.join().unwrap().unwrap(); assert_eq!(client_key, server_key); println!( - "Negotiation finished, both parties arrived at a key of: {:X}", + "Negotiation finished, both parties arrived at a key of: {:?}", client_key ); println!( diff --git a/aucpace/src/client.rs b/aucpace/src/client.rs index 83f3707..81d9608 100644 --- a/aucpace/src/client.rs +++ b/aucpace/src/client.rs @@ -17,7 +17,7 @@ use curve25519_dalek::{ scalar::Scalar, }; use password_hash::{ParamsString, PasswordHash, PasswordHasher, Salt, SaltString}; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use subtle::ConstantTimeEq; #[cfg(feature = "strong_aucpace")] @@ -37,7 +37,7 @@ pub struct AuCPaceClient where D: Digest + Default, H: PasswordHasher, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { rng: CSPRNG, d: PhantomData, @@ -48,7 +48,7 @@ impl AuCPaceClient where D: Digest + Default, H: PasswordHasher, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { /// Create new server pub const fn new(rng: CSPRNG) -> Self { @@ -127,7 +127,7 @@ where where P: AsRef<[u8]>, { - let salt_string = SaltString::generate(&mut self.rng); + let salt_string = SaltString::from_rng(&mut self.rng); // compute the verifier W let pw_hash = hash_password::<&[u8], P, &SaltString, H, BUFSIZ>( @@ -235,8 +235,7 @@ where where P: AsRef<[u8]>, { - // adapted from SaltString::generate, which we cannot use due to curve25519 versions of rand_core - let salt_string = SaltString::generate(&mut self.rng); + let salt_string = SaltString::from_rng(&mut self.rng); // compute the verifier W let pw_hash = @@ -358,7 +357,7 @@ where { fn new(rng: &mut CSPRNG) -> Self where - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { Self { nonce: generate_nonce(rng), @@ -448,7 +447,7 @@ where ClientMessage<'a, K1>, ) where - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { // compute the blinding value and blind the hash of the username and password // ensuring that it is non-zero as required by `invert` @@ -790,7 +789,7 @@ where ) where CI: AsRef<[u8]>, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { let (priv_key, pub_key) = generate_keypair::(rng, self.ssid, self.prs, channel_identifier); @@ -1046,16 +1045,18 @@ mod tests { #[allow(unused)] use super::*; + #[cfg(all(feature = "rand", feature = "sha2"))] + use crate::{OsRng, rand_core::TryRngCore}; + #[test] - #[cfg(all(feature = "alloc", feature = "getrandom", feature = "scrypt"))] + #[cfg(all(feature = "alloc", feature = "rand", feature = "scrypt"))] fn test_hash_password_no_std_and_alloc_agree() { - use rand_core::{OsRng, RngCore}; use scrypt::{Params, Scrypt}; let username = "worf@starship.enterprise"; let password = "data_x_worf_4ever_<3"; let mut bytes = [0u8; Salt::RECOMMENDED_LENGTH]; - OsRng.fill_bytes(&mut bytes); + OsRng.try_fill_bytes(&mut bytes).unwrap(); let salt = SaltString::encode_b64(&bytes).expect("Salt length invariant broken."); // These are weak parameters, do not use them // they are used here to make the test run faster @@ -1071,12 +1072,11 @@ mod tests { } #[test] - #[cfg(all(feature = "getrandom", feature = "sha2"))] + #[cfg(all(feature = "rand", feature = "sha2"))] fn test_client_doesnt_accept_insecure_ssid() { use crate::Client; - use rand_core::OsRng; - let mut client = Client::new(OsRng); + let mut client = Client::new(OsRng.unwrap_err()); let res = client.begin_prestablished_ssid("bad ssid"); assert!(matches!(res, Err(Error::InsecureSsid))); } diff --git a/aucpace/src/database.rs b/aucpace/src/database.rs index 7a3038b..597d3f6 100644 --- a/aucpace/src/database.rs +++ b/aucpace/src/database.rs @@ -83,7 +83,7 @@ pub trait PartialAugDatabase { /// # Return: /// - Ok(()): success - the keypair was stored correctly /// - Err([`Error::UserNotRegistered`](crate::Error::UserNotRegistered)): failure - - /// `username` is not registered and thus we cannot store a keypair for them + /// `username` is not registered and thus we cannot store a keypair for them /// fn store_long_term_keypair( &mut self, @@ -125,12 +125,12 @@ pub trait StrongDatabase { /// # Arguments: /// - `username`: The name of the user who is storing a verifier /// - `uad`: Optional - User Attached Data - "represents application data associated with - /// this specific user account, e.g. specifying the granted authorization level - /// on the server." + /// this specific user account, e.g. specifying the granted authorization level + /// on the server." /// - `verifier`: The password verifier for the given user /// - `secret exponent`: the value of `q` stored for the given user /// - `params`: The parameters used when hashing the password into the verifier - - /// It is called sigma in the protocol definition + /// It is called sigma in the protocol definition fn store_verifier_strong( &mut self, username: &[u8], diff --git a/aucpace/src/lib.rs b/aucpace/src/lib.rs index fd41829..615b7ca 100644 --- a/aucpace/src/lib.rs +++ b/aucpace/src/lib.rs @@ -102,16 +102,25 @@ pub use self::{ server::{AuCPaceServer, ServerMessage}, }; +pub use rand_core; + #[cfg(feature = "partial_augmentation")] pub use self::database::PartialAugDatabase; #[cfg(feature = "strong_aucpace")] pub use self::database::StrongDatabase; +#[cfg(feature = "rand")] +pub use rand::rngs::OsRng; + +/// Infallible version of `OsRng` which panics on error +#[cfg(feature = "rand")] +pub type UnwrapOsRng = rand_core::UnwrapErr; + /// Default Server instantiation with `SHA512`, `OsRng` and a nonce size of 16 bytes -#[cfg(all(feature = "sha2", feature = "getrandom"))] -pub type Server = AuCPaceServer; +#[cfg(all(feature = "sha2", feature = "rand"))] +pub type Server = AuCPaceServer; /// Default Client instantiation with `SHA512`, `Scrypt`, `OsRng` and a nonce size of 16 bytes -#[cfg(all(feature = "scrypt", feature = "sha2", feature = "getrandom"))] -pub type Client = AuCPaceClient; +#[cfg(all(feature = "scrypt", feature = "sha2", feature = "rand"))] +pub type Client = AuCPaceClient; diff --git a/aucpace/src/server.rs b/aucpace/src/server.rs index c421d92..63505a9 100644 --- a/aucpace/src/server.rs +++ b/aucpace/src/server.rs @@ -14,7 +14,7 @@ use curve25519_dalek::{ scalar::Scalar, }; use password_hash::{ParamsString, SaltString}; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use subtle::ConstantTimeEq; #[cfg(feature = "partial_augmentation")] @@ -34,7 +34,7 @@ use serde::{Deserialize, Serialize}; struct ServerSecret(u64); impl ServerSecret { - fn new(rng: &mut CSPRNG) -> Self { + fn new(rng: &mut CSPRNG) -> Self { Self(rng.next_u64()) } } @@ -43,7 +43,7 @@ impl ServerSecret { pub struct AuCPaceServer where D: Digest + Default, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { /// The CSPRNG used to generate random values where needed rng: CSPRNG, @@ -57,7 +57,7 @@ where impl AuCPaceServer where D: Digest + Default, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { /// Create a new server pub fn new(mut rng: CSPRNG) -> Self { @@ -145,7 +145,7 @@ where { fn new(secret: ServerSecret, rng: &mut CSPRNG) -> Self where - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { Self { secret, @@ -210,7 +210,7 @@ where where U: AsRef<[u8]>, DB: Database, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { let (x, x_pub) = generate_server_keypair(&mut rng); @@ -234,7 +234,7 @@ where /// # Arguments: /// - `username`: the client's username /// - `database`: the password verifier database to retrieve the client's information from - /// This is a `PartialAugDatabase` so we can lookup the server's long term keypair. + /// This is a `PartialAugDatabase` so we can lookup the server's long term keypair. /// /// # Return: /// ([`next_step`](AuCPaceServerCPaceSubstep), [`message`](ServerMessage::AugmentationInfo)) @@ -255,7 +255,7 @@ where U: AsRef<[u8]>, DB: Database + PartialAugDatabase, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { let user = username.as_ref(); let (prs, message) = if let Some((x, x_pub)) = database.lookup_long_term_keypair(user) { @@ -283,7 +283,7 @@ where /// - `username`: the client's username /// - `blinded`: the client's blinded point `U` /// - `database`: the password verifier database to retrieve the client's information from - /// This is a `PartialAugDatabase` so we can lookup the server's long term keypair. + /// This is a `PartialAugDatabase` so we can lookup the server's long term keypair. /// /// # Return: /// ([`next_step`](AuCPaceServerCPaceSubstep), [`message`](ServerMessage::AugmentationInfo)) @@ -304,7 +304,7 @@ where where U: AsRef<[u8]>, DB: StrongDatabase, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { let (x, x_pub) = generate_server_keypair(&mut rng); @@ -328,7 +328,7 @@ where /// - `username`: the client's username /// - `blinded`: the client's blinded point `U` /// - `database`: the password verifier database to retrieve the client's information from - /// This is a `PartialAugDatabase` so we can lookup the server's long term keypair. + /// This is a `PartialAugDatabase` so we can lookup the server's long term keypair. /// /// # Return: /// ([`next_step`](AuCPaceServerCPaceSubstep), [`message`](ServerMessage::AugmentationInfo)) @@ -350,7 +350,7 @@ where U: AsRef<[u8]>, DB: StrongDatabase + PartialAugDatabase, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { let user = username.as_ref(); let (prs, message) = if let Some((x, x_pub)) = database.lookup_long_term_keypair(user) { @@ -378,7 +378,7 @@ where ) -> ([u8; 32], ServerMessage<'static, K1>) where DB: Database, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { if let Some((w, salt, sigma)) = database.lookup_verifier(username.as_ref()) { let cofactor = Scalar::ONE; @@ -411,7 +411,7 @@ where ) -> Result<([u8; 32], ServerMessage<'static, K1>)> where DB: StrongDatabase, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { if let Some((w, q, sigma)) = database.lookup_verifier_strong(username.as_ref()) { let cofactor = Scalar::ONE; @@ -442,7 +442,7 @@ where rng: &mut CSPRNG, ) -> ([u8; 32], ServerMessage<'static, K1>) where - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { let prs = { let mut tmp = [0u8; 32]; @@ -483,7 +483,7 @@ where rng: &mut CSPRNG, ) -> Result<([u8; 32], ServerMessage<'static, K1>)> where - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { let prs = { let mut tmp = [0u8; 32]; @@ -519,7 +519,7 @@ where pub struct AuCPaceServerCPaceSubstep where D: Digest + Default, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { ssid: Output, prs: [u8; 32], @@ -529,7 +529,7 @@ where impl AuCPaceServerCPaceSubstep where D: Digest + Default, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { const fn new(ssid: Output, prs: [u8; 32], rng: CSPRNG) -> Self { Self { ssid, prs, rng } @@ -735,12 +735,14 @@ mod tests { #[allow(unused)] use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT; + #[cfg(all(feature = "sha2", feature = "rand"))] + use crate::{OsRng, rand_core::TryRngCore}; + #[test] - #[cfg(all(feature = "sha2", feature = "getrandom"))] + #[cfg(all(feature = "sha2", feature = "rand"))] fn test_server_doesnt_accept_insecure_ssid() { use crate::Server; - use rand_core::OsRng; - let mut server = Server::new(OsRng); + let mut server = Server::new(OsRng.unwrap_err()); let res = server.begin_prestablished_ssid("bad ssid"); assert!(matches!(res, Err(Error::InsecureSsid))); } @@ -833,11 +835,10 @@ mod tests { } #[test] - #[cfg(all(feature = "sha2", feature = "getrandom", feature = "strong_aucpace"))] + #[cfg(all(feature = "sha2", feature = "rand", feature = "strong_aucpace"))] fn test_server_doesnt_accept_invalid_uq() { use crate::utils::H0; use curve25519_dalek::traits::Identity; - use rand_core::OsRng; let ssid = H0::().finalize(); let aug_server: AuCPaceServerAugLayer = @@ -846,7 +847,7 @@ mod tests { b"bobbyyyy", RistrettoPoint::identity(), &FakeDatabase(), - OsRng, + OsRng.unwrap_err(), ); if let Err(e) = res { @@ -857,11 +858,10 @@ mod tests { } #[test] - #[cfg(all(feature = "sha2", feature = "getrandom", feature = "strong_aucpace"))] + #[cfg(all(feature = "sha2", feature = "rand", feature = "strong_aucpace"))] fn test_server_doesnt_accept_invalid_uq_partial() { use crate::utils::H0; use curve25519_dalek::traits::Identity; - use rand_core::OsRng; let ssid = H0::().finalize(); let aug_server: AuCPaceServerAugLayer = @@ -870,7 +870,7 @@ mod tests { b"bobbyyyy", RistrettoPoint::identity(), &FakeDatabase(), - OsRng, + OsRng.unwrap_err(), ); if let Err(e) = res { diff --git a/aucpace/src/utils.rs b/aucpace/src/utils.rs index 0819227..ba44e1d 100644 --- a/aucpace/src/utils.rs +++ b/aucpace/src/utils.rs @@ -7,7 +7,7 @@ use curve25519_dalek::{ scalar::Scalar, }; use password_hash::PasswordHash; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; #[allow(non_snake_case)] #[inline] @@ -38,7 +38,7 @@ create_h_impl!(H5, 5); #[inline] pub fn generate_nonce(rng: &mut CSPRNG) -> [u8; N] where - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { let mut nonce = [0; N]; rng.fill_bytes(&mut nonce); @@ -64,7 +64,7 @@ pub fn generate_keypair( ) -> (Scalar, RistrettoPoint) where D: Digest + Default, - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, CI: AsRef<[u8]>, { let mut hasher: D = H1(); @@ -156,7 +156,7 @@ pub fn scalar_from_hash(pw_hash: &PasswordHash<'_>) -> Result { #[inline] pub fn generate_server_keypair(rng: &mut CSPRNG) -> (Scalar, RistrettoPoint) where - CSPRNG: CryptoRngCore, + CSPRNG: CryptoRng, { // for ristretto255 the cofactor is 1, for normal curve25519 it is 8 // this will need to be provided by a group trait in the future diff --git a/aucpace/tests/test_key_agreement.rs b/aucpace/tests/test_key_agreement.rs index 1520c84..453a246 100644 --- a/aucpace/tests/test_key_agreement.rs +++ b/aucpace/tests/test_key_agreement.rs @@ -1,9 +1,11 @@ -use aucpace::client::{AuCPaceClientPreAug, AuCPaceClientRecvServerKey}; -use aucpace::server::{AuCPaceServerAugLayer, AuCPaceServerRecvClientKey}; -use aucpace::{Client, ClientMessage, Database, Result, Server, ServerMessage}; +use aucpace::{ + Client, ClientMessage, Database, OsRng, Result, Server, ServerMessage, + client::{AuCPaceClientPreAug, AuCPaceClientRecvServerKey}, + rand_core::TryRngCore, + server::{AuCPaceServerAugLayer, AuCPaceServerRecvClientKey}, +}; use curve25519_dalek::RistrettoPoint; use password_hash::{ParamsString, SaltString}; -use rand_core::OsRng; use scrypt::{Params, Scrypt}; use sha2::Sha512; @@ -230,9 +232,11 @@ fn test_key_agreement_prestablished_ssid_implicit_auth() -> Result<()> { /// Perform the initialisation step for all tests fn init() -> Result<(Client, Server, SingleUserDatabase)> { + let rng = OsRng.unwrap_err(); + // Create the client, server and database - let base_server = Server::new(OsRng); - let mut base_client = Client::new(OsRng); + let base_server = Server::new(rng); + let mut base_client = Client::new(rng); let mut database: SingleUserDatabase = Default::default(); // register a user in the database @@ -262,13 +266,15 @@ fn test_core( ClientMessage<'_, K1>, ServerMessage<'_, K1>, )> { + let mut rng = OsRng.unwrap_err(); + // ===== Augmentation Layer ===== // client initiates the augmentation phase let (client, client_message) = client.start_augmentation(USERNAME, PASSWORD); // server generates augmentation info from client's username let (server, server_message) = if let ClientMessage::Username(username) = client_message { - server.generate_client_info(username, database, OsRng) + server.generate_client_info(username, database, rng) } else { panic!("Received invalid client message {:?}", client_message); }; @@ -287,7 +293,7 @@ fn test_core( let r = pbkdf_params.get_str("r").unwrap().parse().unwrap(); let p = pbkdf_params.get_str("p").unwrap().parse().unwrap(); - Params::new(log_n, r, p, Params::RECOMMENDED_LEN).unwrap() + Params::new(log_n, r, p).unwrap() }; client.generate_cpace_alloc(x_pub, &salt, params, Scrypt)? } else { @@ -296,7 +302,7 @@ fn test_core( // ===== CPace substep ===== let (server, server_message) = server.generate_public_key(CI); - let (client, client_message) = client.generate_public_key(CI, &mut OsRng); + let (client, client_message) = client.generate_public_key(CI, &mut rng); Ok((client, server, client_message, server_message)) } diff --git a/aucpace/tests/test_key_agreement_partial_aug.rs b/aucpace/tests/test_key_agreement_partial_aug.rs index ceb42f0..29d1be7 100644 --- a/aucpace/tests/test_key_agreement_partial_aug.rs +++ b/aucpace/tests/test_key_agreement_partial_aug.rs @@ -1,3 +1,4 @@ +use aucpace::OsRng; use aucpace::client::{AuCPaceClientPreAug, AuCPaceClientRecvServerKey}; use aucpace::server::{AuCPaceServerAugLayer, AuCPaceServerRecvClientKey}; use aucpace::{ @@ -5,7 +6,7 @@ use aucpace::{ }; use curve25519_dalek::{RistrettoPoint, Scalar}; use password_hash::{ParamsString, SaltString}; -use rand_core::OsRng; +use rand_core::TryRngCore; use scrypt::{Params, Scrypt}; use sha2::Sha512; @@ -263,9 +264,11 @@ fn test_key_agreement_prestablished_ssid_implicit_auth() -> Result<()> { /// Perform the initialisation step for all tests fn init() -> Result<(Client, Server, SingleUserDatabase)> { + let rng = OsRng.unwrap_err(); + // Create the client, server and database - let mut base_server = Server::new(OsRng); - let mut base_client = Client::new(OsRng); + let mut base_server = Server::new(rng); + let mut base_client = Client::new(rng); let mut database: SingleUserDatabase = Default::default(); // register a user in the database @@ -297,13 +300,15 @@ fn test_core( ClientMessage<'_, K1>, ServerMessage<'_, K1>, )> { + let mut rng = OsRng.unwrap_err(); + // ===== Augmentation Layer ===== // client initiates the augmentation phase let (client, client_message) = client.start_augmentation(USERNAME, PASSWORD); // server generates augmentation info from client's username let (server, server_message) = if let ClientMessage::Username(username) = client_message { - server.generate_client_info_partial_aug(username, database, OsRng) + server.generate_client_info_partial_aug(username, database, rng) } else { panic!("Received invalid client message {:?}", client_message); }; @@ -322,7 +327,7 @@ fn test_core( let r = pbkdf_params.get_str("r").unwrap().parse().unwrap(); let p = pbkdf_params.get_str("p").unwrap().parse().unwrap(); - Params::new(log_n, r, p, Params::RECOMMENDED_LEN).unwrap() + Params::new(log_n, r, p).unwrap() }; client.generate_cpace_alloc(x_pub, &salt, params, Scrypt)? } else { @@ -331,7 +336,7 @@ fn test_core( // ===== CPace substep ===== let (server, server_message) = server.generate_public_key(CI); - let (client, client_message) = client.generate_public_key(CI, &mut OsRng); + let (client, client_message) = client.generate_public_key(CI, &mut rng); Ok((client, server, client_message, server_message)) } diff --git a/aucpace/tests/test_key_agreement_strong.rs b/aucpace/tests/test_key_agreement_strong.rs index 65f2591..002450b 100644 --- a/aucpace/tests/test_key_agreement_strong.rs +++ b/aucpace/tests/test_key_agreement_strong.rs @@ -1,9 +1,11 @@ -use aucpace::client::{AuCPaceClientPreAug, AuCPaceClientRecvServerKey}; -use aucpace::server::{AuCPaceServerAugLayer, AuCPaceServerRecvClientKey}; -use aucpace::{Client, ClientMessage, Result, Server, ServerMessage, StrongDatabase}; +use aucpace::{ + Client, ClientMessage, OsRng, Result, Server, ServerMessage, StrongDatabase, + client::{AuCPaceClientPreAug, AuCPaceClientRecvServerKey}, + rand_core::TryRngCore, + server::{AuCPaceServerAugLayer, AuCPaceServerRecvClientKey}, +}; use curve25519_dalek::{RistrettoPoint, Scalar}; use password_hash::ParamsString; -use rand_core::OsRng; use scrypt::{Params, Scrypt}; use sha2::Sha512; @@ -231,9 +233,11 @@ fn test_key_agreement_prestablished_ssid_implicit_auth() -> Result<()> { /// Perform the initialisation step for all tests fn init() -> Result<(Client, Server, SingleUserDatabase)> { + let rng = OsRng.unwrap_err(); + // Create the client, server and database - let base_server = Server::new(OsRng); - let mut base_client = Client::new(OsRng); + let base_server = Server::new(rng); + let mut base_client = Client::new(rng); let mut database: SingleUserDatabase = Default::default(); // register a user in the database @@ -263,14 +267,16 @@ fn test_core( ClientMessage<'_, K1>, ServerMessage<'_, K1>, )> { + let mut rng = OsRng.unwrap_err(); + // ===== Augmentation Layer ===== // client initiates the augmentation phase - let (client, client_message) = client.start_augmentation_strong(USERNAME, PASSWORD, &mut OsRng); + let (client, client_message) = client.start_augmentation_strong(USERNAME, PASSWORD, &mut rng); // server generates augmentation info from client's username let (server, server_message) = if let ClientMessage::StrongUsername { username, blinded } = client_message { - server.generate_client_info_strong(username, blinded, database, OsRng)? + server.generate_client_info_strong(username, blinded, database, rng)? } else { panic!("Received invalid client message {:?}", client_message); }; @@ -289,7 +295,7 @@ fn test_core( let r = pbkdf_params.get_str("r").unwrap().parse().unwrap(); let p = pbkdf_params.get_str("p").unwrap().parse().unwrap(); - Params::new(log_n, r, p, Params::RECOMMENDED_LEN).unwrap() + Params::new(log_n, r, p).unwrap() }; client.generate_cpace_alloc(x_pub, blinded_salt, params, Scrypt)? } else { @@ -298,7 +304,7 @@ fn test_core( // ===== CPace substep ===== let (server, server_message) = server.generate_public_key(CI); - let (client, client_message) = client.generate_public_key(CI, &mut OsRng); + let (client, client_message) = client.generate_public_key(CI, &mut rng); Ok((client, server, client_message, server_message)) } diff --git a/aucpace/tests/test_key_agreement_strong_partial_aug.rs b/aucpace/tests/test_key_agreement_strong_partial_aug.rs index 23901ba..fa25805 100644 --- a/aucpace/tests/test_key_agreement_strong_partial_aug.rs +++ b/aucpace/tests/test_key_agreement_strong_partial_aug.rs @@ -1,11 +1,12 @@ -use aucpace::client::{AuCPaceClientPreAug, AuCPaceClientRecvServerKey}; -use aucpace::server::{AuCPaceServerAugLayer, AuCPaceServerRecvClientKey}; use aucpace::{ - Client, ClientMessage, Error, PartialAugDatabase, Result, Server, ServerMessage, StrongDatabase, + Client, ClientMessage, Error, OsRng, PartialAugDatabase, Result, Server, ServerMessage, + StrongDatabase, + client::{AuCPaceClientPreAug, AuCPaceClientRecvServerKey}, + rand_core::TryRngCore, + server::{AuCPaceServerAugLayer, AuCPaceServerRecvClientKey}, }; use curve25519_dalek::{RistrettoPoint, Scalar}; use password_hash::ParamsString; -use rand_core::OsRng; use scrypt::{Params, Scrypt}; use sha2::Sha512; @@ -264,9 +265,11 @@ fn test_key_agreement_prestablished_ssid_implicit_auth() -> Result<()> { /// Perform the initialisation step for all tests fn init() -> Result<(Client, Server, SingleUserDatabase)> { + let rng = OsRng.unwrap_err(); + // Create the client, server and database - let mut base_server = Server::new(OsRng); - let mut base_client = Client::new(OsRng); + let mut base_server = Server::new(rng); + let mut base_client = Client::new(rng); let mut database: SingleUserDatabase = Default::default(); // register a user in the database @@ -298,14 +301,16 @@ fn test_core( ClientMessage<'_, K1>, ServerMessage<'_, K1>, )> { + let mut rng = OsRng.unwrap_err(); + // ===== Augmentation Layer ===== // client initiates the augmentation phase - let (client, client_message) = client.start_augmentation_strong(USERNAME, PASSWORD, &mut OsRng); + let (client, client_message) = client.start_augmentation_strong(USERNAME, PASSWORD, &mut rng); // server generates augmentation info from client's username let (server, server_message) = if let ClientMessage::StrongUsername { username, blinded } = client_message { - server.generate_client_info_partial_strong(username, blinded, database, OsRng)? + server.generate_client_info_partial_strong(username, blinded, database, rng)? } else { panic!("Received invalid client message {:?}", client_message); }; @@ -324,7 +329,7 @@ fn test_core( let r = pbkdf_params.get_str("r").unwrap().parse().unwrap(); let p = pbkdf_params.get_str("p").unwrap().parse().unwrap(); - Params::new(log_n, r, p, Params::RECOMMENDED_LEN).unwrap() + Params::new(log_n, r, p).unwrap() }; client.generate_cpace_alloc(x_pub, blinded_salt, params, Scrypt)? } else { @@ -333,7 +338,7 @@ fn test_core( // ===== CPace substep ===== let (server, server_message) = server.generate_public_key(CI); - let (client, client_message) = client.generate_public_key(CI, &mut OsRng); + let (client, client_message) = client.generate_public_key(CI, &mut rng); Ok((client, server, client_message, server_message)) } diff --git a/spake2/Cargo.toml b/spake2/Cargo.toml index 587eb78..549154c 100644 --- a/spake2/Cargo.toml +++ b/spake2/Cargo.toml @@ -15,10 +15,13 @@ edition = "2024" rust-version = "1.85" [dependencies] -curve25519-dalek = { version = "4.1.3", default-features = false, features = ["rand_core"] } -rand_core = { version = "0.6", default-features = false } -sha2 = { version = "0.10", default-features = false } -hkdf = { version = "0.12", default-features = false } +curve25519-dalek = { version = "5.0.0-pre.1", default-features = false, features = ["rand_core"] } +rand_core = { version = "0.10.0-rc-2", default-features = false } +sha2 = { version = "0.11.0-rc.3", default-features = false } +hkdf = { version = "0.13.0-rc.3", default-features = false } + +# optional dependencies +rand = { version = "0.10.0-rc.1", optional = true } [dev-dependencies] bencher = "0.1" @@ -26,8 +29,7 @@ hex = "0.4" num-bigint = "0.4" [features] -default = ["getrandom"] -getrandom = ["rand_core/getrandom"] +default = [] std = [] [package.metadata.docs.rs] diff --git a/spake2/src/lib.rs b/spake2/src/lib.rs index b1d8715..6c44e5e 100644 --- a/spake2/src/lib.rs +++ b/spake2/src/lib.rs @@ -40,7 +40,8 @@ //! //! Thus a client-side program start with: //! -//! ```rust +#![cfg_attr(feature = "rand", doc = "```")] +#![cfg_attr(not(feature = "rand"), doc = "```ignore")] //! use spake2::{Ed25519Group, Identity, Password, Spake2}; //! # fn send(msg: &[u8]) {} //! let (s1, outbound_msg) = Spake2::::start_a( @@ -56,7 +57,8 @@ //! //! while the server-side might do: //! -//! ```rust +#![cfg_attr(feature = "rand", doc = "```")] +#![cfg_attr(not(feature = "rand"), doc = "```ignore")] //! # fn send(msg: &[u8]) {} //! use spake2::{Ed25519Group, Identity, Password, Spake2}; //! let (s1, outbound_msg) = Spake2::::start_b( @@ -100,7 +102,8 @@ //! //! Carol does: //! -//! ```rust +#![cfg_attr(feature = "rand", doc = "```")] +#![cfg_attr(not(feature = "rand"), doc = "```ignore")] //! # fn send(msg: &[u8]) {} //! use spake2::{Ed25519Group, Identity, Password, Spake2}; //! let (s1, outbound_msg) = Spake2::::start_symmetric( @@ -115,7 +118,8 @@ //! //! Dave does exactly the same: //! -//! ```rust +#![cfg_attr(feature = "rand", doc = "```")] +#![cfg_attr(not(feature = "rand"), doc = "```ignore")] //! # fn send(msg: &[u8]) {} //! use spake2::{Ed25519Group, Identity, Password, Spake2}; //! let (s1, outbound_msg) = Spake2::::start_symmetric( @@ -239,14 +243,18 @@ pub use self::{ error::{Error, Result}, group::Group, }; +pub use rand_core; use alloc::vec::Vec; use core::{fmt, ops::Deref, str}; use curve25519_dalek::{edwards::EdwardsPoint as c2_Element, scalar::Scalar as c2_Scalar}; -use rand_core::{CryptoRng, RngCore}; +use rand_core::CryptoRng; -#[cfg(feature = "getrandom")] -use rand_core::OsRng; +#[cfg(feature = "rand")] +pub use rand::rngs::OsRng; + +#[cfg(feature = "rand")] +use rand::TryRngCore; /// Password type. // TODO(tarcieri): avoid allocation? @@ -312,28 +320,28 @@ impl Spake2 { /// Start with identity `idA`. /// /// Uses the system RNG. - #[cfg(feature = "getrandom")] + #[cfg(feature = "rand")] #[must_use] pub fn start_a(password: &Password, id_a: &Identity, id_b: &Identity) -> (Self, Vec) { - Self::start_a_with_rng(password, id_a, id_b, OsRng) + Self::start_a_with_rng(password, id_a, id_b, OsRng.unwrap_mut()) } /// Start with identity `idB`. /// /// Uses the system RNG. - #[cfg(feature = "getrandom")] + #[cfg(feature = "rand")] #[must_use] pub fn start_b(password: &Password, id_a: &Identity, id_b: &Identity) -> (Self, Vec) { - Self::start_b_with_rng(password, id_a, id_b, OsRng) + Self::start_b_with_rng(password, id_a, id_b, OsRng.unwrap_mut()) } /// Start with symmetric identity. /// /// Uses the system RNG. - #[cfg(feature = "getrandom")] + #[cfg(feature = "rand")] #[must_use] pub fn start_symmetric(password: &Password, id_s: &Identity) -> (Self, Vec) { - Self::start_symmetric_with_rng(password, id_s, OsRng) + Self::start_symmetric_with_rng(password, id_s, OsRng.unwrap_mut()) } /// Start with identity `idA` and the provided cryptographically secure RNG. @@ -342,7 +350,7 @@ impl Spake2 { password: &Password, id_a: &Identity, id_b: &Identity, - mut csrng: impl CryptoRng + RngCore, + mut csrng: impl CryptoRng, ) -> (Self, Vec) { let xy_scalar: G::Scalar = G::random_scalar(&mut csrng); Self::start_a_internal(password, id_a, id_b, xy_scalar) @@ -353,7 +361,7 @@ impl Spake2 { password: &Password, id_a: &Identity, id_b: &Identity, - mut csrng: impl CryptoRng + RngCore, + mut csrng: impl CryptoRng, ) -> (Self, Vec) { let xy_scalar: G::Scalar = G::random_scalar(&mut csrng); Self::start_b_internal(password, id_a, id_b, xy_scalar) @@ -363,7 +371,7 @@ impl Spake2 { pub fn start_symmetric_with_rng( password: &Password, id_s: &Identity, - mut csrng: impl CryptoRng + RngCore, + mut csrng: impl CryptoRng, ) -> (Self, Vec) { let xy_scalar: G::Scalar = G::random_scalar(&mut csrng); Self::start_symmetric_internal(password, id_s, xy_scalar) diff --git a/spake2/tests/spake2.rs b/spake2/tests/spake2.rs index 5db2ee6..6e4aded 100644 --- a/spake2/tests/spake2.rs +++ b/spake2/tests/spake2.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "rand")] + use spake2::{Ed25519Group, Error, Identity, Password, Spake2}; #[test] diff --git a/srp/Cargo.toml b/srp/Cargo.toml index 7d54264..68e4d1b 100644 --- a/srp/Cargo.toml +++ b/srp/Cargo.toml @@ -14,14 +14,13 @@ rust-version = "1.85" [dependencies] num-bigint = "0.4" -generic-array = "0.14" -digest = "0.10" +digest = "0.11.0-rc.4" lazy_static = "1.2" subtle = "2.4" [dev-dependencies] hex-literal = "1" num-traits = "0.2" -rand = "0.8" -sha1 = "0.10" -sha2 = "0.10" +rand = "0.10.0-rc.1" +sha1 = "0.11.0-rc.3" +sha2 = "0.11.0-rc.3" diff --git a/srp/tests/srp.rs b/srp/tests/srp.rs index 45ff2fd..7212382 100644 --- a/srp/tests/srp.rs +++ b/srp/tests/srp.rs @@ -6,7 +6,7 @@ use srp::groups::G_2048; use srp::server::SrpServer; fn auth_test(true_pwd: &[u8], auth_pwd: &[u8]) { - let mut rng = rand::rngs::OsRng; + let mut rng = rand::rng(); let username = b"alice"; // Client instance creation @@ -69,7 +69,7 @@ fn auth_test(true_pwd: &[u8], auth_pwd: &[u8]) { } fn auth_test_rfc5054(true_pwd: &[u8], auth_pwd: &[u8]) { - let mut rng = rand::rngs::OsRng; + let mut rng = rand::rng(); let username = b"alice"; // Client instance creation