Latest update.
This commit is contained in:
@@ -912,6 +912,7 @@ static void point_add(felem x3, felem y3, felem z3,
|
||||
felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
|
||||
widefelem tmp, tmp2;
|
||||
limb z1_is_zero, z2_is_zero, x_equal, y_equal;
|
||||
limb points_equal;
|
||||
|
||||
if (!mixed) {
|
||||
/* ftmp2 = z2^2 */
|
||||
@@ -968,15 +969,41 @@ static void point_add(felem x3, felem y3, felem z3,
|
||||
felem_reduce(ftmp, tmp);
|
||||
|
||||
/*
|
||||
* the formulae are incorrect if the points are equal so we check for
|
||||
* this and do doubling if this happens
|
||||
* The formulae are incorrect if the points are equal, in affine coordinates
|
||||
* (X_1, Y_1) == (X_2, Y_2), so we check for this and do doubling if this
|
||||
* happens.
|
||||
*
|
||||
* We use bitwise operations to avoid potential side-channels introduced by
|
||||
* the short-circuiting behaviour of boolean operators.
|
||||
*/
|
||||
x_equal = felem_is_zero(ftmp);
|
||||
y_equal = felem_is_zero(ftmp3);
|
||||
/*
|
||||
* The special case of either point being the point at infinity (z1 and/or
|
||||
* z2 are zero), is handled separately later on in this function, so we
|
||||
* avoid jumping to point_double here in those special cases.
|
||||
*/
|
||||
z1_is_zero = felem_is_zero(z1);
|
||||
z2_is_zero = felem_is_zero(z2);
|
||||
/* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */
|
||||
if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
|
||||
|
||||
/*
|
||||
* Compared to `ecp_nistp256.c` and `ecp_nistp521.c`, in this
|
||||
* specific implementation `felem_is_zero()` returns truth as `0x1`
|
||||
* (rather than `0xff..ff`).
|
||||
*
|
||||
* This implies that `~true` in this implementation becomes
|
||||
* `0xff..fe` (rather than `0x0`): for this reason, to be used in
|
||||
* the if expression, we mask out only the last bit in the next
|
||||
* line.
|
||||
*/
|
||||
points_equal = (x_equal & y_equal & (~z1_is_zero) & (~z2_is_zero)) & 1;
|
||||
|
||||
if (points_equal) {
|
||||
/*
|
||||
* This is obviously not constant-time but, as mentioned before, this
|
||||
* case never happens during single point multiplication, so there is no
|
||||
* timing leak for ECDH or ECDSA signing.
|
||||
*/
|
||||
point_double(x3, y3, z3, x1, y1, z1);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user