diff --git a/Cargo.lock b/Cargo.lock index b0dfdd7..c6795d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,12 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "aead" version = "0.5.2" @@ -27,6 +33,18 @@ dependencies = [ "generic-array", ] +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -36,6 +54,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -101,15 +125,12 @@ dependencies = [ ] [[package]] -name = "argon2" -version = "0.5.3" +name = "arbitrary" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" dependencies = [ - "base64ct", - "blake2", - "cpufeatures", - "password-hash", + "derive_arbitrary", ] [[package]] @@ -140,10 +161,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "base64ct" -version = "1.6.0" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "better-panic" @@ -161,15 +182,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "blake2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" -dependencies = [ - "digest", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -333,6 +345,15 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + [[package]] name = "cpufeatures" version = "0.2.14" @@ -342,6 +363,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crossterm" version = "0.27.0" @@ -378,6 +414,23 @@ dependencies = [ "typenum", ] +[[package]] +name = "dary_heap" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04d2cd9c18b9f454ed67da600630b021a8a80bf33f8c95896ab33aaf1c26b728" + +[[package]] +name = "derive_arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dialoguer" version = "0.11.0" @@ -399,7 +452,17 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", - "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -408,6 +471,12 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.9" @@ -424,6 +493,37 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.59.0", +] + +[[package]] +name = "flate2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + [[package]] name = "futures" version = "0.3.31" @@ -552,6 +652,22 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + [[package]] name = "heck" version = "0.5.0" @@ -564,15 +680,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - [[package]] name = "humantime" version = "2.1.0" @@ -602,6 +709,26 @@ dependencies = [ "cc", ] +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.0", +] + [[package]] name = "indicatif" version = "0.17.9" @@ -666,6 +793,30 @@ version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +[[package]] +name = "libflate" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45d9dfdc14ea4ef0900c1cddbc8dcd553fbaacd8a4a282cf4018ae9dd04fb21e" +dependencies = [ + "adler32", + "core2", + "crc32fast", + "dary_heap", + "libflate_lz77", +] + +[[package]] +name = "libflate_lz77" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e0d73b369f386f1c44abd9c570d5318f55ccde816ff4b562fa452e5182863d" +dependencies = [ + "core2", + "hashbrown 0.14.5", + "rle-decode-fast", +] + [[package]] name = "libmimalloc-sys" version = "0.1.39" @@ -676,6 +827,34 @@ dependencies = [ "libc", ] +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", + "redox_syscall", +] + +[[package]] +name = "libsodium-sys-stable" +version = "1.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "798a1c6d8c3424c0686ca46f2929d81809b371ef61a68c5d1880570584d32b85" +dependencies = [ + "cc", + "libc", + "libflate", + "minisign-verify", + "pkg-config", + "tar", + "ureq", + "vcpkg", + "zip", +] + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -692,6 +871,12 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "lockfree-object-pool" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" + [[package]] name = "log" version = "0.4.22" @@ -713,6 +898,12 @@ dependencies = [ "libmimalloc-sys", ] +[[package]] +name = "minisign-verify" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a05b5d0594e0cb1ad8cee3373018d2b84e25905dc75b2468114cc9a8e86cfc20" + [[package]] name = "miniz_oxide" version = "0.8.0" @@ -794,25 +985,10 @@ dependencies = [ ] [[package]] -name = "password-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" -dependencies = [ - "base64ct", - "rand_core", - "subtle", -] - -[[package]] -name = "pbkdf2" -version = "0.12.2" +name = "percent-encoding" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" -dependencies = [ - "digest", - "hmac", -] +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" @@ -826,6 +1002,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + [[package]] name = "poly1305" version = "0.8.0" @@ -914,6 +1096,12 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" +[[package]] +name = "rle-decode-fast" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" + [[package]] name = "rstest" version = "0.18.2" @@ -977,33 +1165,12 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "salsa20" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" -dependencies = [ - "cipher", -] - [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "scrypt" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" -dependencies = [ - "password-hash", - "pbkdf2", - "salsa20", - "sha2", -] - [[package]] name = "semver" version = "1.0.23" @@ -1105,6 +1272,12 @@ dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "slab" version = "0.4.9" @@ -1116,10 +1289,9 @@ dependencies = [ [[package]] name = "slowkey" -version = "1.6.0" +version = "1.4.1" dependencies = [ - "argon2", - "base64", + "base64 0.21.7", "better-panic", "bs58", "chacha20poly1305", @@ -1133,9 +1305,9 @@ dependencies = [ "humantime", "indicatif", "lazy_static", + "libsodium-sys-stable", "mimalloc", "rstest", - "scrypt", "serde", "serde_json", "sha2", @@ -1171,6 +1343,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tar" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ff6c40d3aedb5e06b57c6f669ad17ab063dd1e63d977c6a88e7f4dfa4f04020" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "tempfile" version = "3.13.0" @@ -1234,12 +1417,27 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "unicode-bidi" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" + [[package]] name = "unicode-ident" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-width" version = "0.1.14" @@ -1262,12 +1460,41 @@ dependencies = [ "subtle", ] +[[package]] +name = "ureq" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" +dependencies = [ + "base64 0.22.1", + "log", + "once_cell", + "url", +] + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" @@ -1533,8 +1760,70 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys", + "rustix", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zip" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc5e4288ea4057ae23afc69a4472434a87a2495cafce6632fd1c4ec9f5cf3494" +dependencies = [ + "arbitrary", + "crc32fast", + "crossbeam-utils", + "displaydoc", + "flate2", + "indexmap", + "memchr", + "thiserror", + "zopfli", +] + +[[package]] +name = "zopfli" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" +dependencies = [ + "bumpalo", + "crc32fast", + "lockfree-object-pool", + "log", + "once_cell", + "simd-adler32", +] diff --git a/Cargo.toml b/Cargo.toml index 6498ed2..abdceed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,37 +2,34 @@ authors = ["Leonid Beder "] edition = "2021" name = "slowkey" -version = "1.6.0" +version = "1.4.1" [dependencies] -argon2 = "0.5.3" -base64 = "0.21.7" better-panic = "0.3.0" -bs58 = "0.5.1" -chacha20poly1305 = "0.10.1" -chrono = "0.4.38" clap = { version = "4.5.21", features = ["derive", "string"] } color-backtrace = "0.6.1" crossterm = "0.27.0" -dialoguer = "0.11.0" -glob = "0.3.1" hex = "0.4.3" humantime = "2.1.0" -indicatif = "0.17.9" -lazy_static = "1.5.0" mimalloc = { version = "0.1.43", default-features = false } -scrypt = "0.11.0" -serde = { version = "1.0.215", features = ["derive"] } -serde_json = "1.0.132" sha2 = "0.10.8" sha3 = "0.10.8" +lazy_static = "1.5.0" +base64 = "0.21.7" +bs58 = "0.5.1" +libsodium-sys-stable = { version = "1.22.1", features = ["optimized"] } +dialoguer = "0.11.0" +serde = { version = "1.0.215", features = ["derive"] } +serde_json = "1.0.132" +chacha20poly1305 = "0.10.1" +glob = "0.3.1" +indicatif = "0.17.9" +chrono = "0.4.38" [dev-dependencies] rstest = "0.18.2" [profile.release] -lto = "thin" -codegen-units = 1 panic = "abort" [profile.profile] diff --git a/src/main.rs b/src/main.rs index 6c5a55d..f6e1fe6 100755 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ mod utils; extern crate chacha20poly1305; extern crate hex; extern crate indicatif; +extern crate libsodium_sys; extern crate serde; extern crate serde_json; @@ -13,7 +14,7 @@ mod slowkey; use crate::{ slowkey::{SlowKey, SlowKeyOptions, TEST_VECTORS}, - utils::scrypt::ScryptOptions, + utils::{scrypt::ScryptOptions, sodium_init::initialize}, }; use base64::{engine::general_purpose, Engine as _}; use chrono::{DateTime, Utc}; @@ -91,10 +92,10 @@ enum Commands { #[arg( long, - default_value = SlowKeyOptions::default().scrypt.log_n.to_string(), - help = format!("Scrypt CPU/memory cost parameter (must be lesser than {})", ScryptOptions::MAX_LOG_N) + default_value = SlowKeyOptions::default().scrypt.n.to_string(), + help = format!("Scrypt CPU/memory cost parameter (must be lesser than {})", ScryptOptions::MAX_N) )] - scrypt_log_n: u8, + scrypt_n: u64, #[arg( long, @@ -122,12 +123,6 @@ enum Commands { help = format!("Argon2 number of iterations (must be greater than {} and lesser than {})", Argon2idOptions::MIN_T_COST, Argon2idOptions::MAX_T_COST))] argon2_t_cost: u32, - #[arg( - long, - default_value = SlowKeyOptions::default().argon2id.p_cost.to_string(), - help = format!("Argon2 Degree of parallelism (must be greater than {} and lesser than {})", Argon2idOptions::MIN_P_COST, Argon2idOptions::MAX_P_COST))] - argon2_p_cost: u32, - #[arg( long, requires = "checkpoint_interval", @@ -399,6 +394,9 @@ fn main() { better_panic::install(); color_backtrace::install(); + // Initialize libsodium + initialize(); + println!("SlowKey v{VERSION}\n"); let cli = Cli::parse(); @@ -410,12 +408,11 @@ fn main() { base64, base58, output, - scrypt_log_n, + scrypt_n, scrypt_r, scrypt_p, argon2_m_cost, argon2_t_cost, - argon2_p_cost, checkpoint_interval, checkpoint_dir, restore_from_checkpoint, @@ -469,8 +466,8 @@ fn main() { slowkey_opts = SlowKeyOptions::new( iterations, length, - &ScryptOptions::new(scrypt_log_n, scrypt_r, scrypt_p), - &Argon2idOptions::new(argon2_m_cost, argon2_t_cost, argon2_p_cost), + &ScryptOptions::new(scrypt_n, scrypt_r, scrypt_p), + &Argon2idOptions::new(argon2_m_cost, argon2_t_cost), ); } @@ -516,8 +513,6 @@ fn main() { let salt = get_salt(); let password = get_password(); - let mut prev_data = Vec::new(); - if let Some(checkpoint_data) = restore_from_checkpoint_data { println!("Verifying the checkpoint...\n"); @@ -530,18 +525,16 @@ fn main() { } else { println!("{}: Unable to verify the first checkpoint\n", "Warning".dark_yellow()); } - - // Since we are starting from this checkpoint, set the rolling previous data to its data - prev_data = checkpoint_data.data.data; } let mb = MultiProgress::new(); let pb = mb - .add(ProgressBar::new((slowkey_opts.iterations - offset) as u64)) + .add(ProgressBar::new(slowkey_opts.iterations as u64)) .with_style( ProgressStyle::with_template("{bar:80.cyan/blue} {pos:>7}/{len:7} {percent}% ({eta})").unwrap(), - ); + ) + .with_position(offset as u64); pb.enable_steady_tick(Duration::from_secs(1)); @@ -550,9 +543,10 @@ fn main() { if checkpoint.is_some() && checkpointing_interval != 0 { cpb = Some( mb.add(ProgressBar::new( - ((slowkey_opts.iterations - offset) / checkpointing_interval) as u64, + (slowkey_opts.iterations / checkpointing_interval) as u64, )) - .with_style(ProgressStyle::with_template("{msg}").unwrap()), + .with_style(ProgressStyle::with_template("{msg}").unwrap()) + .with_position((offset / checkpointing_interval) as u64), ); if let Some(ref mut cpb) = &mut cpb { @@ -563,9 +557,8 @@ fn main() { let start_time = SystemTime::now(); let running_time = Instant::now(); let slowkey = SlowKey::new(&slowkey_opts); - - let prev_data_mutex = Arc::new(Mutex::new(prev_data)); - let prev_data_thread = Arc::clone(&prev_data_mutex); + let prev_data = Arc::new(Mutex::new(Vec::new())); + let prev_data_thread = Arc::clone(&prev_data); let handle = thread::spawn(move || { let key = slowkey.derive_key_with_callback( @@ -581,21 +574,22 @@ fn main() { let prev_data: Option<&[u8]> = if current_iteration == 0 { None } else { Some(&prev_data) }; if let Some(checkpoint) = &mut checkpoint { - checkpoint.create_checkpoint(current_iteration, current_data, prev_data); + checkpoint.create_checkpoint(&salt, current_iteration, current_data, prev_data); } if let Some(ref mut cpb) = &mut cpb { - let hash = Checkpoint::hash_checkpoint(current_iteration, current_data, prev_data); + let hash = + Checkpoint::hash_checkpoint(&salt, current_iteration, current_data, prev_data); cpb.set_message(format!( - "\nCreated checkpoint #{} with data hash {}", + "\nCreated checkpoint #{} with data hash (salted) {}", (current_iteration + 1).to_string().cyan(), format!("0x{}", hex::encode(hash)).cyan() )); } } - // Store the current data in order to store it in the checkpoint for future verification of the + // Store the current data in order to store it in the checkpoint for future verification of the // parameters if current_iteration < iterations - 1 { prev_data.clone_from(current_data); @@ -640,7 +634,7 @@ fn main() { println!(); if let Some(out) = out { - let prev_data_guard = prev_data_mutex.lock().unwrap(); + let prev_data_guard = prev_data.lock().unwrap(); let prev_data_option: Option<&[u8]> = if prev_data_guard.is_empty() { None } else { diff --git a/src/slowkey.rs b/src/slowkey.rs index 6ef8a70..8025917 100755 --- a/src/slowkey.rs +++ b/src/slowkey.rs @@ -3,7 +3,6 @@ use crate::utils::{ scrypt::{Scrypt, ScryptOptions}, }; use crossterm::style::Stylize; -use scrypt::password_hash::SaltString; use serde::{Deserialize, Serialize}; use sha2::Sha512; use sha3::{Digest, Keccak512}; @@ -21,8 +20,8 @@ impl SlowKeyOptions { pub const MAX_ITERATIONS: usize = u32::MAX as usize; pub const DEFAULT_ITERATIONS: usize = 100; - pub const MIN_KEY_SIZE: usize = 9; - pub const MAX_KEY_SIZE: usize = 64; + pub const MIN_KEY_SIZE: usize = 10; + pub const MAX_KEY_SIZE: usize = 128; pub const DEFAULT_KEY_SIZE: usize = 32; pub fn new(iterations: usize, length: usize, scrypt: &ScryptOptions, argon2id: &Argon2idOptions) -> Self { @@ -60,21 +59,20 @@ impl SlowKeyOptions { pub fn print(&self) { println!( - "{}:\n {}: {}\n {}: {}\n {}: (log_n: {}, r: {}, p: {})\n {}: (version: {}, m_cost: {}, t_cost: {}, p_cost: {})\n", + "{}:\n {}: {}\n {}: {}\n {}: (n: {}, r: {}, p: {})\n {}: (version: {}, m_cost: {}, t_cost: {})\n", "SlowKey Parameters".yellow(), "Iterations".green(), &self.iterations.to_string().cyan(), "Length".green(), &self.length.to_string().cyan(), "Scrypt".green(), - &self.scrypt.log_n.to_string().cyan(), + &self.scrypt.n.to_string().cyan(), &self.scrypt.r.to_string().cyan(), &self.scrypt.p.to_string().cyan(), "Argon2id".green(), - (Argon2id::VERSION as u8).to_string().cyan(), + Argon2id::VERSION.to_string().cyan(), &self.argon2id.m_cost.to_string().cyan(), - &self.argon2id.t_cost.to_string().cyan(), - &self.argon2id.p_cost.to_string().cyan() + &self.argon2id.t_cost.to_string().cyan() ); } } @@ -128,14 +126,14 @@ lazy_static! { ]; } -pub struct SlowKey<'a> { +pub struct SlowKey { iterations: usize, length: usize, scrypt: Scrypt, - argon2id: Argon2id<'a>, + argon2id: Argon2id, } -impl<'a> SlowKey<'a> { +impl SlowKey { pub const SALT_SIZE: usize = 16; pub const DEFAULT_SALT: [u8; SlowKey::SALT_SIZE] = [0; SlowKey::SALT_SIZE]; @@ -160,8 +158,6 @@ impl<'a> SlowKey<'a> { _ => offset_data.to_vec(), }; - let salt_string = SaltString::encode_b64(salt).unwrap(); - for i in offset..self.iterations { let iteration = i as u64; @@ -169,13 +165,13 @@ impl<'a> SlowKey<'a> { self.double_hash(salt, password, iteration, &mut res); // Calculate the Scrypt hash of the result and the inputs - self.scrypt(salt, &salt_string, password, iteration, &mut res); + self.scrypt(salt, password, iteration, &mut res); // Calculate the SHA2 and SHA3 hashes of the result and the inputs again self.double_hash(salt, password, iteration, &mut res); // Calculate the Argon2 hash of the result and the inputs - self.argon2id(salt, &salt_string, password, iteration, &mut res); + self.argon2id(salt, password, iteration, &mut res); callback(i, &res); } @@ -209,26 +205,27 @@ impl<'a> SlowKey<'a> { *res = keccack512.finalize().to_vec(); } - fn scrypt(&self, salt: &[u8], salt_string: &SaltString, password: &[u8], iteration: u64, res: &mut Vec) { + fn scrypt(&self, salt: &[u8], password: &[u8], iteration: u64, res: &mut Vec) { res.extend_from_slice(salt); res.extend_from_slice(password); res.extend_from_slice(&iteration.to_le_bytes()); - *res = self.scrypt.hash(salt_string, res); + *res = self.scrypt.hash(salt, res); } - fn argon2id(&self, salt: &[u8], salt_string: &SaltString, password: &[u8], iteration: u64, res: &mut Vec) { + fn argon2id(&self, salt: &[u8], password: &[u8], iteration: u64, res: &mut Vec) { res.extend_from_slice(salt); res.extend_from_slice(password); res.extend_from_slice(&iteration.to_le_bytes()); - *res = self.argon2id.hash(salt_string, res); + *res = self.argon2id.hash(salt, res); } } #[cfg(test)] mod tests { use super::*; + use crate::utils::sodium_init::initialize; use rstest::rstest; #[rstest] @@ -244,7 +241,7 @@ mod tests { #[case(&SlowKeyOptions { iterations: 10, length: 32, - scrypt: ScryptOptions { log_n: 12, r: 8, p: 1 }, + scrypt: ScryptOptions { n: 1 << 12, r: 8, p: 1 }, argon2id: Argon2idOptions::default() }, b"saltsaltsaltsalt", b"test", &Vec::new(), 0, "6fe4ad1ea824710e75b4a3914c6f3c617c70b3aeb0451639188c253b6f52880e")] @@ -252,63 +249,79 @@ mod tests { iterations: 10, length: 32, scrypt: ScryptOptions::default(), - argon2id: Argon2idOptions { m_cost: 16, t_cost: 2, p_cost: 1 } + argon2id: Argon2idOptions { m_cost: 16, t_cost: 2 } }, b"saltsaltsaltsalt", b"test", &Vec::new(), 0, "744cfcc54433dfb5f4027163cc94c81d4630a63a6e60799c44f2a5801ad2bc77")] #[case(&SlowKeyOptions { iterations: 4, length: 64, - scrypt: ScryptOptions { log_n: 20, r: 8, p: 1 }, + scrypt: ScryptOptions { n: 1 << 20, r: 8, p: 1 }, argon2id: Argon2idOptions::default() }, b"saltsaltsaltsalt", b"test", &Vec::new(), 0, "3ed36a2cb71a043a901cbe237df6976b7a724acadfbc12112c90402548876dd5e76be1da2a1cb57e924a858c36b51c68db13b986e70ddc23254d7fa7a15c2ee0")] + #[case(&SlowKeyOptions { + iterations: 4, + length: 128, + scrypt: ScryptOptions { n: 1 << 20, r: 8, p: 1 }, + argon2id: Argon2idOptions::default() + }, b"saltsaltsaltsalt", b"test", &Vec::new(), 0, + "8e69eb21b3aa9cf0d5b42d18b5a80c8db50908c3baadd9c425d8dfc21ca0f37a503e37a18c5312cf040654f643cc1a5b1801e1f8e86fde355d05a5d2699725b088bf6bf02b0a5888e9198c1876ce82b2664185ff914c853b86b6ead34a351fcfd7124e75bfd643fbdb391025eee3483f30b1f765eae304547a1a1168d0ef448b")] #[case(&SlowKeyOptions { iterations: 4, length: 64, - scrypt: ScryptOptions { log_n: 15, r: 8, p: 1 }, + scrypt: ScryptOptions { n: 1 << 15, r: 8, p: 1 }, argon2id: Argon2idOptions::default() }, b"saltsaltsaltsalt", b"", &Vec::new(), 0, "3af13ebf654ddf60014f4a7f37826f5f60e4defddefffdfc6bf5431e37420c1e308e823bef30a6adb3f862c4b4270aa55e9b0440af7e8ec8d52a3458c1cb3ff4")] #[case(&SlowKeyOptions { iterations: 10, length: 64, - scrypt: ScryptOptions { log_n: 15, r: 8, p: 1 }, + scrypt: ScryptOptions { n: 1 << 15, r: 8, p: 1 }, argon2id: Argon2idOptions::default() }, b"saltsaltsaltsalt", b"test", &Vec::new(), 0, "c2a74fca9621ca13f2ab1a1bdf7cb8e6abe231d7494c280ff40024b1e92f964579d7c77e4b5c32ec438f2932b612f8eae9eeedbba93b0708e1f1b497bcdaed5d")] #[case(&SlowKeyOptions { iterations: 10, length: 64, - scrypt: ScryptOptions { log_n: 15, r: 8, p: 1 }, + scrypt: ScryptOptions { n: 1 << 15, r: 8, p: 1 }, argon2id: Argon2idOptions::default() }, b"saltsaltsaltsal2", b"test", &Vec::new(), 0, "016bbfa52b69c0fc366f9b93b5209d0c9783c018102101eb755f217627541778b13c5db624a105ed6470d7a916e8e5843f952f20bb9f0e9b6053e72176b6158b")] #[case(&SlowKeyOptions { iterations: 10, length: 64, - scrypt: ScryptOptions { log_n: 15, r: 8, p: 1 }, + scrypt: ScryptOptions { n: 1 << 15, r: 8, p: 1 }, argon2id: Argon2idOptions::default() }, b"saltsaltsaltsalt", b"test2", &Vec::new(), 0, "f20e5bf61c9c0ab9208eb1b5a2f3a51a8276dbc5490862f17afbba5ffe539ee95765095aff000d86371ed6ca927efe736008fd048fbde77af56b20331ebde083")] #[case(&SlowKeyOptions { iterations: 10, length: 32, - scrypt: ScryptOptions { log_n: 12, r: 8, p: 1 }, + scrypt: ScryptOptions { n: 1 << 12, r: 8, p: 1 }, argon2id: Argon2idOptions::default() }, b"saltsaltsaltsalt", b"test", &Vec::new(), 1, "dc4ca67e268ac2df2bbaa377afabafda82012b6188d562d67ef57f66f2f592e1")] #[case(&SlowKeyOptions { iterations: 10, length: 64, - scrypt: ScryptOptions { log_n: 15, r: 8, p: 1 }, + scrypt: ScryptOptions { n: 1 << 15, r: 8, p: 1 }, argon2id: Argon2idOptions::default() }, b"saltsaltsaltsalt", b"test", &Vec::new(), 5, "488d73ed1e5c22edfe060d542dc1bc517cdc567aede68fbf87f344fc153b1febbfff6bb52f236a21fa6aaa16e39769248f7eb01c80a48988049a9faee7434f99")] + #[case(&SlowKeyOptions { + iterations: 10, + length: 128, + scrypt: ScryptOptions { n: 1 << 15, r: 8, p: 1 }, + argon2id: Argon2idOptions::default() + }, b"saltsaltsaltsalt", b"test", &Vec::new(), 5, + "0ff28531af487240b664d549ebc2a367df89a2b5d94baed94a53025601b2b2f5ced135415c7cf880b4cc1fe97ea5ba052838caebb8301719d268b7a2d795d75908712910839c8145a70b7ebdf49e2f61a4c1466e89e2e5bd8fb45eb076a72baa60bc803162ee20481b1b85a5985d768908b283e95e52df4466f116ab9014945a")] fn derive_test( #[case] options: &SlowKeyOptions, #[case] salt: &[u8], #[case] password: &[u8], #[case] offset_data: &[u8], #[case] offset: usize, #[case] expected: &str, ) { + initialize(); + let kdf = SlowKey::new(options); let key = kdf.derive_key(salt, password, offset_data, offset); assert_eq!(hex::encode(key), expected); diff --git a/src/utils/checkpoints/checkpoint.rs b/src/utils/checkpoints/checkpoint.rs index 01e0903..b8e7094 100644 --- a/src/utils/checkpoints/checkpoint.rs +++ b/src/utils/checkpoints/checkpoint.rs @@ -136,20 +136,19 @@ impl CheckpointData { if display.options { output = format!( - "{}\n {}:\n {}: {}\n {}: (log_n: {}, r: {}, p: {})\n {}: (version: {}, m_cost: {}, t_cost: {}, p_cost: {})\n", + "{}\n {}:\n {}: {}\n {}: (n: {}, r: {}, p: {})\n {}: (version: {}, m_cost: {}, t_cost: {})\n", output, "SlowKey Parameters".yellow(), "Length".green(), &self.data.slowkey.length.to_string().cyan(), "Scrypt".green(), - &self.data.slowkey.scrypt.log_n.to_string().cyan(), + &self.data.slowkey.scrypt.n.to_string().cyan(), &self.data.slowkey.scrypt.r.to_string().cyan(), &self.data.slowkey.scrypt.p.to_string().cyan(), "Argon2id".green(), - (Argon2id::VERSION as u8).to_string().cyan(), + Argon2id::VERSION.to_string().cyan(), &self.data.slowkey.argon2id.m_cost.to_string().cyan(), - &self.data.slowkey.argon2id.t_cost.to_string().cyan(), - &self.data.slowkey.argon2id.p_cost.to_string().cyan() + &self.data.slowkey.argon2id.t_cost.to_string().cyan() ); } @@ -224,8 +223,8 @@ impl Checkpoint { } } - pub fn create_checkpoint(&mut self, iteration: usize, data: &[u8], prev_data: Option<&[u8]>) { - let hash = Self::hash_checkpoint(iteration, data, prev_data); + pub fn create_checkpoint(&mut self, salt: &[u8], iteration: usize, data: &[u8], prev_data: Option<&[u8]>) { + let hash = Self::hash_checkpoint(salt, iteration, data, prev_data); let padding = self.checkpoint_extension_padding; let checkpoint_path = Path::new(&self.dir) .join(Self::CHECKPOINT_PREFIX) @@ -249,16 +248,17 @@ impl Checkpoint { } } - pub fn hash_checkpoint(iteration: usize, data: &[u8], prev_data: Option<&[u8]>) -> Vec { - let mut hash_data = data.to_vec(); - hash_data.extend_from_slice(&iteration.to_be_bytes()); + pub fn hash_checkpoint(salt: &[u8], iteration: usize, data: &[u8], prev_data: Option<&[u8]>) -> Vec { + let mut salted_data = data.to_vec(); + salted_data.extend_from_slice(salt); + salted_data.extend_from_slice(&iteration.to_be_bytes()); if let Some(prev_data) = prev_data { - hash_data.extend_from_slice(prev_data); + salted_data.extend_from_slice(prev_data); } let mut sha256 = Sha256::new(); - sha256.update(hash_data); + sha256.update(salted_data); sha256.finalize().to_vec() } diff --git a/src/utils/scrypt.rs b/src/utils/scrypt.rs index e400c8f..c4f40f1 100644 --- a/src/utils/scrypt.rs +++ b/src/utils/scrypt.rs @@ -1,20 +1,16 @@ +use libsodium_sys::crypto_pwhash_scryptsalsa208sha256_ll; use serde::{Deserialize, Serialize}; -use scrypt::{ - password_hash::{PasswordHasher, SaltString}, - Params, Scrypt as RustScrypt, -}; - #[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize)] pub struct ScryptOptions { - pub log_n: u8, + pub n: u64, pub r: u32, pub p: u32, } impl ScryptOptions { - pub const MAX_LOG_N: u8 = usize::BITS as u8; - pub const DEFAULT_LOG_N: u8 = 20; + pub const MAX_N: u64 = u64::MAX; + pub const DEFAULT_N: u64 = 1 << 20; pub const MIN_R: u32 = 0; pub const MAX_R: u32 = u32::MAX; @@ -24,22 +20,18 @@ impl ScryptOptions { pub const MAX_P: u32 = u32::MAX; pub const DEFAULT_P: u32 = 1; - pub fn new(log_n: u8, r: u32, p: u32) -> Self { - if log_n > Self::MAX_LOG_N { - panic!("log_n {} is greater than the max length of {}", Self::MAX_LOG_N, log_n); - } - - // Note that there is no need to check if either r or p are in bounds, since both are bound by the maximum + pub fn new(n: u64, r: u32, p: u32) -> Self { + // Note that there is no need to check if either n, r or p are in bounds, since both are bound by the maximum // and the minimum values for this type - Self { log_n, r, p } + Self { n, r, p } } } impl Default for ScryptOptions { fn default() -> Self { Self { - log_n: Self::DEFAULT_LOG_N, + n: Self::DEFAULT_N, r: Self::DEFAULT_R, p: Self::DEFAULT_P, } @@ -56,47 +48,58 @@ impl Scrypt { Self { length, opts: *opts } } - pub fn hash(&self, salt: &SaltString, password: &[u8]) -> Vec { - let res = RustScrypt - .hash_password_customized( - password, - None, - None, - Params::new(self.opts.log_n, self.opts.r, self.opts.p, self.length).unwrap(), - salt, - ) - .unwrap(); - - match res.hash { - Some(output) => output.as_bytes().to_vec(), - None => panic!("hash_password_customized failed"), + pub fn hash(&self, salt: &[u8], password: &[u8]) -> Vec { + let mut dk = vec![0; self.length]; + + unsafe { + let ret = crypto_pwhash_scryptsalsa208sha256_ll( + password.as_ptr(), + password.len(), + salt.as_ptr(), + salt.len(), + self.opts.n, + self.opts.r, + self.opts.p, + dk.as_mut_ptr(), + dk.len(), + ); + + if ret != 0 { + panic!("crypto_pwhash_scryptsalsa208sha256_ll failed with: {ret}"); + } } + + dk.to_vec() } } #[cfg(test)] mod tests { use super::*; + use crate::utils::sodium_init::initialize; use rstest::rstest; #[rstest] - #[case(b"salt", b"", 64, &ScryptOptions { log_n: 15, r: 8, p: 1 }, "6e6d0720a5766a2f99679af8dbf78794d8cfe4c2b658ec82a1d005c0d54582846583ccf105fa66271ad7907868b4e3f5bb61f12b427fe0dd2c75df55afce74c1")] + #[case(&Vec::new(), &Vec::new(), 64, &ScryptOptions::default(), "d436cba148427322d47a09a84b9bbb64d5ff086545170518711f3ec6936124e0383b3f47409e0329776231b295df5038ab07b096b8717718fd6f092195bfb03a")] + #[case(b"salt", b"", 64, &ScryptOptions { n: 1 << 15, r: 8, p: 1 }, "6e6d0720a5766a2f99679af8dbf78794d8cfe4c2b658ec82a1d005c0d54582846583ccf105fa66271ad7907868b4e3f5bb61f12b427fe0dd2c75df55afce74c1")] #[case(b"salt", b"test", 64, &ScryptOptions::default(), "c91328bf58e9904c6c3aa15b26178b7ff03caf4eab382e3b9e1a335fb487c775b64ff03b82391a33b655047a632391b6216b98b2595cd82e89eaa1d9c8c2ccf5")] #[case(b"salt", b"test", 32, &ScryptOptions::default(), "c91328bf58e9904c6c3aa15b26178b7ff03caf4eab382e3b9e1a335fb487c775")] #[case(b"salt", b"test", 16, &ScryptOptions::default(), "c91328bf58e9904c6c3aa15b26178b7f")] - #[case(b"salt", b"test", 64, &ScryptOptions { log_n: 12, r: 8, p: 2 }, "3ed57e6edeae5e46f2932b6d22e0a73e47ff22c66d3acab5f0488cda26297425693b2d5cbd463c3521c8132056fb801997b915a9f8d051948a430142c7aa5855")] - #[case(b"salt", b"test", 32, &ScryptOptions { log_n: 12, r: 8, p: 2 }, "3ed57e6edeae5e46f2932b6d22e0a73e47ff22c66d3acab5f0488cda26297425")] - #[case(b"salt", b"test", 16, &ScryptOptions { log_n: 12, r: 8, p: 2 }, "3ed57e6edeae5e46f2932b6d22e0a73e")] - #[case(b"salt", b"test", 64, &ScryptOptions { log_n: 12, r: 16, p: 1 }, "107a4e74f205207f82c8fd0f8a4a5fbe3a485fb9509e1b839d9cb98d63649354a0d56eaad6340f2c1e92dd25a6883b51f9806b6c7980c60c1b290b96dbceec45")] - #[case(b"salt", b"test", 32, &ScryptOptions { log_n: 12, r: 16, p: 1 }, "107a4e74f205207f82c8fd0f8a4a5fbe3a485fb9509e1b839d9cb98d63649354")] - #[case(b"salt", b"test", 16, &ScryptOptions { log_n: 12, r: 16, p: 1 }, "107a4e74f205207f82c8fd0f8a4a5fbe")] + #[case(b"salt", b"test", 64, &ScryptOptions { n: 1 << 12, r: 8, p: 2 }, "3ed57e6edeae5e46f2932b6d22e0a73e47ff22c66d3acab5f0488cda26297425693b2d5cbd463c3521c8132056fb801997b915a9f8d051948a430142c7aa5855")] + #[case(b"salt", b"test", 32, &ScryptOptions { n: 1 << 12, r: 8, p: 2 }, "3ed57e6edeae5e46f2932b6d22e0a73e47ff22c66d3acab5f0488cda26297425")] + #[case(b"salt", b"test", 16, &ScryptOptions { n: 1 << 12, r: 8, p: 2 }, "3ed57e6edeae5e46f2932b6d22e0a73e")] + #[case(b"salt", b"test", 64, &ScryptOptions { n: 1 << 12, r: 16, p: 1 }, "107a4e74f205207f82c8fd0f8a4a5fbe3a485fb9509e1b839d9cb98d63649354a0d56eaad6340f2c1e92dd25a6883b51f9806b6c7980c60c1b290b96dbceec45")] + #[case(b"salt", b"test", 32, &ScryptOptions { n: 1 << 12, r: 16, p: 1 }, "107a4e74f205207f82c8fd0f8a4a5fbe3a485fb9509e1b839d9cb98d63649354")] + #[case(b"salt", b"test", 16, &ScryptOptions { n: 1 << 12, r: 16, p: 1 }, "107a4e74f205207f82c8fd0f8a4a5fbe")] fn scrypt_test( #[case] salt: &[u8], #[case] password: &[u8], #[case] length: usize, #[case] opts: &ScryptOptions, #[case] expected: &str, ) { + initialize(); + let scrypt = Scrypt::new(length, opts); - let key = scrypt.hash(&SaltString::encode_b64(salt).unwrap(), password); + let key = scrypt.hash(salt, password); assert_eq!(hex::encode(key), expected); }