|
|
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 |
|