Closed watason closed 6 months ago
The RFC has chosen to describe the compression function G
as accepting two 1024-byte inputs, however our implementation operates directly on two Block
s which are internally an array of 64-bit integers. In either case the input is permuted using P
which accepts an input of eight 16-byte registers.
The two are functionally equivalent. Also note our implementation predates the RFC and is based on the Argon2 paper / reference implementation.
@tarcieri Thank you for your prompt response!
The RFC has chosen to describe the compression function G as accepting two 1024-byte inputs, however our implementation operates directly on two Blocks which are internally an array of 64-bit integers. In either case the input is permuted using P which accepts an input of eight 16-byte registers.
Yes I am aware of this part.
The two are functionally equivalent. Also note our implementation predates the RFC and is based on the Argon2 paper / reference implementation.
I see, so the implementation is not updated according to the RFC. I am implementing Argon2 myself for study, It would be helpful if you could answer a few questions for future study.
I always refer to the implementation here. Sorry for the detailed question, but thank you in advance.
u64
. If we were to follow the RFC to the letter and use bytes, the distinction would likely be optimized away by the compiler.From the practical point of view, using [u64; N]
usually allows better optimizations than [u8; 8 * N]
because of higher alignment.
@tarcieri @newpavlov
Thank you for taking the time to answer these amateur questions!
I have read the PDF, but I have a specific question regarding the handling of 64-bit values in little-endian format.
Is there a difference between a regular u64
and a little-endian u64
? Do these differences affect the permutation P
?
Referring to this part of the paper on page 6:
where
• r is the pass number; <- 8 bytes
• l is the lane number; <- 8 bytes
• s is the slice number; <- 8 bytes
• m0 is the total number of memory blocks;
• t is the total number of passes;
• x is the type of the Argon function (equals 1 for Argon2i);
• i is the counter starting in each segment from 1.
All the numbers are put as little-endian. We increase the counter so that each application of G2 gives 128 64-bit values J1||J2.
I understand that the permutation P
is processed in u64
. I also understand that it is handled in u64
arrays instead of bytes.
My apologies for my poor English.
In other words:
G
?Thank you in advance.
The implementation is endianess-agnostic, i.e. it will produce the same result on BE and LE targets. We test the crate on both kinds. u64
does not have endianess per se, endianess matters during conversion u64
<-> [u8; 8]
. We do it by using to_le_bytes
/from_le_bytes
methods (grep the crate source code to see their uses). On BE machines they causes additional byte swapping, but it's a somewhat inevitable cost with how the algorithm is specified.
I see! So if you only put in the LE conversion when you BE, it will work optimally on that machine! I completely forgot about the actual environment.
Now I understand. Thank you so much!
Hi! I recently read the RFC, so I may be looking in the wrong place, but let me ask you a question. First. In RFC 3.4.1.2 Argon2i, the Z calculation is as follows
In contrast, in the code here (and other oss codes seemed to be similar), I think the following part is applicable.
https://github.com/RustCrypto/password-hashes/blob/master/argon2/src/lib.rs#L339-L357
In the other Little Endian convert part. For example, here
This is what the code looks like
Why is it that only the code for update_address_block does not do the conversion?
Thank you in advance.