Re: ssh-ed25519 implementations

Stefan Bühler <[email protected]> Thu, 11 May 2017 15:15:31 +0200
Newsgroups gmane.ietf.curdle,gmane.ietf.secsh
Message-ID <[email protected]>
Hi,

On 05/10/2017 06:18 PM, Mark Baushke wrote:
> Hi,
> 
> Eric Rescorla <[email protected]> has brought to my attention that in
> https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves-04 it is
> currently specifying the SSH encoding of secrets on the wire using the
> mpint process as described in section 5 of [RFC4251] while RFC 7748
> describes using a little-endian format:
> 
>   GF(2^448 - 2^224 - 1) and are encoded as an array of bytes, u,
>   in little-endian order such that u[0] + 256*u[1] + 256^2*u[2] + ... +
> 
> This seems to be what is being implemeneted for
> [email protected], so I should make
> an explicit note of this in the draft.

While we are on the topic of converting the shared secret bytes X
generated by Curve* to an mpint, I'd like to point out that the
draft-ietf-curdle-ssh-curves-04 is not clear regarding leading zeroes:

>    If X has leading zero bytes, the mpint format requires such bytes
>    to be skipped.  In this case, the length of the encoded K will be
>    smaller.

If X has one leading zero byte, and the highest bit of the second byte
is set, K will be exactly X, not shorter.

Maybe it would be better to describe an algorithm for the conversion, like:

- trim all leading zero bytes
- at least one byte must remain ("Clients and servers MUST fail the key
  exchange if [...], or if the derived shared secret only consists of
  zero bits.")
- if the highest bit of the first byte of the remaining string is set,
  prepend one zero byte

Or as pseudo code:

    k := x;
    while (k.length() > 0 && k[0] == 0) k = k[1:];
    assert(k.length() > 0);
    if 0 != (k[0] & 0x80) k = '\0' .. k;

cheers,
Stefan