From 141b75a71abe8bcc8dc891ac7b68a772be644e32 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Fri, 28 Feb 2020 19:25:13 +0000 Subject: [PATCH] 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. --- ecc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ecc.c b/ecc.c index 82fd14d9..857fc024 100644 --- a/ecc.c +++ b/ecc.c @@ -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); }