IETF-SSH archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: ssh-ed25519 implementations
Hi Ron,
I have made some adjustments. Here is a unified diff of the relevant
changes to the .txt form of the draft. If the pseudo-code looks bad,
let me know if I should just remove it or not.
--- draft-ietf-curdle-ssh-curves-05.txt 2017-05-11 11:58:23.000000000 -0700
+++ draft-ietf-curdle-ssh-curves-06.txt 2017-05-13 07:46:54.000000000 -0700
@@ -140,47 +140,64 @@
only to be applicable to the scope of the mechanism described in this
document.
- The shared secret, K, is defined in [RFC4253] as a multiple precision
- integer (mpint). Curve25519/448 outputs a binary string X, which is
- the 32 or 56 byte point obtained by scalar multiplication of the
- other side's public key and the local private key scalar. The 32 or
- 56 bytes of X are converted into K by interpreting the bytes as an
- unsigned fixed-length integer encoded in network byte order. This
- conversion follows the normal "mpint" process as described in section
- 5 of [RFC4251].
+ The shared secret, K, is defined in [RFC4253] and [RFC5656] as an
+ integer encoded as a multiple precision integer (mpint).
+ Curve25519/448 outputs a binary string X, which is the 32 or 56 byte
+ point obtained by scalar multiplication of the other side's public
+ key and the local private key scalar. The 32 or 56 bytes of X are
+ converted into K by interpreting the octets as an unsigned fixed-
+ length integer encoded in network byte order.
+
+ The fixed-length integer is then minimized into the minimum number of
+ octets to represent a positve mpint. This conversion follows the
+ normal "mpint" process as described in section 5 of [RFC4251] which
+ requires that unnecessary leading bytes with the value 0 MUST NOT be
+ included. The length of the integer is then prepended with a 4 octet
+ big-endian integer which is the length in octets of the minimized K.
+
+ The mpint K is then fed along with other data to the key exchange
+ method's hash function to generate encryption keys.
To clarify a corner-case in this conversion, when X is encoded as an
mpint K, in order to calculate the exchange hash, it may vary as
follows:
- o Trim all leading zero-bytes of X. If X is all zero-bytes, then
- the key exchange MUST fail.
-
- o If the high bit of X is set, the mpint format requires a zero byte
- to be prepended.
-
- o The length of the encoded K may not be the same as the original
- length of X due to trimming or prepending zero-bytes as needed for
- "mpint" format.
- Or, as pseudo code:
+ o Trim all leading zero-bytes of X, as required in section 5 of
+ [RFC4251]. If X is all zero-bytes, then the key exchange MUST
+ fail as required in section 6 of [RFC7748].
+
+ o Given X is a positive, if the MSB of X is set, then the "mpint"
+ format requires a zero-byte to be prepended.
+
+ o The length of the "mpint" form of K may not be the same as the
+ original length of X due to trimming or prepending zero-byte
+ values as needed for "mpint" format. prepend K with the big-endian
+ number of octets for the length of K.
+
+ Or, as pseudo code (without dealing with side-channel issues):
k := x;
- while (k.length() > 0 && k[0] == 0) k = k[1:];
+ while (k.length() > 0 && k[0] == 0) k := k[1:];
assert(k.length() > 0);
- if 0 != (k[0] & 0x80) k = '\0' .. k;
+ if 0 != (k[0] & 0x80) k := '\0' .. k;
+ l[0] := k.lengh() >> 24;
+ l[1] := (k.lengh() >> 16) & 0xff;
+ l[2] := (k.lengh() >> 8) & 0xff;
+ l[3] := k.lengh() & 0xff;
+ k := l .. k;
Figure 1
When performing the X25519 or X448 operations, the integer values
- there will be encoded into byte strings by doing a fix-length
+ there will be encoded into byte strings by doing a fixed-length
unsigned litle-endian conversion, per [RFC7748]. It is only later
when these byte strings are then passed to the ECDH code in SSH that
the bytes are re-interpreted as a fixed-length unsigned big-endian
Home |
Main Index |
Thread Index |
Old Index