Skip to content

Commit c6b6b8f

Browse files
committed
Merge #830: Rip out non-endomorphism code + dependencies
c582aba Consistency improvements to the comments (Pieter Wuille) 63c6b71 Reorder comments/function around scalar_split_lambda (Pieter Wuille) 2edc514 WNAF of lambda_split output has max size 129 (Pieter Wuille) 4232e5b Rip out non-endomorphism code (Pieter Wuille) ebad841 Check correctness of lambda split without -DVERIFY (Gregory Maxwell) fe7fc1f Make lambda constant accessible (Pieter Wuille) 9d2f2b4 Add tests to exercise lambda split near bounds (Pieter Wuille) 9aca2f7 Add secp256k1_split_lambda_verify (Russell O'Connor) acab934 Detailed comments for secp256k1_scalar_split_lambda (Russell O'Connor) 76ed922 Increase precision of g1 and g2 (Russell O'Connor) 6173839 Switch to our own memcmp function (Tim Ruffing) Pull request description: This is a rebased/combined version of the following pull requests/commits with minor changes: * #825 Switch to our own memcmp function * Modification: `secp256k1_memcmp_var` is marked static inline * Modification: also replace `memcmp` with `secp256k1_memcmp_var` in exhaustive tests * Modification: add reference to GCC bug 95189 * #822 Increase precision of g1 and g2 * Modification: use the new `secp256k1_memcmp_var` function instead of `memcmp` (see #822 (comment)) * Modification: drop the " Allow secp256k1_split_lambda_verify to pass even in the presence of GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95189." commit, as it's dealt with using `secp256k1_memcmp_var`. * Modification: rename secp256k1_gej_mul_lambda -> secp256k1_ge_mul_lambda * A new commit that moves the `lambda` constant out of `secp256k1_scalar_split_lambda` and (`_verify`). * The test commit suggested here: #822 (comment) * Modification: use the new accessible `secp256k1_const_lambda` instead of duplicating it. * #826 Rip out non-endomorphism code * A new commit that reduces the size of the WNAF output to 129, as we now have proof that the split output is always 128 bits or less. * A new commit to more consistently use input:`k`, integer outputs:`k1`,`k2`, modulo n outputs:`r1`,`r2` ACKs for top commit: real-or-random: ACK c582aba code inspection, some tests, verified the new g1/g2 constants jonasnick: ACK c582aba didn't verify the proof Tree-SHA512: 323a3ee3884b7ac4fa85c8e7b785111b5c0638d718bc1c805a38963c87411e81a746c98e9a42a3e2197ab34a874544de5cc51326955d1c4d0ea45afd418e819f
2 parents 63150ab + c582aba commit c6b6b8f

28 files changed

+548
-469
lines changed

.travis.yml

+6-10
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,29 @@ compiler:
1717
- gcc
1818
env:
1919
global:
20-
- WIDEMUL=auto BIGNUM=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ECMULTGENPRECISION=auto ASM=no BUILD=check WITH_VALGRIND=yes RUN_VALGRIND=no EXTRAFLAGS= HOST= ECDH=no RECOVERY=no SCHNORRSIG=no EXPERIMENTAL=no CTIMETEST=yes BENCH=yes ITERS=2
20+
- WIDEMUL=auto BIGNUM=auto STATICPRECOMPUTATION=yes ECMULTGENPRECISION=auto ASM=no BUILD=check WITH_VALGRIND=yes RUN_VALGRIND=no EXTRAFLAGS= HOST= ECDH=no RECOVERY=no SCHNORRSIG=no EXPERIMENTAL=no CTIMETEST=yes BENCH=yes ITERS=2
2121
matrix:
2222
- WIDEMUL=int64 RECOVERY=yes
2323
- WIDEMUL=int64 ECDH=yes EXPERIMENTAL=yes SCHNORRSIG=yes
24-
- WIDEMUL=int64 ENDOMORPHISM=yes
2524
- WIDEMUL=int128
2625
- WIDEMUL=int128 RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes
27-
- WIDEMUL=int128 ENDOMORPHISM=yes
28-
- WIDEMUL=int128 ENDOMORPHISM=yes ECDH=yes EXPERIMENTAL=yes SCHNORRSIG=yes
26+
- WIDEMUL=int128 ECDH=yes EXPERIMENTAL=yes SCHNORRSIG=yes
2927
- WIDEMUL=int128 ASM=x86_64
30-
- WIDEMUL=int128 ENDOMORPHISM=yes ASM=x86_64
3128
- BIGNUM=no
32-
- BIGNUM=no ENDOMORPHISM=yes RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes
29+
- BIGNUM=no RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes
3330
- BIGNUM=no STATICPRECOMPUTATION=no
3431
- BUILD=distcheck WITH_VALGRIND=no CTIMETEST=no BENCH=no
3532
- CPPFLAGS=-DDETERMINISTIC
3633
- CFLAGS=-O0 CTIMETEST=no
3734
- ECMULTGENPRECISION=2
3835
- ECMULTGENPRECISION=8
39-
- RUN_VALGRIND=yes ENDOMORPHISM=yes BIGNUM=no ASM=x86_64 EXPERIMENTAL=yes ECDH=yes RECOVERY=yes EXTRAFLAGS="--disable-openssl-tests" BUILD=
40-
- RUN_VALGRIND=yes BIGNUM=no ASM=x86_64 EXPERIMENTAL=yes ECDH=yes RECOVERY=yes EXTRAFLAGS="--disable-openssl-tests" BUILD=
36+
- RUN_VALGRIND=yes BIGNUM=no ASM=x86_64 EXPERIMENTAL=yes ECDH=yes RECOVERY=yes EXTRAFLAGS="--disable-openssl-tests" BUILD=
4137
matrix:
4238
fast_finish: true
4339
include:
4440
- compiler: clang
4541
os: linux
46-
env: HOST=i686-linux-gnu ENDOMORPHISM=yes
42+
env: HOST=i686-linux-gnu
4743
addons:
4844
apt:
4945
packages:
@@ -63,7 +59,7 @@ matrix:
6359
- libtool-bin
6460
- libc6-dbg:i386
6561
- compiler: gcc
66-
env: HOST=i686-linux-gnu ENDOMORPHISM=yes
62+
env: HOST=i686-linux-gnu
6763
os: linux
6864
addons:
6965
apt:

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Implementation details
4848
* Use wNAF notation for point multiplicands.
4949
* Use a much larger window for multiples of G, using precomputed multiples.
5050
* Use Shamir's trick to do the multiplication with the public key and the generator simultaneously.
51-
* Optionally (off by default) use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones.
51+
* Use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones.
5252
* Point multiplication for signing
5353
* Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions.
5454
* Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains)

