Blame SOURCES/CheckForPeqQ-or-PnoteqQ-before-adding-P-and-Q.patch

716a00
# HG changeset patch
716a00
# User Wan-Teh Chang <wtc@google.com>
716a00
# Date 1430759760 25200
716a00
# Node ID 2c05e861ce070a1c29083b00f987cc930974909d
716a00
# Parent  ca159a08d006b28aff5b66545f9782a4a0e53349
716a00
Bug 1125025: Check for P == Q or P == -Q before adding P and Q.
716a00
Check for P == -P before doubling P. r=rrelyea.
716a00
716a00
diff --git a/lib/freebl/ecl/ecp_jac.c b/lib/freebl/ecl/ecp_jac.c
716a00
--- a/lib/freebl/ecl/ecp_jac.c
716a00
+++ b/lib/freebl/ecl/ecp_jac.c
716a00
@@ -139,16 +139,30 @@ ec_GFp_pt_add_jac_aff(const mp_int *px, 
716a00
 	MP_CHECKOK(group->meth->field_mul(&A, pz, &B, group->meth));
716a00
 	MP_CHECKOK(group->meth->field_mul(&A, qx, &A, group->meth));
716a00
 	MP_CHECKOK(group->meth->field_mul(&B, qy, &B, group->meth));
716a00
 
716a00
 	/* C = A - px, D = B - py */
716a00
 	MP_CHECKOK(group->meth->field_sub(&A, px, &C, group->meth));
716a00
 	MP_CHECKOK(group->meth->field_sub(&B, py, &D, group->meth));
716a00
 
716a00
+	if (mp_cmp_z(&C) == 0) {
716a00
+		/* P == Q or P == -Q */
716a00
+		if (mp_cmp_z(&D) == 0) {
716a00
+			/* P == Q */
716a00
+			/* It is cheaper to double (qx, qy, 1) than (px, py, pz). */
716a00
+			MP_DIGIT(&D, 0) = 1; /* Set D to 1. */
716a00
+			MP_CHECKOK(ec_GFp_pt_dbl_jac(qx, qy, &D, rx, ry, rz, group));
716a00
+		} else {
716a00
+			/* P == -Q */
716a00
+			MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
716a00
+		}
716a00
+		goto CLEANUP;
716a00
+	}
716a00
+
716a00
 	/* C2 = C^2, C3 = C^3 */
716a00
 	MP_CHECKOK(group->meth->field_sqr(&C, &C2, group->meth));
716a00
 	MP_CHECKOK(group->meth->field_mul(&C, &C2, &C3, group->meth));
716a00
 
716a00
 	/* rz = pz * C */
716a00
 	MP_CHECKOK(group->meth->field_mul(pz, &C, rz, group->meth));
716a00
 
716a00
 	/* C = px * C^2 */
716a00
@@ -200,17 +214,18 @@ ec_GFp_pt_dbl_jac(const mp_int *px, cons
716a00
 	MP_DIGITS(&t1) = 0;
716a00
 	MP_DIGITS(&M) = 0;
716a00
 	MP_DIGITS(&S) = 0;
716a00
 	MP_CHECKOK(mp_init(&t0));
716a00
 	MP_CHECKOK(mp_init(&t1));
716a00
 	MP_CHECKOK(mp_init(&M);;
716a00
 	MP_CHECKOK(mp_init(&S);;
716a00
 
716a00
-	if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
716a00
+	/* P == inf or P == -P */
716a00
+	if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES || mp_cmp_z(py) == 0) {
716a00
 		MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
716a00
 		goto CLEANUP;
716a00
 	}
716a00
 
716a00
 	if (mp_cmp_d(pz, 1) == 0) {
716a00
 		/* M = 3 * px^2 + a */
716a00
 		MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
716a00
 		MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
716a00
716a00