Make endomorphism optimization optional
This commit is contained in:
parent
ad52495d72
commit
399c03f227
|
@ -114,6 +114,9 @@ for arg in "$@"; do
|
|||
--use-5x64)
|
||||
HAVE_LIMB=64
|
||||
;;
|
||||
--use-endomorphism)
|
||||
USE_ENDOMORPHISM=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
@ -163,7 +166,9 @@ CFLAGS_TEST_EXTRA=""
|
|||
if [ "$HAVE_OPENSSL_EC" = "1" ]; then
|
||||
CFLAGS_TEST_EXTRA="-DENABLE_OPENSSL_TESTS"
|
||||
fi
|
||||
|
||||
if [ "$USE_ENDOMORPHISM" = "1" ]; then
|
||||
CFLAGS_EXTRA="$(CFLAGS_EXTRA) -DUSE_ENDOMORPHISM"
|
||||
fi
|
||||
echo "CC=$CC" > config.mk
|
||||
echo "YASM=$YASM" >>config.mk
|
||||
echo "CFLAGS_EXTRA=$CFLAGS_EXTRA" >> config.mk
|
||||
|
|
|
@ -98,11 +98,13 @@ void static secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c
|
|||
/** Get a hex representation of a point. *rlen will be overwritten with the real length. */
|
||||
void static secp256k1_gej_get_hex(char *r, int *rlen, const secp256k1_gej_t *a);
|
||||
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
/** Set r to be equal to lambda times a, where lambda is chosen in a way such that this is very fast. */
|
||||
void static secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a);
|
||||
|
||||
/** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (given that a is
|
||||
not more than 256 bits). */
|
||||
void static secp256k1_gej_split_exp(secp256k1_num_t *r1, secp256k1_num_t *r2, const secp256k1_num_t *a);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -173,34 +173,46 @@ void static secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_num_t *gn)
|
|||
void static secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_num_t *na, const secp256k1_num_t *ng) {
|
||||
const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts;
|
||||
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
secp256k1_num_t na_1, na_lam;
|
||||
secp256k1_num_t ng_1, ng_128;
|
||||
secp256k1_num_init(&na_1);
|
||||
secp256k1_num_init(&na_lam);
|
||||
secp256k1_num_init(&ng_1);
|
||||
secp256k1_num_init(&ng_128);
|
||||
|
||||
// split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit)
|
||||
secp256k1_gej_split_exp(&na_1, &na_lam, na);
|
||||
// split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit)
|
||||
secp256k1_num_split(&ng_1, &ng_128, ng, 128);
|
||||
|
||||
// build wnaf representation for na_1, na_lam, ng_1, ng_128
|
||||
// build wnaf representation for na_1 and na_lam.
|
||||
int wnaf_na_1[129]; int bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A);
|
||||
int wnaf_na_lam[129]; int bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, &na_lam, WINDOW_A);
|
||||
int wnaf_ng_1[129]; int bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G);
|
||||
int wnaf_ng_128[129]; int bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, &ng_128, WINDOW_G);
|
||||
int bits = bits_na_1;
|
||||
if (bits_na_lam > bits) bits = bits_na_lam;
|
||||
|
||||
// calculate a_lam = a*lambda
|
||||
secp256k1_gej_t a_lam; secp256k1_gej_mul_lambda(&a_lam, a);
|
||||
|
||||
// calculate odd multiples of a and a_lam
|
||||
secp256k1_gej_t pre_a_1[ECMULT_TABLE_SIZE(WINDOW_A)], pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)];
|
||||
secp256k1_ecmult_table_precomp_gej(pre_a_1, a, WINDOW_A);
|
||||
// calculate odd multiples of a_lam
|
||||
secp256k1_gej_t pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)];
|
||||
secp256k1_ecmult_table_precomp_gej(pre_a_lam, &a_lam, WINDOW_A);
|
||||
#else
|
||||
// build wnaf representation for na.
|
||||
int wnaf_na[257]; int bits_na = secp256k1_ecmult_wnaf(wnaf_na, na, WINDOW_A);
|
||||
int bits = bits_na;
|
||||
#endif
|
||||
|
||||
int bits = bits_na_1;
|
||||
if (bits_na_lam > bits) bits = bits_na_lam;
|
||||
// calculate odd multiples of a
|
||||
secp256k1_gej_t pre_a[ECMULT_TABLE_SIZE(WINDOW_A)];
|
||||
secp256k1_ecmult_table_precomp_gej(pre_a, a, WINDOW_A);
|
||||
|
||||
// Splitted G factors.
|
||||
secp256k1_num_t ng_1, ng_128;
|
||||
secp256k1_num_init(&ng_1);
|
||||
secp256k1_num_init(&ng_128);
|
||||
|
||||
// split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit)
|
||||
secp256k1_num_split(&ng_1, &ng_128, ng, 128);
|
||||
|
||||
// Build wnaf representation for ng_1 and ng_128
|
||||
int wnaf_ng_1[129]; int bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G);
|
||||
int wnaf_ng_128[129]; int bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, &ng_128, WINDOW_G);
|
||||
if (bits_ng_1 > bits) bits = bits_ng_1;
|
||||
if (bits_ng_128 > bits) bits = bits_ng_128;
|
||||
|
||||
|
@ -211,14 +223,21 @@ void static secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const
|
|||
for (int i=bits-1; i>=0; i--) {
|
||||
secp256k1_gej_double(r, r);
|
||||
int n;
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
if (i < bits_na_1 && (n = wnaf_na_1[i])) {
|
||||
ECMULT_TABLE_GET_GEJ(&tmpj, pre_a_1, n, WINDOW_A);
|
||||
ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A);
|
||||
secp256k1_gej_add(r, r, &tmpj);
|
||||
}
|
||||
if (i < bits_na_lam && (n = wnaf_na_lam[i])) {
|
||||
ECMULT_TABLE_GET_GEJ(&tmpj, pre_a_lam, n, WINDOW_A);
|
||||
secp256k1_gej_add(r, r, &tmpj);
|
||||
}
|
||||
#else
|
||||
if (i < bits_na && (n = wnaf_na[i])) {
|
||||
ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A);
|
||||
secp256k1_gej_add(r, r, &tmpj);
|
||||
}
|
||||
#endif
|
||||
if (i < bits_ng_1 && (n = wnaf_ng_1[i])) {
|
||||
ECMULT_TABLE_GET_GE(&tmpa, c->pre_g, n, WINDOW_G);
|
||||
secp256k1_gej_add_ge(r, r, &tmpa);
|
||||
|
@ -229,8 +248,10 @@ void static secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
secp256k1_num_free(&na_1);
|
||||
secp256k1_num_free(&na_lam);
|
||||
#endif
|
||||
secp256k1_num_free(&ng_1);
|
||||
secp256k1_num_free(&ng_128);
|
||||
}
|
||||
|
|
|
@ -268,6 +268,7 @@ void static secp256k1_gej_get_hex(char *r, int *rlen, const secp256k1_gej_t *a)
|
|||
secp256k1_ge_get_hex(r, rlen, &t);
|
||||
}
|
||||
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
void static secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
|
||||
const secp256k1_fe_t *beta = &secp256k1_ge_consts->beta;
|
||||
*r = *a;
|
||||
|
@ -309,6 +310,7 @@ void static secp256k1_gej_split_exp(secp256k1_num_t *r1, secp256k1_num_t *r2, co
|
|||
secp256k1_num_free(&bnt2);
|
||||
secp256k1_num_free(&bnn2);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void static secp256k1_ge_start(void) {
|
||||
|
@ -330,6 +332,7 @@ void static secp256k1_ge_start(void) {
|
|||
0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,
|
||||
0x9C,0x47,0xD0,0x8F,0xFB,0x10,0xD4,0xB8
|
||||
};
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
// properties of secp256k1's efficiently computable endomorphism
|
||||
static const unsigned char secp256k1_ge_consts_lambda[] = {
|
||||
0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,
|
||||
|
@ -356,22 +359,25 @@ void static secp256k1_ge_start(void) {
|
|||
0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,
|
||||
0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8
|
||||
};
|
||||
#endif
|
||||
if (secp256k1_ge_consts == NULL) {
|
||||
secp256k1_ge_consts_t *ret = (secp256k1_ge_consts_t*)malloc(sizeof(secp256k1_ge_consts_t));
|
||||
secp256k1_num_init(&ret->order);
|
||||
secp256k1_num_init(&ret->half_order);
|
||||
secp256k1_num_set_bin(&ret->order, secp256k1_ge_consts_order, sizeof(secp256k1_ge_consts_order));
|
||||
secp256k1_num_copy(&ret->half_order, &ret->order);
|
||||
secp256k1_num_shift(&ret->half_order, 1);
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
secp256k1_num_init(&ret->lambda);
|
||||
secp256k1_num_init(&ret->a1b2);
|
||||
secp256k1_num_init(&ret->a2);
|
||||
secp256k1_num_init(&ret->b1);
|
||||
secp256k1_num_set_bin(&ret->order, secp256k1_ge_consts_order, sizeof(secp256k1_ge_consts_order));
|
||||
secp256k1_num_set_bin(&ret->lambda, secp256k1_ge_consts_lambda, sizeof(secp256k1_ge_consts_lambda));
|
||||
secp256k1_num_set_bin(&ret->a1b2, secp256k1_ge_consts_a1b2, sizeof(secp256k1_ge_consts_a1b2));
|
||||
secp256k1_num_set_bin(&ret->a2, secp256k1_ge_consts_a2, sizeof(secp256k1_ge_consts_a2));
|
||||
secp256k1_num_set_bin(&ret->b1, secp256k1_ge_consts_b1, sizeof(secp256k1_ge_consts_b1));
|
||||
secp256k1_num_copy(&ret->half_order, &ret->order);
|
||||
secp256k1_num_shift(&ret->half_order, 1);
|
||||
secp256k1_fe_set_b32(&ret->beta, secp256k1_ge_consts_beta);
|
||||
#endif
|
||||
secp256k1_fe_t g_x, g_y;
|
||||
secp256k1_fe_set_b32(&g_x, secp256k1_ge_consts_g_x);
|
||||
secp256k1_fe_set_b32(&g_y, secp256k1_ge_consts_g_y);
|
||||
|
|
Loading…
Reference in New Issue