Skip to content

Commit

Permalink
Implement endomorphism optimization for secp256k1_ecdh_point_multiply
Browse files Browse the repository at this point in the history
  • Loading branch information
apoelstra committed May 22, 2015
1 parent a022656 commit a0992eb
Showing 1 changed file with 43 additions and 1 deletion.
44 changes: 43 additions & 1 deletion src/ecdh_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,43 @@ static void secp256k1_ecdh_point_multiply(secp256k1_gej_t *r, const secp256k1_ge
secp256k1_ge_t tmpa;
secp256k1_fe_t Z;

#ifdef USE_ENDOMORPHISM
secp256k1_ge_t pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)];
int wnaf_1[256];
int wnaf_lam[256];
int n_words_lam;
secp256k1_scalar_t q_1, q_lam;
#else
int wnaf[256];
#endif
int n_words;

int i;
int is_zero = secp256k1_scalar_is_zero(scalar);
secp256k1_scalar_t sc = *scalar;

/* build wnaf representation for q. */
#ifdef USE_ENDOMORPHISM
/* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */
secp256k1_scalar_split_lambda(&q_1, &q_lam, &sc);
/* the wNAF ladder cannot handle zero, so bump this to one .. we will
* correct the result after the fact */
q_1.d[0] += is_zero;
q_lam.d[0] += is_zero;
VERIFY_CHECK(!secp256k1_scalar_is_zero(&q_1));
VERIFY_CHECK(!secp256k1_scalar_is_zero(&q_lam));

n_words = secp256k1_ecdh_wnaf(wnaf_1, &q_1, WINDOW_A - 1);
n_words_lam = secp256k1_ecdh_wnaf(wnaf_lam, &q_lam, WINDOW_A - 1);
VERIFY_CHECK(n_words == n_words_lam);
#else
/* the wNAF ladder cannot handle zero, so bump this to one .. we will
* correct the result after the fact */
sc.d[0] += is_zero;
VERIFY_CHECK(!secp256k1_scalar_is_zero(&sc));

/* build wnaf representation for q. */
n_words = secp256k1_ecdh_wnaf(wnaf, &sc, WINDOW_A - 1);
#endif

/* Calculate odd multiples of a.
* All multiples are brought to the same Z 'denominator', which is stored
Expand All @@ -82,6 +107,11 @@ static void secp256k1_ecdh_point_multiply(secp256k1_gej_t *r, const secp256k1_ge
*/
secp256k1_gej_set_ge(r, a);
secp256k1_ecmult_odd_multiples_table_globalz_windowa(pre_a, &Z, r);
#ifdef USE_ENDOMORPHISM
for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) {
secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]);
}
#endif
secp256k1_gej_set_infinity(r);

for (i = n_words; i >= 0; i--) {
Expand All @@ -90,10 +120,22 @@ static void secp256k1_ecdh_point_multiply(secp256k1_gej_t *r, const secp256k1_ge
for (j = 0; j < WINDOW_A - 1; ++j) {
secp256k1_gej_double_var(r, r, NULL);
}
#ifdef USE_ENDOMORPHISM
n = wnaf_1[i];
ECMULT_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A);
VERIFY_CHECK(n != 0);
secp256k1_gej_add_ge(r, r, &tmpa);

n = wnaf_lam[i];
ECMULT_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A);
VERIFY_CHECK(n != 0);
secp256k1_gej_add_ge(r, r, &tmpa);
#else
n = wnaf[i];
VERIFY_CHECK(n != 0);
ECMULT_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A);
secp256k1_gej_add_ge(r, r, &tmpa);
#endif
}

if (!r->infinity) {
Expand Down

0 comments on commit a0992eb

Please sign in to comment.