mit-plv/fiat-crypto

Mask most significant bit in from_bytes

Opened this issue · 2 comments

The function from_bytes, at least for curve25519, doesn't mask the most significant bit:

x1 = ((uint64_t)(arg1[31]) << 44);

In practice, this function is often used as part of point decompression, where the most significant bit is set to determine the sign of the other coordinate, so it'd be nice to "disregard" the msb.

The fix is straightforward:

x1 = ((uint64_t)(arg1[31] & 0x7F) << 44);
                          ^^^^^^

In addition, right now this limitation forces the caller to either make the input buffer writeable (to zero the bit), or to copy the buffer (example in dalek). Both seem undesirable.

The proposed change is compatible with the current spec which already assumes truncated input. I don't have a clear intuition about where to apply it though. Do you think the same concept should also be applied to other finite fields, or is this a curve25519 special?

To my knowledge that's a typical way to encode points, not just for curve25519, but also for secp, secp256k1, etc. Also, it shouldn't hurt even if one is just using the field.