From 55e7fc32cb0d0c57b75cc4fc00c2f9c1e201ff0e Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sat, 4 Jul 2015 14:32:39 +0930 Subject: [PATCH 1/5] Perf. improvement in _gej_add_ge - Avoid one weak normalization - Change one full normalization to weak - Avoid unnecessary fe assignment - Update magnitude annotations --- src/group_impl.h | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/group_impl.h b/src/group_impl.h index 2da89097930..05599be1e21 100644 --- a/src/group_impl.h +++ b/src/group_impl.h @@ -461,7 +461,7 @@ static void secp256k1_gej_add_zinv_var(secp256k1_gej_t *r, const secp256k1_gej_t static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) { - /* Operations: 7 mul, 5 sqr, 5 normalize, 17 mul_int/add/negate/cmov */ + /* Operations: 7 mul, 5 sqr, 4 normalize, 17 mul_int/add/negate/cmov */ static const secp256k1_fe_t fe_1 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); secp256k1_fe_t zz, u1, u2, s1, s2, z, t, tt, m, n, q, rr; secp256k1_fe_t m_alt, rr_alt; @@ -557,23 +557,21 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c * so M^3 * Malt is either Malt^4 (which is computed by squaring), or * zero (which is "computed" by cmov). So the cost is one squaring * versus two multiplications. */ - secp256k1_fe_sqr(&n, &n); /* n = M^3 * Malt (1) */ - secp256k1_fe_cmov(&n, &m, degenerate); - secp256k1_fe_normalize_weak(&n); + secp256k1_fe_sqr(&n, &n); + secp256k1_fe_cmov(&n, &m, degenerate); /* n = M^3 * Malt (2) */ secp256k1_fe_sqr(&t, &rr_alt); /* t = Ralt^2 (1) */ secp256k1_fe_mul(&r->z, &m_alt, &z); /* r->z = Malt*Z (1) */ infinity = secp256k1_fe_normalizes_to_zero(&r->z) * (1 - a->infinity); secp256k1_fe_mul_int(&r->z, 2); /* r->z = Z3 = 2*Malt*Z (2) */ - r->x = t; /* r->x = Ralt^2 (1) */ secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */ - secp256k1_fe_add(&r->x, &q); /* r->x = Ralt^2-Q (3) */ - secp256k1_fe_normalize(&r->x); - t = r->x; + secp256k1_fe_add(&t, &q); /* t = Ralt^2-Q (3) */ + secp256k1_fe_normalize_weak(&t); + r->x = t; /* r->x = Ralt^2-Q (1) */ secp256k1_fe_mul_int(&t, 2); /* t = 2*x3 (2) */ - secp256k1_fe_add(&t, &q); /* t = 2*x3 - Q: (8) */ + secp256k1_fe_add(&t, &q); /* t = 2*x3 - Q: (4) */ secp256k1_fe_mul(&t, &t, &rr_alt); /* t = Ralt*(2*x3 - Q) (1) */ - secp256k1_fe_add(&t, &n); /* t = Ralt*(2*x3 - Q) + M^3*Malt (2) */ - secp256k1_fe_negate(&r->y, &t, 2); /* r->y = Ralt*(Q - 2x3) - M^3*Malt (3) */ + secp256k1_fe_add(&t, &n); /* t = Ralt*(2*x3 - Q) + M^3*Malt (3) */ + secp256k1_fe_negate(&r->y, &t, 3); /* r->y = Ralt*(Q - 2x3) - M^3*Malt (4) */ secp256k1_fe_normalize_weak(&r->y); secp256k1_fe_mul_int(&r->x, 4); /* r->x = X3 = 4*(Ralt^2-Q) */ secp256k1_fe_mul_int(&r->y, 4); /* r->y = Y3 = 4*Ralt*(Q - 2x3) - 4*M^3*Malt (4) */ From b28d02a5d5b9b1b622207b372cf44a7c8efd23f7 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sat, 4 Jul 2015 16:30:56 +0930 Subject: [PATCH 2/5] Refactor to remove a local var --- src/group_impl.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/group_impl.h b/src/group_impl.h index 05599be1e21..589f33728e7 100644 --- a/src/group_impl.h +++ b/src/group_impl.h @@ -463,7 +463,7 @@ static void secp256k1_gej_add_zinv_var(secp256k1_gej_t *r, const secp256k1_gej_t static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) { /* Operations: 7 mul, 5 sqr, 4 normalize, 17 mul_int/add/negate/cmov */ static const secp256k1_fe_t fe_1 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_fe_t zz, u1, u2, s1, s2, z, t, tt, m, n, q, rr; + secp256k1_fe_t zz, u1, u2, s1, s2, t, tt, m, n, q, rr; secp256k1_fe_t m_alt, rr_alt; int infinity, degenerate; VERIFY_CHECK(!b->infinity); @@ -525,7 +525,6 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */ secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z2^2 (1) */ secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */ - z = a->z; /* z = Z = Z1*Z2 (8) */ t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (2) */ m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (2) */ secp256k1_fe_sqr(&rr, &t); /* rr = T^2 (1) */ @@ -560,7 +559,7 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c secp256k1_fe_sqr(&n, &n); secp256k1_fe_cmov(&n, &m, degenerate); /* n = M^3 * Malt (2) */ secp256k1_fe_sqr(&t, &rr_alt); /* t = Ralt^2 (1) */ - secp256k1_fe_mul(&r->z, &m_alt, &z); /* r->z = Malt*Z (1) */ + secp256k1_fe_mul(&r->z, &a->z, &m_alt); /* r->z = Malt*Z (1) */ infinity = secp256k1_fe_normalizes_to_zero(&r->z) * (1 - a->infinity); secp256k1_fe_mul_int(&r->z, 2); /* r->z = Z3 = 2*Malt*Z (2) */ secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */ From 7d054cd030ab81d484ef8f98efdbd34e2e1781b5 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sat, 4 Jul 2015 16:38:46 +0930 Subject: [PATCH 3/5] Refactor to save a _fe_negate --- src/group_impl.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/group_impl.h b/src/group_impl.h index 589f33728e7..f2268f9e548 100644 --- a/src/group_impl.h +++ b/src/group_impl.h @@ -461,7 +461,7 @@ static void secp256k1_gej_add_zinv_var(secp256k1_gej_t *r, const secp256k1_gej_t static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) { - /* Operations: 7 mul, 5 sqr, 4 normalize, 17 mul_int/add/negate/cmov */ + /* Operations: 7 mul, 5 sqr, 4 normalize, 22 mul_int/add/negate/cmov */ static const secp256k1_fe_t fe_1 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); secp256k1_fe_t zz, u1, u2, s1, s2, t, tt, m, n, q, rr; secp256k1_fe_t m_alt, rr_alt; @@ -528,8 +528,9 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (2) */ m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (2) */ secp256k1_fe_sqr(&rr, &t); /* rr = T^2 (1) */ - secp256k1_fe_mul(&tt, &u1, &u2); secp256k1_fe_negate(&tt, &tt, 1); /* tt = -U1*U2 (2) */ - secp256k1_fe_add(&rr, &tt); /* rr = R = T^2-U1*U2 (3) */ + secp256k1_fe_negate(&m_alt, &u2, 1); /* m = -X2*Z1^2 */ + secp256k1_fe_mul(&tt, &u1, &m_alt); /* tt = -U1*U2 (2) */ + secp256k1_fe_add(&rr, &tt); /* rr = R = T^2-U1*U2 (3) */ /** If lambda = R/M = 0/0 we have a problem (except in the "trivial" * case that Z = z1z2 = 0, and this is special-cased later on). */ degenerate = secp256k1_fe_normalizes_to_zero(&m) & @@ -541,7 +542,6 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c * so we set R/M equal to this. */ secp256k1_fe_negate(&rr_alt, &s2, 1); /* rr = -Y2*Z1^3 */ secp256k1_fe_add(&rr_alt, &s1); /* rr = Y1*Z2^3 - Y2*Z1^3 */ - secp256k1_fe_negate(&m_alt, &u2, 1); /* m = -X2*Z1^2 */ secp256k1_fe_add(&m_alt, &u1); /* m = X1*Z2^2 - X2*Z1^2 */ secp256k1_fe_cmov(&rr_alt, &rr, !degenerate); From a5d796e0b1337284f20428aee272901ea10b0795 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 7 Jul 2015 09:16:15 +0930 Subject: [PATCH 4/5] Update code comments --- src/group_impl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/group_impl.h b/src/group_impl.h index f2268f9e548..b6076db6cd7 100644 --- a/src/group_impl.h +++ b/src/group_impl.h @@ -528,7 +528,7 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (2) */ m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (2) */ secp256k1_fe_sqr(&rr, &t); /* rr = T^2 (1) */ - secp256k1_fe_negate(&m_alt, &u2, 1); /* m = -X2*Z1^2 */ + secp256k1_fe_negate(&m_alt, &u2, 1); /* Malt = -X2*Z1^2 */ secp256k1_fe_mul(&tt, &u1, &m_alt); /* tt = -U1*U2 (2) */ secp256k1_fe_add(&rr, &tt); /* rr = R = T^2-U1*U2 (3) */ /** If lambda = R/M = 0/0 we have a problem (except in the "trivial" @@ -542,7 +542,7 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c * so we set R/M equal to this. */ secp256k1_fe_negate(&rr_alt, &s2, 1); /* rr = -Y2*Z1^3 */ secp256k1_fe_add(&rr_alt, &s1); /* rr = Y1*Z2^3 - Y2*Z1^3 */ - secp256k1_fe_add(&m_alt, &u1); /* m = X1*Z2^2 - X2*Z1^2 */ + secp256k1_fe_add(&m_alt, &u1); /* Malt = X1*Z2^2 - X2*Z1^2 */ secp256k1_fe_cmov(&rr_alt, &rr, !degenerate); secp256k1_fe_cmov(&m_alt, &m, !degenerate); From 5a43124c691df8fd148c8e07747c44893bf35229 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 7 Jul 2015 22:30:00 +1000 Subject: [PATCH 5/5] Save 1 _fe_negate since s1 == -s2 --- src/group_impl.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/group_impl.h b/src/group_impl.h index b6076db6cd7..d8bed81c65b 100644 --- a/src/group_impl.h +++ b/src/group_impl.h @@ -461,7 +461,7 @@ static void secp256k1_gej_add_zinv_var(secp256k1_gej_t *r, const secp256k1_gej_t static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) { - /* Operations: 7 mul, 5 sqr, 4 normalize, 22 mul_int/add/negate/cmov */ + /* Operations: 7 mul, 5 sqr, 4 normalize, 21 mul_int/add/negate/cmov */ static const secp256k1_fe_t fe_1 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); secp256k1_fe_t zz, u1, u2, s1, s2, t, tt, m, n, q, rr; secp256k1_fe_t m_alt, rr_alt; @@ -540,8 +540,8 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c * a nontrivial cube root of one. In either case, an alternate * non-indeterminate expression for lambda is (y1 - y2)/(x1 - x2), * so we set R/M equal to this. */ - secp256k1_fe_negate(&rr_alt, &s2, 1); /* rr = -Y2*Z1^3 */ - secp256k1_fe_add(&rr_alt, &s1); /* rr = Y1*Z2^3 - Y2*Z1^3 */ + rr_alt = s1; + secp256k1_fe_mul_int(&rr_alt, 2); /* rr = Y1*Z2^3 - Y2*Z1^3 (2) */ secp256k1_fe_add(&m_alt, &u1); /* Malt = X1*Z2^2 - X2*Z1^2 */ secp256k1_fe_cmov(&rr_alt, &rr, !degenerate);