configure.ac

+1-12
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,6 @@ AC_ARG_ENABLE(exhaustive_tests,
116116
[use_exhaustive_tests=$enableval],
117117
[use_exhaustive_tests=yes])
118118

119-
AC_ARG_ENABLE(endomorphism,
120-
AS_HELP_STRING([--enable-endomorphism],[enable endomorphism [default=no]]),
121-
[use_endomorphism=$enableval],
122-
[use_endomorphism=no])
123-
124119
AC_ARG_ENABLE(ecmult_static_precomputation,
125120
AS_HELP_STRING([--enable-ecmult-static-precomputation],[enable precomputed ecmult table for signing [default=auto]]),
126121
[use_ecmult_static_precomputation=$enableval],
@@ -164,8 +159,7 @@ AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm|no|auto],
164159
AC_ARG_WITH([ecmult-window], [AS_HELP_STRING([--with-ecmult-window=SIZE|auto],
165160
[window size for ecmult precomputation for verification, specified as integer in range [2..24].]
166161
[Larger values result in possibly better performance at the cost of an exponentially larger precomputed table.]
167-
[The table will store 2^(SIZE-2) * 64 bytes of data but can be larger in memory due to platform-specific padding and alignment.]
168-
[If the endomorphism optimization is enabled, two tables of this size are used instead of only one.]
162+
[The table will store 2^(SIZE-1) * 64 bytes of data but can be larger in memory due to platform-specific padding and alignment.]
169163
["auto" is a reasonable setting for desktop machines (currently 15). [default=auto]]
170164
)],
171165
[req_ecmult_window=$withval], [req_ecmult_window=auto])
@@ -429,10 +423,6 @@ if test x"$set_bignum" = x"gmp"; then
429423
SECP_INCLUDES="$SECP_INCLUDES $GMP_CPPFLAGS"
430424
fi
431425

432-
if test x"$use_endomorphism" = x"yes"; then
433-
AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization])
434-
fi
435-
436426
if test x"$set_precomp" = x"yes"; then
437427
AC_DEFINE(USE_ECMULT_STATIC_PRECOMPUTATION, 1, [Define this symbol to use a statically generated ecmult table])
438428
fi
@@ -514,7 +504,6 @@ AC_OUTPUT
514504

515505
echo
516506
echo "Build Options:"
517-
echo " with endomorphism = $use_endomorphism"
518507
echo " with ecmult precomp = $set_precomp"
519508
echo " with external callbacks = $use_external_default_callbacks"
520509
echo " with benchmarks = $use_benchmark"

contrib/travis.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ then
1313
fi
1414

1515
./configure \
16-
--enable-experimental="$EXPERIMENTAL" --enable-endomorphism="$ENDOMORPHISM" \
16+
--enable-experimental="$EXPERIMENTAL" \
1717
--with-test-override-wide-multiply="$WIDEMUL" --with-bignum="$BIGNUM" --with-asm="$ASM" \
1818
--enable-ecmult-static-precomputation="$STATICPRECOMPUTATION" --with-ecmult-gen-precision="$ECMULTGENPRECISION" \
1919
--enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \

src/basic-config.h

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#undef USE_ASM_X86_64
1313
#undef USE_ECMULT_STATIC_PRECOMPUTATION
14-
#undef USE_ENDOMORPHISM
1514
#undef USE_EXTERNAL_ASM
1615
#undef USE_EXTERNAL_DEFAULT_CALLBACKS
1716
#undef USE_FIELD_INV_BUILTIN

src/bench_internal.c

-4
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ void bench_scalar_mul(void* arg, int iters) {
117117
}
118118
}
119119

120-
#ifdef USE_ENDOMORPHISM
121120
void bench_scalar_split(void* arg, int iters) {
122121
int i, j = 0;
123122
bench_inv *data = (bench_inv*)arg;
@@ -128,7 +127,6 @@ void bench_scalar_split(void* arg, int iters) {
128127
}
129128
CHECK(j <= iters);
130129
}
131-
#endif
132130

133131
void bench_scalar_inverse(void* arg, int iters) {
134132
int i, j = 0;
@@ -397,9 +395,7 @@ int main(int argc, char **argv) {
397395
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, 10, iters*100);
398396
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "sqr")) run_benchmark("scalar_sqr", bench_scalar_sqr, bench_setup, NULL, &data, 10, iters*10);
399397
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "mul")) run_benchmark("scalar_mul", bench_scalar_mul, bench_setup, NULL, &data, 10, iters*10);
400-
#ifdef USE_ENDOMORPHISM
401398
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "split")) run_benchmark("scalar_split", bench_scalar_split, bench_setup, NULL, &data, 10, iters);
402-
#endif
403399
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse", bench_scalar_inverse, bench_setup, NULL, &data, 10, 2000);
404400
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse_var", bench_scalar_inverse_var, bench_setup, NULL, &data, 10, 2000);
405401

src/ecmult.h

-2
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
typedef struct {
1616
/* For accelerating the computation of a*P + b*G: */
1717
secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */
18-
#ifdef USE_ENDOMORPHISM
1918
secp256k1_ge_storage (*pre_g_128)[]; /* odd multiples of 2^128*generator */
20-
#endif
2119
} secp256k1_ecmult_context;
2220

2321
static const size_t SECP256K1_ECMULT_CONTEXT_PREALLOCATED_SIZE;

src/ecmult_const_impl.h

-20
Original file line numberDiff line numberDiff line change
@@ -140,32 +140,26 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons
140140
secp256k1_fe Z;
141141

142142
int skew_1;
143-
#ifdef USE_ENDOMORPHISM
144143
secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)];
145144
int wnaf_lam[1 + WNAF_SIZE(WINDOW_A - 1)];
146145
int skew_lam;
147146
secp256k1_scalar q_1, q_lam;
148-
#endif
149147
int wnaf_1[1 + WNAF_SIZE(WINDOW_A - 1)];
150148

151149
int i;
152150

153151
/* build wnaf representation for q. */
154152
int rsize = size;
155-
#ifdef USE_ENDOMORPHISM
156153
if (size > 128) {
157154
rsize = 128;
158155
/* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */
159156
secp256k1_scalar_split_lambda(&q_1, &q_lam, scalar);
160157
skew_1 = secp256k1_wnaf_const(wnaf_1, &q_1, WINDOW_A - 1, 128);
161158
skew_lam = secp256k1_wnaf_const(wnaf_lam, &q_lam, WINDOW_A - 1, 128);
162159
} else
163-
#endif
164160
{
165161
skew_1 = secp256k1_wnaf_const(wnaf_1, scalar, WINDOW_A - 1, size);
166-
#ifdef USE_ENDOMORPHISM
167162
skew_lam = 0;
168-
#endif
169163
}
170164

171165
/* Calculate odd multiples of a.
@@ -179,14 +173,12 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons
179173
for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) {
180174
secp256k1_fe_normalize_weak(&pre_a[i].y);
181175
}
182-
#ifdef USE_ENDOMORPHISM
183176
if (size > 128) {
184177
for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) {
185178
secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]);
186179
}
187180

188181
}
189-
#endif
190182

191183
/* first loop iteration (separated out so we can directly set r, rather
192184
* than having it start at infinity, get doubled several times, then have
@@ -195,14 +187,12 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons
195187
VERIFY_CHECK(i != 0);
196188
ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A);
197189
secp256k1_gej_set_ge(r, &tmpa);
198-
#ifdef USE_ENDOMORPHISM
199190
if (size > 128) {
200191
i = wnaf_lam[WNAF_SIZE_BITS(rsize, WINDOW_A - 1)];
201192
VERIFY_CHECK(i != 0);
202193
ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, i, WINDOW_A);
203194
secp256k1_gej_add_ge(r, r, &tmpa);
204195
}
205-
#endif
206196
/* remaining loop iterations */
207197
for (i = WNAF_SIZE_BITS(rsize, WINDOW_A - 1) - 1; i >= 0; i--) {
208198
int n;
@@ -215,14 +205,12 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons
215205
ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A);
216206
VERIFY_CHECK(n != 0);
217207
secp256k1_gej_add_ge(r, r, &tmpa);
218-
#ifdef USE_ENDOMORPHISM
219208
if (size > 128) {
220209
n = wnaf_lam[i];
221210
ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A);
222211
VERIFY_CHECK(n != 0);
223212
secp256k1_gej_add_ge(r, r, &tmpa);
224213
}
225-
#endif
226214
}
227215

228216
secp256k1_fe_mul(&r->z, &r->z, &Z);
@@ -231,43 +219,35 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons
231219
/* Correct for wNAF skew */
232220
secp256k1_ge correction = *a;
233221
secp256k1_ge_storage correction_1_stor;
234-
#ifdef USE_ENDOMORPHISM
235222
secp256k1_ge_storage correction_lam_stor;
236-
#endif
237223
secp256k1_ge_storage a2_stor;
238224
secp256k1_gej tmpj;
239225
secp256k1_gej_set_ge(&tmpj, &correction);
240226
secp256k1_gej_double_var(&tmpj, &tmpj, NULL);
241227
secp256k1_ge_set_gej(&correction, &tmpj);
242228
secp256k1_ge_to_storage(&correction_1_stor, a);
243-
#ifdef USE_ENDOMORPHISM
244229
if (size > 128) {
245230
secp256k1_ge_to_storage(&correction_lam_stor, a);
246231
}
247-
#endif
248232
secp256k1_ge_to_storage(&a2_stor, &correction);
249233

250234
/* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */
251235
secp256k1_ge_storage_cmov(&correction_1_stor, &a2_stor, skew_1 == 2);
252-
#ifdef USE_ENDOMORPHISM
253236
if (size > 128) {
254237
secp256k1_ge_storage_cmov(&correction_lam_stor, &a2_stor, skew_lam == 2);
255238
}
256-
#endif
257239

258240
/* Apply the correction */
259241
secp256k1_ge_from_storage(&correction, &correction_1_stor);
260242
secp256k1_ge_neg(&correction, &correction);
261243
secp256k1_gej_add_ge(r, r, &correction);
262244

263-
#ifdef USE_ENDOMORPHISM
264245
if (size > 128) {
265246
secp256k1_ge_from_storage(&correction, &correction_lam_stor);
266247
secp256k1_ge_neg(&correction, &correction);
267248
secp256k1_ge_mul_lambda(&correction, &correction);
268249
secp256k1_gej_add_ge(r, r, &correction);
269250
}
270-
#endif
271251
}
272252
}
273253

0 commit comments

Comments
 (0)