1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 09:27:59 +00:00

Generalise the Montgomery-curve DH support.

This gets rid of the magic constants we apply to the top and bottom
bytes of the random data to make the Curve25519 private DH value. Or
rather, one of the magic constants is completely gone (we can infer it
from curve->fieldBits), and the other is moved into the curve
structure instead of being hardwired into the private-key-inventing
function.

With this change, it will be easy to add the similar Curve448 kex
method, because it's now just a matter of adding the protocol names
and curve constants.
This commit is contained in:
Simon Tatham 2019-03-23 07:45:02 +00:00
parent 319d4b5075
commit 7fa0749fcb
2 changed files with 14 additions and 5 deletions

1
ssh.h
View File

@ -451,6 +451,7 @@ struct ec_mcurve
{
MontgomeryCurve *mc;
MontgomeryPoint *G;
unsigned log2_cofactor;
};
/* Edwards form curve */

View File

@ -66,11 +66,12 @@ static void initialise_wcurve(
static void initialise_mcurve(
struct ec_curve *curve, mp_int *p, mp_int *a, mp_int *b,
mp_int *G_x)
mp_int *G_x, unsigned log2_cofactor)
{
initialise_common(curve, EC_MONTGOMERY, p);
curve->m.mc = ecc_montgomery_curve(p, a, b);
curve->m.log2_cofactor = log2_cofactor;
curve->m.G = ecc_montgomery_point_new(curve->m.mc, G_x);
}
@ -194,7 +195,7 @@ static struct ec_curve *ec_curve25519(void)
mp_int *a = MP_LITERAL(0x0000000000000000000000000000000000000000000000000000000000076d06);
mp_int *b = MP_LITERAL(0x0000000000000000000000000000000000000000000000000000000000000001);
mp_int *G_x = MP_LITERAL(0x0000000000000000000000000000000000000000000000000000000000000009);
initialise_mcurve(&curve, p, a, b, G_x);
initialise_mcurve(&curve, p, a, b, G_x, 3);
mp_free(p);
mp_free(a);
mp_free(b);
@ -1283,10 +1284,17 @@ static void ssh_ecdhkex_m_setup(ecdh_key *dh)
random_read(strbuf_append(bytes, dh->curve->fieldBytes),
dh->curve->fieldBytes);
bytes->u[0] &= 0xF8;
bytes->u[bytes->len-1] &= 0x7F;
bytes->u[bytes->len-1] |= 0x40;
dh->private = mp_from_bytes_le(ptrlen_from_strbuf(bytes));
/* Ensure the private key has the highest valid bit set, and no
* bits _above_ the highest valid one */
mp_reduce_mod_2to(dh->private, dh->curve->fieldBits);
mp_set_bit(dh->private, dh->curve->fieldBits - 1, 1);
/* Clear a curve-specific number of low bits */
for (unsigned bit = 0; bit < dh->curve->m.log2_cofactor; bit++)
mp_set_bit(dh->private, bit, 0);
strbuf_free(bytes);
dh->m_public = ecc_montgomery_multiply(dh->curve->m.G, dh->private);