From: Loup Vaillant Date: Thu, 27 Jul 2023 10:36:13 +0000 (+0200) Subject: Fix Argon2 multiple lanes bug X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=50b1e0f274a1493ac3aac3965fad66e544187666;p=Monocypher.git Fix Argon2 multiple lanes bug Argon2 failed to conform to the reference implementation when used with multiple lanes, rendering it useless for this compatibility use case. The error came from the way we select the reference set: - On the first slice of the first pass, only the current lane is valid. - When selecting other lanes, only fully completed segments are valid. - The previous block of *all* lanes must be excluded. Fixes #263 --- diff --git a/src/monocypher.c b/src/monocypher.c index 11de568..9423b08 100644 --- a/src/monocypher.c +++ b/src/monocypher.c @@ -863,16 +863,22 @@ void crypto_argon2(u8 *hash, u32 hash_size, void *work_area, u32 next_slice = ((slice + 1) % 4) * segment_size; u32 window_start = pass == 0 ? 0 : next_slice; u32 nb_segments = pass == 0 ? slice : 3; - u32 window_size = nb_segments * segment_size + block - 1; + u64 lane = + pass == 0 && slice == 0 + ? segment + : (index_seed >> 32) % config.nb_lanes; + u32 window_size = + nb_segments * segment_size + + (lane == segment ? block-1 : + block == 0 ? (u32)-1 : 0); // Find reference block u64 j1 = index_seed & 0xffffffff; // block selector - u64 j2 = index_seed >> 32; // lane selector u64 x = (j1 * j1) >> 32; u64 y = (window_size * x) >> 32; u64 z = (window_size - 1) - y; u64 ref = (window_start + z) % lane_size; - u32 index = (j2%config.nb_lanes)*lane_size + (u32)ref; + u32 index = lane * lane_size + (u32)ref; blk *reference = blocks + index; // Shuffle the previous & reference block diff --git a/tests/gen/vectors/argon2 b/tests/gen/vectors/argon2 index d57614e..c111670 100644 --- a/tests/gen/vectors/argon2 +++ b/tests/gen/vectors/argon2 @@ -60,3 +60,17 @@ c814d9d1dc7f37aa13f0d77f2494bda1c8de6b016dd388d29952a4c4672b6ce8: 0303030303030303: 040404040404040404040404: 0d640df58d78766c08c037a34a8b53c9d01ef0452d75b65eb52520e96b01e659: + +# +# This one was modified from the RFC (Argon2d) to 2 lanes, +# which is enough to trigger the reference set error +# +0000000000000000: +2000000000000000: +0300000000000000: +0200000000000000: +0101010101010101010101010101010101010101010101010101010101010101: +02020202020202020202020202020202: +0303030303030303: +040404040404040404040404: +c53c3e988d88e8c37b322e3302d273f4847eb058bf06449f647ea6396f14e87c: