Skip to content

Commit 399c03f

Browse files
committed
Make endomorphism optimization optional
1 parent ad52495 commit 399c03f

File tree

4 files changed

+53
-19
lines changed

4 files changed

+53
-19
lines changed

configure

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ for arg in "$@"; do
114114
--use-5x64)
115115
HAVE_LIMB=64
116116
;;
117+
--use-endomorphism)
118+
USE_ENDOMORPHISM=1
119+
;;
117120
esac
118121
done
119122

@@ -163,7 +166,9 @@ CFLAGS_TEST_EXTRA=""
163166
if [ "$HAVE_OPENSSL_EC" = "1" ]; then
164167
CFLAGS_TEST_EXTRA="-DENABLE_OPENSSL_TESTS"
165168
fi
166-
169+
if [ "$USE_ENDOMORPHISM" = "1" ]; then
170+
CFLAGS_EXTRA="$(CFLAGS_EXTRA) -DUSE_ENDOMORPHISM"
171+
fi
167172
echo "CC=$CC" > config.mk
168173
echo "YASM=$YASM" >>config.mk
169174
echo "CFLAGS_EXTRA=$CFLAGS_EXTRA" >> config.mk

src/group.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,13 @@ void static secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c
9898
/** Get a hex representation of a point. *rlen will be overwritten with the real length. */
9999
void static secp256k1_gej_get_hex(char *r, int *rlen, const secp256k1_gej_t *a);
100100

101+
#ifdef USE_ENDOMORPHISM
101102
/** Set r to be equal to lambda times a, where lambda is chosen in a way such that this is very fast. */
102103
void static secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a);
103104

104105
/** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (given that a is
105106
not more than 256 bits). */
106107
void static secp256k1_gej_split_exp(secp256k1_num_t *r1, secp256k1_num_t *r2, const secp256k1_num_t *a);
108+
#endif
107109

108110
#endif

src/impl/ecmult.h

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -173,34 +173,46 @@ void static secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_num_t *gn)
173173
void static secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_num_t *na, const secp256k1_num_t *ng) {
174174
const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts;
175175

176+
#ifdef USE_ENDOMORPHISM
176177
secp256k1_num_t na_1, na_lam;
177-
secp256k1_num_t ng_1, ng_128;
178178
secp256k1_num_init(&na_1);
179179
secp256k1_num_init(&na_lam);
180-
secp256k1_num_init(&ng_1);
181-
secp256k1_num_init(&ng_128);
182-
183180
// split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit)
184181
secp256k1_gej_split_exp(&na_1, &na_lam, na);
185-
// 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)
186-
secp256k1_num_split(&ng_1, &ng_128, ng, 128);
187182

188-
// build wnaf representation for na_1, na_lam, ng_1, ng_128
183+
// build wnaf representation for na_1 and na_lam.
189184
int wnaf_na_1[129]; int bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A);
190185
int wnaf_na_lam[129]; int bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, &na_lam, WINDOW_A);
191-
int wnaf_ng_1[129]; int bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G);
192-
int wnaf_ng_128[129]; int bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, &ng_128, WINDOW_G);
186+
int bits = bits_na_1;
187+
if (bits_na_lam > bits) bits = bits_na_lam;
193188

194189
// calculate a_lam = a*lambda
195190
secp256k1_gej_t a_lam; secp256k1_gej_mul_lambda(&a_lam, a);
196191

197-
// calculate odd multiples of a and a_lam
198-
secp256k1_gej_t pre_a_1[ECMULT_TABLE_SIZE(WINDOW_A)], pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)];
199-
secp256k1_ecmult_table_precomp_gej(pre_a_1, a, WINDOW_A);
192+
// calculate odd multiples of a_lam
193+
secp256k1_gej_t pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)];
200194
secp256k1_ecmult_table_precomp_gej(pre_a_lam, &a_lam, WINDOW_A);
195+
#else
196+
// build wnaf representation for na.
197+
int wnaf_na[257]; int bits_na = secp256k1_ecmult_wnaf(wnaf_na, na, WINDOW_A);
198+
int bits = bits_na;
199+
#endif
201200

202-
int bits = bits_na_1;
203-
if (bits_na_lam > bits) bits = bits_na_lam;
201+
// calculate odd multiples of a
202+
secp256k1_gej_t pre_a[ECMULT_TABLE_SIZE(WINDOW_A)];
203+
secp256k1_ecmult_table_precomp_gej(pre_a, a, WINDOW_A);
204+
205+
// Splitted G factors.
206+
secp256k1_num_t ng_1, ng_128;
207+
secp256k1_num_init(&ng_1);
208+
secp256k1_num_init(&ng_128);
209+
210+
// 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)
211+
secp256k1_num_split(&ng_1, &ng_128, ng, 128);
212+
213+
// Build wnaf representation for ng_1 and ng_128
214+
int wnaf_ng_1[129]; int bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G);
215+
int wnaf_ng_128[129]; int bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, &ng_128, WINDOW_G);
204216
if (bits_ng_1 > bits) bits = bits_ng_1;
205217
if (bits_ng_128 > bits) bits = bits_ng_128;
206218

@@ -211,14 +223,21 @@ void static secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const
211223
for (int i=bits-1; i>=0; i--) {
212224
secp256k1_gej_double(r, r);
213225
int n;
226+
#ifdef USE_ENDOMORPHISM
214227
if (i < bits_na_1 && (n = wnaf_na_1[i])) {
215-
ECMULT_TABLE_GET_GEJ(&tmpj, pre_a_1, n, WINDOW_A);
228+
ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A);
216229
secp256k1_gej_add(r, r, &tmpj);
217230
}
218231
if (i < bits_na_lam && (n = wnaf_na_lam[i])) {
219232
ECMULT_TABLE_GET_GEJ(&tmpj, pre_a_lam, n, WINDOW_A);
220233
secp256k1_gej_add(r, r, &tmpj);
221234
}
235+
#else
236+
if (i < bits_na && (n = wnaf_na[i])) {
237+
ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A);
238+
secp256k1_gej_add(r, r, &tmpj);
239+
}
240+
#endif
222241
if (i < bits_ng_1 && (n = wnaf_ng_1[i])) {
223242
ECMULT_TABLE_GET_GE(&tmpa, c->pre_g, n, WINDOW_G);
224243
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
229248
}
230249
}
231250

251+
#ifdef USE_ENDOMORPHISM
232252
secp256k1_num_free(&na_1);
233253
secp256k1_num_free(&na_lam);
254+
#endif
234255
secp256k1_num_free(&ng_1);
235256
secp256k1_num_free(&ng_128);
236257
}

src/impl/group.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ void static secp256k1_gej_get_hex(char *r, int *rlen, const secp256k1_gej_t *a)
268268
secp256k1_ge_get_hex(r, rlen, &t);
269269
}
270270

271+
#ifdef USE_ENDOMORPHISM
271272
void static secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
272273
const secp256k1_fe_t *beta = &secp256k1_ge_consts->beta;
273274
*r = *a;
@@ -309,6 +310,7 @@ void static secp256k1_gej_split_exp(secp256k1_num_t *r1, secp256k1_num_t *r2, co
309310
secp256k1_num_free(&bnt2);
310311
secp256k1_num_free(&bnn2);
311312
}
313+
#endif
312314

313315

314316
void static secp256k1_ge_start(void) {
@@ -330,6 +332,7 @@ void static secp256k1_ge_start(void) {
330332
0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,
331333
0x9C,0x47,0xD0,0x8F,0xFB,0x10,0xD4,0xB8
332334
};
335+
#ifdef USE_ENDOMORPHISM
333336
// properties of secp256k1's efficiently computable endomorphism
334337
static const unsigned char secp256k1_ge_consts_lambda[] = {
335338
0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,
@@ -356,22 +359,25 @@ void static secp256k1_ge_start(void) {
356359
0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,
357360
0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8
358361
};
362+
#endif
359363
if (secp256k1_ge_consts == NULL) {
360364
secp256k1_ge_consts_t *ret = (secp256k1_ge_consts_t*)malloc(sizeof(secp256k1_ge_consts_t));
361365
secp256k1_num_init(&ret->order);
362366
secp256k1_num_init(&ret->half_order);
367+
secp256k1_num_set_bin(&ret->order, secp256k1_ge_consts_order, sizeof(secp256k1_ge_consts_order));
368+
secp256k1_num_copy(&ret->half_order, &ret->order);
369+
secp256k1_num_shift(&ret->half_order, 1);
370+
#ifdef USE_ENDOMORPHISM
363371
secp256k1_num_init(&ret->lambda);
364372
secp256k1_num_init(&ret->a1b2);
365373
secp256k1_num_init(&ret->a2);
366374
secp256k1_num_init(&ret->b1);
367-
secp256k1_num_set_bin(&ret->order, secp256k1_ge_consts_order, sizeof(secp256k1_ge_consts_order));
368375
secp256k1_num_set_bin(&ret->lambda, secp256k1_ge_consts_lambda, sizeof(secp256k1_ge_consts_lambda));
369376
secp256k1_num_set_bin(&ret->a1b2, secp256k1_ge_consts_a1b2, sizeof(secp256k1_ge_consts_a1b2));
370377
secp256k1_num_set_bin(&ret->a2, secp256k1_ge_consts_a2, sizeof(secp256k1_ge_consts_a2));
371378
secp256k1_num_set_bin(&ret->b1, secp256k1_ge_consts_b1, sizeof(secp256k1_ge_consts_b1));
372-
secp256k1_num_copy(&ret->half_order, &ret->order);
373-
secp256k1_num_shift(&ret->half_order, 1);
374379
secp256k1_fe_set_b32(&ret->beta, secp256k1_ge_consts_beta);
380+
#endif
375381
secp256k1_fe_t g_x, g_y;
376382
secp256k1_fe_set_b32(&g_x, secp256k1_ge_consts_g_x);
377383
secp256k1_fe_set_b32(&g_y, secp256k1_ge_consts_g_y);

0 commit comments

Comments
 (0)