Closed kroggen closed 4 years ago
Thanks for taking a thorough look at our implementation!
I can't speak to Leo's implementation, but I believe the implementation we are using in algod
(our fork of libsodium) stores c
in the least significant bits. In particular, in the file you pointed to, c_scalar
is used below in line 112 and passed to the sc25519_muladd
function. I believe that c_scalar
is interpreted as a little-endian 256-bit number inside of that function and so the first 16 bytes in memory are treated as the 16 least significant bytes in that finite-field element computation, in accordance with the IETF draft (2n=32 for curve25519 (section 5.5) so n=16 bytes are output by ECVRF hash points (section 5.4.3)).
Likewise, I believe the ge25519_scalarmult
routine in verify
also interprets c_scalar
as a little-endian integer.
Does this make sense, or are we missing something here?
(@algoradam)
Hi Derek,
I thought that the libsodium used big endian numbers on their scalar computations.
My mistake.
Thank you for your clarification!
Hi!
I know that Silvio Micalli was one of the creators of VRFs. But your VRF implementation appears to differ from the IETF draft in one part:
The
prove
function stores the C number in the most significant bits of a 32-byte scalar instead of the least significant bits, as we can see here and hereThe proof if verified correctly because this is done so in the
prove
as in theverify
function.But the IETF draft appears to consider the
c scalar
as a number with only the least significant bits being used.The reference implementation appears to use only the LSB too as we can see here and here
I would like to know if this difference in your implementation is intentional or not, or if there is no difference and I am misunderstanding the IETF document.
If there is difference, what is the purpose of it? Does it help to protect the private key in some way?
Cheers,