[noise] Invalid point attacks

Jason A. Donenfeld Jason at zx2c4.com
Thu Mar 30 14:13:28 PDT 2017


On Thu, Mar 30, 2017 at 11:03 PM, Trevor Perrin <trevp at trevp.net> wrote:
> On Thu, Mar 30, 2017 at 1:52 PM, Jason A. Donenfeld <Jason at zx2c4.com> wrote:
>> On Thu, Mar 30, 2017 at 6:37 PM, Trevor Perrin <trevp at trevp.net> wrote:
>>>> 1. It prevents accidents in which a peer might shoot himself in the
>>>> foot with a bad RNG for ephemerals and/or bad static key.
>>>
>>> It doesn't prevent that.  A low-entropy private key multiplied by the
>>> base point is still a valid public key.
>>
>> Yea obviously. But usually when RNGs fail, they wind up just returning
>> all zeros. By "usual" I mean the majority of things I've dealt with in
>> the wild. Since it's nearly free (quick comparison of 4 qwords) to
>> implement, this seems like a nice failsafe.
>
> Typically X25519 and X448 private scalars are created by taking some
> RNG output, then setting some high and low bits ("clamping").  This
> clamping would turn an all-zeros RNG output into a non-zero scalar.
>
> So even if you assume all-zeros RNG output is a common failure (I'm
> not sure about that), the check you're recommending would not catch
> that.

What I'm suggesting is comparing the output of curve25519 -- the
product -- to the null string and aborting the handshake if the output
is null, in the same way that the handshake is aborted if an aead
doesn't authenticate. At first I thought you misunderstood me, but
then I checked what you wrote:

DH(private, public_zero) = 0
DH(private, CLAMP(public_zero)) != 0

So, you raise a good point.


More information about the Noise mailing list