algorand / go-algorand

Algorand's official implementation in Go.
https://developer.algorand.org/
Other
1.35k stars 470 forks source link

VRF implementation and IETF draft #775

Closed kroggen closed 4 years ago

kroggen commented 4 years ago

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 here

The proof if verified correctly because this is done so in the prove as in the verify 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,

derbear commented 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)

kroggen commented 4 years ago

Hi Derek,

I thought that the libsodium used big endian numbers on their scalar computations.

My mistake.

Thank you for your clarification!