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

Preserve zero denominators in ECC point normalisation.

ecc_montgomery_normalise takes a point with X and Z coordinates, and
normalises it to Z=1 by means of multiplying X by the inverse of Z and
then setting Z=1.

If you pass in a point with Z=0, representing the curve identity, then
it would be nice to still get the identity back out again afterwards.
We haven't really needed that property until now, but I'm about to
want it.

Currently, what happens is that we try to invert Z mod p; fail, but
don't notice we've failed, and come out with some nonsense value as
the inverse; multiply X by that; and then _set Z to 1_. So the output
value no longer has Z=0.

This commit changes things so that we multiply Z by the inverse we
computed. That way, if Z started off 0, it stays 0.

Also made the same change in the other two curve types, on general
principles, though I don't yet have a use for that.
This commit is contained in:
Simon Tatham 2020-02-28 19:25:13 +00:00
parent 0645824e4d
commit 141b75a71a

6
ecc.c
View File

@ -486,10 +486,10 @@ static void ecc_weierstrass_normalise(WeierstrassPoint *wp)
mp_int *zinv3 = monty_mul(wc->mc, zinv2, zinv);
monty_mul_into(wc->mc, wp->X, wp->X, zinv2);
monty_mul_into(wc->mc, wp->Y, wp->Y, zinv3);
monty_mul_into(wc->mc, wp->Z, wp->Z, zinv);
mp_free(zinv);
mp_free(zinv2);
mp_free(zinv3);
mp_copy_into(wp->Z, monty_identity(wc->mc));
}
void ecc_weierstrass_get_affine(
@ -759,8 +759,8 @@ static void ecc_montgomery_normalise(MontgomeryPoint *mp)
MontgomeryCurve *mc = mp->mc;
mp_int *zinv = monty_invert(mc->mc, mp->Z);
monty_mul_into(mc->mc, mp->X, mp->X, zinv);
monty_mul_into(mc->mc, mp->Z, mp->Z, zinv);
mp_free(zinv);
mp_copy_into(mp->Z, monty_identity(mc->mc));
}
MontgomeryPoint *ecc_montgomery_multiply(MontgomeryPoint *B, mp_int *n)
@ -1083,8 +1083,8 @@ static void ecc_edwards_normalise(EdwardsPoint *ep)
mp_int *zinv = monty_invert(ec->mc, ep->Z);
monty_mul_into(ec->mc, ep->X, ep->X, zinv);
monty_mul_into(ec->mc, ep->Y, ep->Y, zinv);
monty_mul_into(ec->mc, ep->Z, ep->Z, zinv);
mp_free(zinv);
mp_copy_into(ep->Z, monty_identity(ec->mc));
monty_mul_into(ec->mc, ep->T, ep->X, ep->Y);
}