//! Argon2 Known Answer Tests (KAT). //! //! Taken from the Argon2 reference implementation as well as //! `draft-irtf-cfrg-argon2-12` Section 5: //! #![cfg(all(feature = "alloc", feature = "password-hash"))] // TODO(tarcieri): test full set of vectors from the reference implementation: // https://github.com/P-H-C/phc-winner-argon2/blob/master/src/test.c use argon2::{ Algorithm, Argon2, AssociatedData, Error, Params, ParamsBuilder, PasswordHash, PasswordHasher, PasswordVerifier, Version, }; use hex_literal::hex; use password_hash::SaltString; /// Params used by the KATs. fn example_params() -> Params { ParamsBuilder::new() .m_cost(32) .t_cost(3) .p_cost(4) .data(AssociatedData::new(&[0x04; 12]).unwrap()) .build() .unwrap() } /// ======================================= /// Argon2d version number 16 /// ======================================= /// Memory: 32 KiB, Iterations: 3, Parallelism: 4 lanes, Tag length: 32 bytes /// Password[32]: /// 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 /// 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 /// Salt[16]: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 /// Secret[8]: 03 03 03 03 03 03 03 03 /// Associated data[12]: 04 04 04 04 04 04 04 04 04 04 04 04 /// Pre-hashing digest: /// ec dc 26 dc 6b dd 21 56 19 68 97 aa 8c c9 a0 4c /// 03 ed 07 cd 12 92 67 c5 3c a6 ae f7 76 a4 30 89 /// 6a 09 80 54 e4 de c3 e0 2e cd 82 c4 7f 56 2c a2 /// 73 d2 f6 97 8a 5c 05 41 1a 0c d0 9d 47 7b 7b 06 /// Tag[32]: /// 96 a9 d4 e5 a1 73 40 92 c8 5e 29 f4 10 a4 59 14 /// a5 dd 1f 5c bf 08 b2 67 0d a6 8a 02 85 ab f3 2b #[test] fn argon2d_v0x10() { let algorithm = Algorithm::Argon2d; let version = Version::V0x10; let params = example_params(); let password = [0x01; 32]; let salt = [0x02; 16]; let secret = [0x03; 8]; let expected_tag = hex!( " 96 a9 d4 e5 a1 73 40 92 c8 5e 29 f4 10 a4 59 14 a5 dd 1f 5c bf 08 b2 67 0d a6 8a 02 85 ab f3 2b " ); let ctx = Argon2::new_with_secret(&secret, algorithm, version, params).unwrap(); let mut out = [0u8; 32]; ctx.hash_password_into(&password, &salt, &mut out).unwrap(); assert_eq!(out, expected_tag); } /// ======================================= /// Argon2i version number 16 /// ======================================= /// Memory: 32 KiB, Iterations: 3, Parallelism: 4 lanes, Tag length: 32 bytes /// Password[32]: /// 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 /// 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 /// Salt[16]: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 /// Secret[8]: 03 03 03 03 03 03 03 03 /// Associated data[12]: 04 04 04 04 04 04 04 04 04 04 04 04 /// Pre-hashing digest: /// 1c dc ec c8 58 ca 1b 6d 45 c7 3c 78 d0 00 76 c5 /// ec fc 5e df 14 45 b4 43 73 97 b1 b8 20 83 ff bf /// e3 c9 1a a8 f5 06 67 ad 8f b9 d4 e7 52 df b3 85 /// 34 71 9f ba d2 22 61 33 7b 2b 55 29 81 44 09 af /// Tag[32]: /// 87 ae ed d6 51 7a b8 30 cd 97 65 cd 82 31 ab b2 /// e6 47 a5 de e0 8f 7c 05 e0 2f cb 76 33 35 d0 fd #[test] fn argon2i_v0x10() { let algorithm = Algorithm::Argon2i; let version = Version::V0x10; let params = example_params(); let password = [0x01; 32]; let salt = [0x02; 16]; let secret = [0x03; 8]; let expected_tag = hex!( " 87 ae ed d6 51 7a b8 30 cd 97 65 cd 82 31 ab b2 e6 47 a5 de e0 8f 7c 05 e0 2f cb 76 33 35 d0 fd " ); let ctx = Argon2::new_with_secret(&secret, algorithm, version, params).unwrap(); let mut out = [0u8; 32]; ctx.hash_password_into(&password, &salt, &mut out).unwrap(); assert_eq!(out, expected_tag); } /// ======================================= /// Argon2id version number 16 /// ======================================= /// Memory: 32 KiB, Iterations: 3, Parallelism: 4 lanes, Tag length: 32 bytes /// Password[32]: /// 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 /// 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 /// Salt[16]: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 /// Secret[8]: 03 03 03 03 03 03 03 03 /// Associated data[12]: 04 04 04 04 04 04 04 04 04 04 04 04 /// Pre-hashing digest: /// 70 65 ab 9c 82 b5 f0 e8 71 28 c7 84 7a 02 1d 1e /// 59 aa 16 66 6f c8 b4 ef ac a3 86 3f bf d6 5e 0e /// 8b a6 f6 09 eb bc 9b 60 e2 78 22 c8 24 b7 50 6f /// b9 f9 5b e9 0e e5 84 2a ac 6e d6 b7 da 67 30 44 /// Tag[32]: /// b6 46 15 f0 77 89 b6 6b 64 5b 67 ee 9e d3 b3 77 /// ae 35 0b 6b fc bb 0f c9 51 41 ea 8f 32 26 13 c0 #[test] fn argon2id_v0x10() { let algorithm = Algorithm::Argon2id; let version = Version::V0x10; let params = example_params(); let password = [0x01; 32]; let salt = [0x02; 16]; let secret = [0x03; 8]; let expected_tag = hex!( " b6 46 15 f0 77 89 b6 6b 64 5b 67 ee 9e d3 b3 77 ae 35 0b 6b fc bb 0f c9 51 41 ea 8f 32 26 13 c0 " ); let ctx = Argon2::new_with_secret(&secret, algorithm, version, params).unwrap(); let mut out = [0u8; 32]; ctx.hash_password_into(&password, &salt, &mut out).unwrap(); assert_eq!(out, expected_tag); } /// ======================================= /// Argon2d version number 19 /// ======================================= /// Memory: 32 KiB /// Passes: 3 /// Parallelism: 4 lanes /// Tag length: 32 bytes /// Password[32]: /// 01 01 01 01 01 01 01 01 /// 01 01 01 01 01 01 01 01 /// 01 01 01 01 01 01 01 01 /// 01 01 01 01 01 01 01 01 /// Salt[16]: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 /// Secret[8]: 03 03 03 03 03 03 03 03 /// Associated data[12]: 04 04 04 04 04 04 04 04 04 04 04 04 /// Pre-hashing digest: /// b8 81 97 91 a0 35 96 60 /// bb 77 09 c8 5f a4 8f 04 /// d5 d8 2c 05 c5 f2 15 cc /// db 88 54 91 71 7c f7 57 /// 08 2c 28 b9 51 be 38 14 /// 10 b5 fc 2e b7 27 40 33 /// b9 fd c7 ae 67 2b ca ac /// 5d 17 90 97 a4 af 31 09 /// Tag[32]: /// 51 2b 39 1b 6f 11 62 97 /// 53 71 d3 09 19 73 42 94 /// f8 68 e3 be 39 84 f3 c1 /// a1 3a 4d b9 fa be 4a cb #[test] fn argon2d_v0x13() { let algorithm = Algorithm::Argon2d; let version = Version::V0x13; let params = example_params(); let password = [0x01; 32]; let salt = [0x02; 16]; let secret = [0x03; 8]; let expected_tag = hex!( " 51 2b 39 1b 6f 11 62 97 53 71 d3 09 19 73 42 94 f8 68 e3 be 39 84 f3 c1 a1 3a 4d b9 fa be 4a cb " ); let ctx = Argon2::new_with_secret(&secret, algorithm, version, params).unwrap(); let mut out = [0u8; 32]; ctx.hash_password_into(&password, &salt, &mut out).unwrap(); assert_eq!(out, expected_tag); } /// ======================================= /// Argon2i version number 19 /// ======================================= /// Memory: 32 KiB /// Passes: 3 /// Parallelism: 4 lanes /// Tag length: 32 bytes /// Password[32]: /// 01 01 01 01 01 01 01 01 /// 01 01 01 01 01 01 01 01 /// 01 01 01 01 01 01 01 01 /// 01 01 01 01 01 01 01 01 /// Salt[16]: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 /// Secret[8]: 03 03 03 03 03 03 03 03 /// Associated data[12]: 04 04 04 04 04 04 04 04 04 04 04 04 /// Pre-hashing digest: /// c4 60 65 81 52 76 a0 b3 /// e7 31 73 1c 90 2f 1f d8 /// 0c f7 76 90 7f bb 7b 6a /// 5c a7 2e 7b 56 01 1f ee /// ca 44 6c 86 dd 75 b9 46 /// 9a 5e 68 79 de c4 b7 2d /// 08 63 fb 93 9b 98 2e 5f /// 39 7c c7 d1 64 fd da a9 /// Tag[32]: /// c8 14 d9 d1 dc 7f 37 aa /// 13 f0 d7 7f 24 94 bd a1 /// c8 de 6b 01 6d d3 88 d2 /// 99 52 a4 c4 67 2b 6c e8 #[test] fn argon2i_v0x13() { let algorithm = Algorithm::Argon2i; let version = Version::V0x13; let params = example_params(); let password = [0x01; 32]; let salt = [0x02; 16]; let secret = [0x03; 8]; let expected_tag = hex!( " c8 14 d9 d1 dc 7f 37 aa 13 f0 d7 7f 24 94 bd a1 c8 de 6b 01 6d d3 88 d2 99 52 a4 c4 67 2b 6c e8 " ); let ctx = Argon2::new_with_secret(&secret, algorithm, version, params).unwrap(); let mut out = [0u8; 32]; ctx.hash_password_into(&password, &salt, &mut out).unwrap(); assert_eq!(out, expected_tag); } /// ======================================= /// Argon2id version number 19 /// ======================================= /// Memory: 32 KiB, Passes: 3, /// Parallelism: 4 lanes, Tag length: 32 bytes /// Password[32]: /// 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 /// 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 /// Salt[16]: 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 /// Secret[8]: 03 03 03 03 03 03 03 03 /// Associated data[12]: 04 04 04 04 04 04 04 04 04 04 04 04 /// Pre-hashing digest: /// 28 89 de 48 7e b4 2a e5 00 c0 00 7e d9 25 2f 10 /// 69 ea de c4 0d 57 65 b4 85 de 6d c2 43 7a 67 b8 /// 54 6a 2f 0a cc 1a 08 82 db 8f cf 74 71 4b 47 2e /// 94 df 42 1a 5d a1 11 2f fa 11 43 43 70 a1 e9 97 /// Tag[32]: /// 0d 64 0d f5 8d 78 76 6c 08 c0 37 a3 4a 8b 53 c9 /// d0 1e f0 45 2d 75 b6 5e b5 25 20 e9 6b 01 e6 59 #[test] fn argon2id_v0x13() { let algorithm = Algorithm::Argon2id; let version = Version::V0x13; let params = example_params(); let password = [0x01; 32]; let salt = [0x02; 16]; let secret = [0x03; 8]; let expected_tag = hex!( " 0d 64 0d f5 8d 78 76 6c 08 c0 37 a3 4a 8b 53 c9 d0 1e f0 45 2d 75 b6 5e b5 25 20 e9 6b 01 e6 59 " ); let ctx = Argon2::new_with_secret(&secret, algorithm, version, params).unwrap(); let mut out = [0u8; 32]; ctx.hash_password_into(&password, &salt, &mut out).unwrap(); assert_eq!(out, expected_tag); } // ======================================= // Basic error checks // ======================================= #[test] fn salt_bad_length() { let ctx = Argon2::new(Algorithm::Argon2id, Version::V0x13, example_params()); let mut out = [0u8; 32]; let too_short_salt = [0u8; argon2::MIN_SALT_LEN - 1]; let ret = ctx.hash_password_into(b"password", &too_short_salt, &mut out); assert_eq!(ret, Err(Error::SaltTooShort)); #[cfg(target_pointer_width = "64")] // MAX_SALT_LEN + 1 is too big for 32-bit targets { // 4 GiB of RAM seems big, but as long as we ask for a zero-initialized vector // optimizations kicks in an nothing is really allocated let too_long_salt = vec![0u8; argon2::MAX_SALT_LEN + 1]; let ret = ctx.hash_password_into(b"password", &too_long_salt, &mut out); assert_eq!(ret, Err(Error::SaltTooLong)); } } #[test] fn output_bad_length() { let ctx = Argon2::new(Algorithm::Argon2id, Version::V0x13, example_params()); let mut out = [0u8; Params::MIN_OUTPUT_LEN - 1]; let ret = ctx.hash_password_into(b"password", b"diffsalt", &mut out); assert_eq!(ret, Err(Error::OutputTooShort)); #[cfg(target_pointer_width = "64")] // MAX_SALT_LEN + 1 is too big for 32-bit targets { // 4 GiB of RAM seems big, but as long as we ask for a zero-initialized vector // optimizations kicks in an nothing is really allocated let mut out = vec![0u8; Params::MAX_OUTPUT_LEN + 1]; let ret = ctx.hash_password_into(b"password", b"diffsalt", &mut out); assert_eq!(ret, Err(Error::OutputTooLong)); } } // ======================================= // Reference implementation's test suite // ======================================= // Taken from https://github.com/P-H-C/phc-winner-argon2/blob/master/src/test.c #[allow(clippy::too_many_arguments)] fn hashtest( algorithm: Algorithm, version: Version, t: u32, m: u32, p: u32, pwd: &[u8], salt: &[u8], expected_raw_hash: [u8; 32], expected_phc_hash: &str, alternative_phc_hash: &str, ) { let params = ParamsBuilder::new() .t_cost(t) .m_cost(1 << m) .p_cost(p) .build() .unwrap(); let ctx = Argon2::new(algorithm, version, params); // Test raw hash let mut out = [0u8; 32]; ctx.hash_password_into(pwd, salt, &mut out).unwrap(); assert_eq!(out, expected_raw_hash); // Test hash encoding let salt_string = SaltString::encode_b64(salt).unwrap(); let phc_hash = ctx.hash_password(pwd, &salt_string).unwrap().to_string(); assert_eq!(phc_hash, expected_phc_hash); let hash = PasswordHash::new(alternative_phc_hash).unwrap(); assert!(Argon2::default().verify_password(pwd, &hash).is_ok()); } macro_rules! testcase_good { ($name: ident, $algorithm: expr, $version: expr, $t: expr, $m: expr, $p: expr, $pwd: expr, $salt: expr, $expected_raw: expr, $expected_phc: expr) => { #[test] fn $name() { hashtest( $algorithm, $version, $t, $m, $p, $pwd, $salt, $expected_raw, $expected_phc, $expected_phc, ) } }; ($name: ident, $algorithm: expr, $version: expr, $t: expr, $m: expr, $p: expr, $pwd: expr, $salt: expr, $expected_raw: expr, $expected_phc: expr, $alternative_phc: expr) => { #[test] fn $name() { hashtest( $algorithm, $version, $t, $m, $p, $pwd, $salt, $expected_raw, $expected_phc, $alternative_phc, ) } }; } macro_rules! ignored_testcase_good { ($name: ident, $algorithm: expr, $version: expr, $t: expr, $m: expr, $p: expr, $pwd: expr, $salt: expr, $expected_raw: expr, $expected_phc: expr, $alternative_phc: expr) => { #[test] #[ignore] fn $name() { hashtest( $algorithm, $version, $t, $m, $p, $pwd, $salt, $expected_raw, $expected_phc, $alternative_phc, ) } }; } /* Argon2i V0x10: Multiple test cases for various input values */ // TODO: If version is not provided, verifier incorrectly uses version 0x13 ignored_testcase_good!( reference_argon2i_v0x10_2_16_1, Algorithm::Argon2i, Version::V0x10, 2, 16, 1, b"password", b"somesalt", hex!("f6c4db4a54e2a370627aff3db6176b94a2a209a62c8e36152711802f7b30c694"), "$argon2i$v=16$m=65536,t=2,p=1$c29tZXNhbHQ$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", "$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ" ); // TODO: If version is not provided, verifier incorrectly uses version 0x13 #[ignore] #[cfg(test_large_ram)] testcase_good!( reference_argon2i_v0x10_2_20_1_large_ram, Algorithm::Argon2i, Version::V0x10, 2, 20, 1, b"password", b"somesalt", hex!("9690ec55d28d3ed32562f2e73ea62b02b018757643a2ae6e79528459de8106e9"), "$argon2i$v=16$m=1048576,t=2,p=1$c29tZXNhbHQ$lpDsVdKNPtMlYvLnPqYrArAYdXZDoq5ueVKEWd6BBuk", "$argon2i$m=1048576,t=2,p=1$c29tZXNhbHQ$lpDsVdKNPtMlYvLnPqYrArAYdXZDoq5ueVKEWd6BBuk" ); // TODO: If version is not provided, verifier incorrectly uses version 0x13 ignored_testcase_good!( reference_argon2i_v0x10_2_18_1, Algorithm::Argon2i, Version::V0x10, 2, 18, 1, b"password", b"somesalt", hex!("3e689aaa3d28a77cf2bc72a51ac53166761751182f1ee292e3f677a7da4c2467"), "$argon2i$v=16$m=262144,t=2,p=1$c29tZXNhbHQ$Pmiaqj0op3zyvHKlGsUxZnYXURgvHuKS4/Z3p9pMJGc", "$argon2i$m=262144,t=2,p=1$c29tZXNhbHQ$Pmiaqj0op3zyvHKlGsUxZnYXURgvHuKS4/Z3p9pMJGc" ); // TODO: If version is not provided, verifier incorrectly uses version 0x13 ignored_testcase_good!( reference_argon2i_v0x10_2_8_1, Algorithm::Argon2i, Version::V0x10, 2, 8, 1, b"password", b"somesalt", hex!("fd4dd83d762c49bdeaf57c47bdcd0c2f1babf863fdeb490df63ede9975fccf06"), "$argon2i$v=16$m=256,t=2,p=1$c29tZXNhbHQ$/U3YPXYsSb3q9XxHvc0MLxur+GP960kN9j7emXX8zwY", "$argon2i$m=256,t=2,p=1$c29tZXNhbHQ$/U3YPXYsSb3q9XxHvc0MLxur+GP960kN9j7emXX8zwY" ); // TODO: If version is not provided, verifier incorrectly uses version 0x13 ignored_testcase_good!( reference_argon2i_v0x10_2_8_2, Algorithm::Argon2i, Version::V0x10, 2, 8, 2, b"password", b"somesalt", hex!("b6c11560a6a9d61eac706b79a2f97d68b4463aa3ad87e00c07e2b01e90c564fb"), "$argon2i$v=16$m=256,t=2,p=2$c29tZXNhbHQ$tsEVYKap1h6scGt5ovl9aLRGOqOth+AMB+KwHpDFZPs", "$argon2i$m=256,t=2,p=2$c29tZXNhbHQ$tsEVYKap1h6scGt5ovl9aLRGOqOth+AMB+KwHpDFZPs" ); // TODO: If version is not provided, verifier incorrectly uses version 0x13 ignored_testcase_good!( reference_argon2i_v0x10_1_16_1, Algorithm::Argon2i, Version::V0x10, 1, 16, 1, b"password", b"somesalt", hex!("81630552b8f3b1f48cdb1992c4c678643d490b2b5eb4ff6c4b3438b5621724b2"), "$argon2i$v=16$m=65536,t=1,p=1$c29tZXNhbHQ$gWMFUrjzsfSM2xmSxMZ4ZD1JCytetP9sSzQ4tWIXJLI", "$argon2i$m=65536,t=1,p=1$c29tZXNhbHQ$gWMFUrjzsfSM2xmSxMZ4ZD1JCytetP9sSzQ4tWIXJLI" ); // TODO: If version is not provided, verifier incorrectly uses version 0x13 ignored_testcase_good!( reference_argon2i_v0x10_4_16_1, Algorithm::Argon2i, Version::V0x10, 4, 16, 1, b"password", b"somesalt", hex!("f212f01615e6eb5d74734dc3ef40ade2d51d052468d8c69440a3a1f2c1c2847b"), "$argon2i$v=16$m=65536,t=4,p=1$c29tZXNhbHQ$8hLwFhXm6110c03D70Ct4tUdBSRo2MaUQKOh8sHChHs", "$argon2i$m=65536,t=4,p=1$c29tZXNhbHQ$8hLwFhXm6110c03D70Ct4tUdBSRo2MaUQKOh8sHChHs" ); // TODO: If version is not provided, verifier incorrectly uses version 0x13 ignored_testcase_good!( reference_argon2i_v0x10_2_16_1_differentpassword, Algorithm::Argon2i, Version::V0x10, 2, 16, 1, b"differentpassword", b"somesalt", hex!("e9c902074b6754531a3a0be519e5baf404b30ce69b3f01ac3bf21229960109a3"), "$argon2i$v=16$m=65536,t=2,p=1$c29tZXNhbHQ$6ckCB0tnVFMaOgvlGeW69ASzDOabPwGsO/ISKZYBCaM", "$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ$6ckCB0tnVFMaOgvlGeW69ASzDOabPwGsO/ISKZYBCaM" ); // TODO: If version is not provided, verifier incorrectly uses version 0x13 ignored_testcase_good!( reference_argon2i_v0x10_2_16_1_diffsalt, Algorithm::Argon2i, Version::V0x10, 2, 16, 1, b"password", b"diffsalt", hex!("79a103b90fe8aef8570cb31fc8b22259778916f8336b7bdac3892569d4f1c497"), "$argon2i$v=16$m=65536,t=2,p=1$ZGlmZnNhbHQ$eaEDuQ/orvhXDLMfyLIiWXeJFvgza3vaw4kladTxxJc", "$argon2i$m=65536,t=2,p=1$ZGlmZnNhbHQ$eaEDuQ/orvhXDLMfyLIiWXeJFvgza3vaw4kladTxxJc" ); /* Argon2i V0x10: Error state tests */ // TODO: If version is not provided, verifier incorrectly uses version 0x13 #[ignore] #[test] fn reference_argon2i_v0x10_mismatching_hash() { /* Handle an mismatching hash (the encoded password is "passwore") */ let hash = PasswordHash::new( "$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ$b2G3seW+uPzerwQQC+/E1K50CLLO7YXy0JRcaTuswRo", ) .unwrap(); assert_eq!( Argon2::default().verify_password(b"password", &hash), Err(password_hash::errors::Error::Password) ); } /* Argon2i V0x13: Multiple test cases for various input values */ testcase_good!( reference_argon2i_v0x13_2_16_1, Algorithm::Argon2i, Version::V0x13, 2, 16, 1, b"password", b"somesalt", hex!("c1628832147d9720c5bd1cfd61367078729f6dfb6f8fea9ff98158e0d7816ed0"), "$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ$wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA" ); #[cfg(test_large_ram)] testcase_good!( reference_argon2i_v0x13_2_20_1, Algorithm::Argon2i, Version::V0x13, 2, 20, 1, b"password", b"somesalt", hex!("d1587aca0922c3b5d6a83edab31bee3c4ebaef342ed6127a55d19b2351ad1f41"), "$argon2i$v=19$m=1048576,t=2,p=1$c29tZXNhbHQ$0Vh6ygkiw7XWqD7asxvuPE667zQu1hJ6VdGbI1GtH0E" ); testcase_good!( reference_argon2i_v0x13_2_18_1, Algorithm::Argon2i, Version::V0x13, 2, 18, 1, b"password", b"somesalt", hex!("296dbae80b807cdceaad44ae741b506f14db0959267b183b118f9b24229bc7cb"), "$argon2i$v=19$m=262144,t=2,p=1$c29tZXNhbHQ$KW266AuAfNzqrUSudBtQbxTbCVkmexg7EY+bJCKbx8s" ); testcase_good!( reference_argon2i_v0x13_2_8_1, Algorithm::Argon2i, Version::V0x13, 2, 8, 1, b"password", b"somesalt", hex!("89e9029f4637b295beb027056a7336c414fadd43f6b208645281cb214a56452f"), "$argon2i$v=19$m=256,t=2,p=1$c29tZXNhbHQ$iekCn0Y3spW+sCcFanM2xBT63UP2sghkUoHLIUpWRS8" ); testcase_good!( reference_argon2i_v0x13_2_8_2, Algorithm::Argon2i, Version::V0x13, 2, 8, 2, b"password", b"somesalt", hex!("4ff5ce2769a1d7f4c8a491df09d41a9fbe90e5eb02155a13e4c01e20cd4eab61"), "$argon2i$v=19$m=256,t=2,p=2$c29tZXNhbHQ$T/XOJ2mh1/TIpJHfCdQan76Q5esCFVoT5MAeIM1Oq2E" ); testcase_good!( reference_argon2i_v0x13_1_16_1, Algorithm::Argon2i, Version::V0x13, 1, 16, 1, b"password", b"somesalt", hex!("d168075c4d985e13ebeae560cf8b94c3b5d8a16c51916b6f4ac2da3ac11bbecf"), "$argon2i$v=19$m=65536,t=1,p=1$c29tZXNhbHQ$0WgHXE2YXhPr6uVgz4uUw7XYoWxRkWtvSsLaOsEbvs8" ); testcase_good!( reference_argon2i_v0x13_4_16_1, Algorithm::Argon2i, Version::V0x13, 4, 16, 1, b"password", b"somesalt", hex!("aaa953d58af3706ce3df1aefd4a64a84e31d7f54175231f1285259f88174ce5b"), "$argon2i$v=19$m=65536,t=4,p=1$c29tZXNhbHQ$qqlT1YrzcGzj3xrv1KZKhOMdf1QXUjHxKFJZ+IF0zls" ); testcase_good!( reference_argon2i_v0x13_2_16_1_differentpassword, Algorithm::Argon2i, Version::V0x13, 2, 16, 1, b"differentpassword", b"somesalt", hex!("14ae8da01afea8700c2358dcef7c5358d9021282bd88663a4562f59fb74d22ee"), "$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ$FK6NoBr+qHAMI1jc73xTWNkCEoK9iGY6RWL1n7dNIu4" ); testcase_good!( reference_argon2i_v0x13_2_16_1_diffsalt, Algorithm::Argon2i, Version::V0x13, 2, 16, 1, b"password", b"diffsalt", hex!("b0357cccfbef91f3860b0dba447b2348cbefecadaf990abfe9cc40726c521271"), "$argon2i$v=19$m=65536,t=2,p=1$ZGlmZnNhbHQ$sDV8zPvvkfOGCw26RHsjSMvv7K2vmQq/6cxAcmxSEnE" ); #[test] fn reference_argon2i_v0x13_mismatching_hash() { /* Handle an mismatching hash (the encoded password is "passwore") */ let hash = PasswordHash::new( "$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ$8iIuixkI73Js3G1uMbezQXD0b8LG4SXGsOwoQkdAQIM", ) .unwrap(); assert_eq!( Argon2::default().verify_password(b"password", &hash), Err(password_hash::errors::Error::Password) ); } /* Argon2id V0x13: Multiple test cases for various input values */ testcase_good!( reference_argon2id_v0x13_2_16_1, Algorithm::Argon2id, Version::V0x13, 2, 16, 1, b"password", b"somesalt", hex!("09316115d5cf24ed5a15a31a3ba326e5cf32edc24702987c02b6566f61913cf7"), "$argon2id$v=19$m=65536,t=2,p=1$c29tZXNhbHQ$CTFhFdXPJO1aFaMaO6Mm5c8y7cJHAph8ArZWb2GRPPc" ); testcase_good!( reference_argon2id_v0x13_2_18_1, Algorithm::Argon2id, Version::V0x13, 2, 18, 1, b"password", b"somesalt", hex!("78fe1ec91fb3aa5657d72e710854e4c3d9b9198c742f9616c2f085bed95b2e8c"), "$argon2id$v=19$m=262144,t=2,p=1$c29tZXNhbHQ$eP4eyR+zqlZX1y5xCFTkw9m5GYx0L5YWwvCFvtlbLow" ); testcase_good!( reference_argon2id_v0x13_2_8_1, Algorithm::Argon2id, Version::V0x13, 2, 8, 1, b"password", b"somesalt", hex!("9dfeb910e80bad0311fee20f9c0e2b12c17987b4cac90c2ef54d5b3021c68bfe"), "$argon2id$v=19$m=256,t=2,p=1$c29tZXNhbHQ$nf65EOgLrQMR/uIPnA4rEsF5h7TKyQwu9U1bMCHGi/4" ); testcase_good!( reference_argon2id_v0x13_2_8_2, Algorithm::Argon2id, Version::V0x13, 2, 8, 2, b"password", b"somesalt", hex!("6d093c501fd5999645e0ea3bf620d7b8be7fd2db59c20d9fff9539da2bf57037"), "$argon2id$v=19$m=256,t=2,p=2$c29tZXNhbHQ$bQk8UB/VmZZF4Oo79iDXuL5/0ttZwg2f/5U52iv1cDc" ); testcase_good!( reference_argon2id_v0x13_1_16_1, Algorithm::Argon2id, Version::V0x13, 1, 16, 1, b"password", b"somesalt", hex!("f6a5adc1ba723dddef9b5ac1d464e180fcd9dffc9d1cbf76cca2fed795d9ca98"), "$argon2id$v=19$m=65536,t=1,p=1$c29tZXNhbHQ$9qWtwbpyPd3vm1rB1GThgPzZ3/ydHL92zKL+15XZypg" ); testcase_good!( reference_argon2id_v0x13_4_16_1, Algorithm::Argon2id, Version::V0x13, 4, 16, 1, b"password", b"somesalt", hex!("9025d48e68ef7395cca9079da4c4ec3affb3c8911fe4f86d1a2520856f63172c"), "$argon2id$v=19$m=65536,t=4,p=1$c29tZXNhbHQ$kCXUjmjvc5XMqQedpMTsOv+zyJEf5PhtGiUghW9jFyw" ); testcase_good!( reference_argon2id_v0x13_2_16_1_differentpassword, Algorithm::Argon2id, Version::V0x13, 2, 16, 1, b"differentpassword", b"somesalt", hex!("0b84d652cf6b0c4beaef0dfe278ba6a80df6696281d7e0d2891b817d8c458fde"), "$argon2id$v=19$m=65536,t=2,p=1$c29tZXNhbHQ$C4TWUs9rDEvq7w3+J4umqA32aWKB1+DSiRuBfYxFj94" ); testcase_good!( reference_argon2id_v0x13_2_16_1_diffsalt, Algorithm::Argon2id, Version::V0x13, 2, 16, 1, b"password", b"diffsalt", hex!("bdf32b05ccc42eb15d58fd19b1f856b113da1e9a5874fdcc544308565aa8141c"), "$argon2id$v=19$m=65536,t=2,p=1$ZGlmZnNhbHQ$vfMrBczELrFdWP0ZsfhWsRPaHppYdP3MVEMIVlqoFBw" );