]> Git Repo - secp256k1.git/blame - src/ecmult_impl.h
Add VERIFY_CHECK/DEBUG_CHECK and use CHECK macros more
[secp256k1.git] / src / ecmult_impl.h
CommitLineData
0a433ea2
PW
1// Copyright (c) 2013 Pieter Wuille
2// Distributed under the MIT/X11 software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
7a4b7691
PW
5#ifndef _SECP256K1_ECMULT_IMPL_H_
6#define _SECP256K1_ECMULT_IMPL_H_
7
0592d117 8#include <assert.h>
11ab5622
PW
9#include "num.h"
10#include "group.h"
11#include "ecmult.h"
607884fc 12
eb0be8ee 13// optimal for 128-bit and 256-bit exponents.
607884fc
PW
14#define WINDOW_A 5
15
16// larger numbers may result in slightly better performance, at the cost of
eb0be8ee 17// exponentially larger precomputed tables. WINDOW_G == 14 results in 640 KiB.
607884fc
PW
18#define WINDOW_G 14
19
b1483f87
PW
20/** Fill a table 'pre' with precomputed odd multiples of a. W determines the size of the table.
21 * pre will contains the values [1*a,3*a,5*a,...,(2^(w-1)-1)*a], so it needs place for
22 * 2^(w-2) entries.
23 *
24 * There are two versions of this function:
25 * - secp256k1_ecmult_precomp_wnaf_gej, which operates on group elements in jacobian notation,
26 * fast to precompute, but slower to use in later additions.
27 * - secp256k1_ecmult_precomp_wnaf_ge, which operates on group elements in affine notations,
28 * (much) slower to precompute, but a bit faster to use in later additions.
29 * To compute a*P + b*G, we use the jacobian version for P, and the affine version for G, as
30 * G is constant, so it only needs to be done once in advance.
31 */
32void static secp256k1_ecmult_table_precomp_gej(secp256k1_gej_t *pre, const secp256k1_gej_t *a, int w) {
33 pre[0] = *a;
34 secp256k1_gej_t d; secp256k1_gej_double(&d, &pre[0]);
35 for (int i=1; i<(1 << (w-2)); i++)
36 secp256k1_gej_add(&pre[i], &d, &pre[i-1]);
37}
f11ff5be 38
f16be77f
PD
39void static secp256k1_ecmult_table_precomp_ge(secp256k1_ge_t *pre, const secp256k1_gej_t *a, int w) {
40 const int table_size = 1 << (w-2);
41 secp256k1_gej_t prej[table_size];
42 prej[0] = *a;
43 secp256k1_gej_t d; secp256k1_gej_double(&d, a);
44 for (int i=1; i<table_size; i++) {
45 secp256k1_gej_add(&prej[i], &d, &prej[i-1]);
f11ff5be 46 }
f16be77f 47 secp256k1_ge_set_all_gej(table_size, pre, prej);
b1483f87 48}
f11ff5be 49
b1483f87
PW
50/** The number of entries a table with precomputed multiples needs to have. */
51#define ECMULT_TABLE_SIZE(w) (1 << ((w)-2))
52
53/** The following two macro retrieves a particular odd multiple from a table
54 * of precomputed multiples. */
55#define ECMULT_TABLE_GET(r,pre,n,w,neg) do { \
1c7fa133
PW
56 VERIFY_CHECK(((n) & 1) == 1); \
57 VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \
58 VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \
b1483f87
PW
59 if ((n) > 0) \
60 *(r) = (pre)[((n)-1)/2]; \
61 else \
62 (neg)((r), &(pre)[(-(n)-1)/2]); \
63} while(0)
64
65#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_gej_neg)
66#define ECMULT_TABLE_GET_GE(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_ge_neg)
67
68typedef struct {
65a79b30 69 // For accelerating the computation of a*P + b*G:
b1483f87
PW
70 secp256k1_ge_t pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; // odd multiples of the generator
71 secp256k1_ge_t pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; // odd multiples of 2^128*generator
65a79b30
PW
72
73 // For accelerating the computation of a*G:
74 // To harden against timing attacks, use the following mechanism:
75 // * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63.
76 // * Compute sum((n_i + 1) * 16^i * G, i=0..63).
77 // * Subtract sum(1 * 16^i * G, i=0..63).
78 // For each i, and each of the 16 possible values of n_i, ((n_i + 1) * 16^i * G) is
79 // precomputed (call it prec(i,n_i), as well as -sum(1 * 16^i * G) (called fin).
80 // The formula now becomes sum(prec(i, n_i), i=0..63) + fin.
81 // To make memory access uniform, the bytes of prec(i,n_i) are sliced per value of n_i.
82 unsigned char prec[64][sizeof(secp256k1_ge_t)][16]; // prec[j][k][i] = k'th byte of (16^j * (i+1) * G)
b1483f87
PW
83 secp256k1_ge_t fin; // -(sum(prec[j][0], j=0..63))
84} secp256k1_ecmult_consts_t;
85
f491cd35 86static const secp256k1_ecmult_consts_t *secp256k1_ecmult_consts = NULL;
b1483f87
PW
87
88static void secp256k1_ecmult_start(void) {
89 if (secp256k1_ecmult_consts != NULL)
90 return;
91
92 secp256k1_ecmult_consts_t *ret = (secp256k1_ecmult_consts_t*)malloc(sizeof(secp256k1_ecmult_consts_t));
93 secp256k1_ecmult_consts = ret;
94
95 // get the generator
96 const secp256k1_ge_t *g = &secp256k1_ge_consts->g;
f16be77f 97 secp256k1_gej_t gj; secp256k1_gej_set_ge(&gj, g);
b1483f87
PW
98
99 // calculate 2^128*generator
f16be77f 100 secp256k1_gej_t g_128j = gj;
b1483f87
PW
101 for (int i=0; i<128; i++)
102 secp256k1_gej_double(&g_128j, &g_128j);
b1483f87
PW
103
104 // precompute the tables with odd multiples
f16be77f
PD
105 secp256k1_ecmult_table_precomp_ge(ret->pre_g, &gj, WINDOW_G);
106 secp256k1_ecmult_table_precomp_ge(ret->pre_g_128, &g_128j, WINDOW_G);
b1483f87
PW
107
108 // compute prec and fin
f16be77f
PD
109 secp256k1_gej_t tj[961];
110 int pos = 0;
b1483f87 111 secp256k1_gej_t fn; secp256k1_gej_set_infinity(&fn);
f16be77f
PD
112 for (int j=0; j<64; j++) {
113 secp256k1_gej_add(&fn, &fn, &gj);
114 secp256k1_gej_t adj = gj;
115 for (int i=1; i<16; i++) {
116 secp256k1_gej_add(&gj, &gj, &adj);
117 tj[pos++] = gj;
118 }
119 }
1c7fa133 120 VERIFY_CHECK(pos == 960);
f16be77f
PD
121 tj[pos] = fn;
122 secp256k1_ge_t t[961]; secp256k1_ge_set_all_gej(961, t, tj);
123 pos = 0;
124 const unsigned char *raw = (const unsigned char*)g;
b1483f87 125 for (int j=0; j<64; j++) {
65a79b30 126 for (int k=0; k<sizeof(secp256k1_ge_t); k++)
f16be77f 127 ret->prec[j][k][0] = raw[k];
b1483f87 128 for (int i=1; i<16; i++) {
f16be77f 129 raw = (const unsigned char*)(&t[pos++]);
65a79b30 130 for (int k=0; k<sizeof(secp256k1_ge_t); k++)
f16be77f 131 ret->prec[j][k][i] = raw[k];
607884fc
PW
132 }
133 }
1c7fa133 134 VERIFY_CHECK(pos == 960);
f16be77f 135 secp256k1_ge_neg(&ret->fin, &t[pos]);
b1483f87 136}
607884fc 137
b1483f87
PW
138static void secp256k1_ecmult_stop(void) {
139 if (secp256k1_ecmult_consts == NULL)
140 return;
607884fc 141
f491cd35
PW
142 secp256k1_ecmult_consts_t *c = (secp256k1_ecmult_consts_t*)secp256k1_ecmult_consts;
143 free(c);
b1483f87
PW
144 secp256k1_ecmult_consts = NULL;
145}
607884fc 146
b1483f87
PW
147/** Convert a number to WNAF notation. The number becomes represented by sum(2^i * wnaf[i], i=0..bits),
148 * with the following guarantees:
149 * - each wnaf[i] is either 0, or an odd integer between -(1<<(w-1) - 1) and (1<<(w-1) - 1)
150 * - two non-zero entries in wnaf are separated by at least w-1 zeroes.
151 * - the index of the highest non-zero entry in wnaf (=return value-1) is at most bits, where
152 * bits is the number of bits necessary to represent the absolute value of the input.
153 */
154static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_num_t *a, int w) {
155 int ret = 0;
156 int zeroes = 0;
157 secp256k1_num_t x;
158 secp256k1_num_init(&x);
159 secp256k1_num_copy(&x, a);
160 int sign = 1;
161 if (secp256k1_num_is_neg(&x)) {
162 sign = -1;
163 secp256k1_num_negate(&x);
607884fc 164 }
b1483f87
PW
165 while (!secp256k1_num_is_zero(&x)) {
166 while (!secp256k1_num_is_odd(&x)) {
167 zeroes++;
168 secp256k1_num_shift(&x, 1);
607884fc 169 }
b1483f87
PW
170 int word = secp256k1_num_shift(&x, w);
171 while (zeroes) {
172 wnaf[ret++] = 0;
173 zeroes--;
607884fc 174 }
b1483f87
PW
175 if (word & (1 << (w-1))) {
176 secp256k1_num_inc(&x);
177 wnaf[ret++] = sign * (word - (1 << w));
178 } else {
179 wnaf[ret++] = sign * word;
0a07e62f 180 }
b1483f87 181 zeroes = w-1;
607884fc 182 }
b1483f87
PW
183 secp256k1_num_free(&x);
184 return ret;
607884fc
PW
185}
186
b1483f87 187void static secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_num_t *gn) {
4adf6b2a
PW
188 secp256k1_num_t n;
189 secp256k1_num_init(&n);
b1483f87
PW
190 secp256k1_num_copy(&n, gn);
191 const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts;
65a79b30 192 secp256k1_gej_set_infinity(r);
2f6c8019
GM
193 secp256k1_ge_t add;
194 int bits;
65a79b30 195 for (int j=0; j<64; j++) {
2f6c8019 196 bits = secp256k1_num_shift(&n, 4);
65a79b30
PW
197 for (int k=0; k<sizeof(secp256k1_ge_t); k++)
198 ((unsigned char*)(&add))[k] = c->prec[j][k][bits];
199 secp256k1_gej_add_ge(r, r, &add);
200 }
2f6c8019
GM
201 bits = 0;
202 secp256k1_ge_clear(&add);
203 secp256k1_num_clear(&n);
4adf6b2a 204 secp256k1_num_free(&n);
b1483f87 205 secp256k1_gej_add_ge(r, r, &c->fin);
0a07e62f
PW
206}
207
b1483f87
PW
208void static secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_num_t *na, const secp256k1_num_t *ng) {
209 const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts;
210
399c03f2 211#ifdef USE_ENDOMORPHISM
b1483f87 212 secp256k1_num_t na_1, na_lam;
b1483f87
PW
213 secp256k1_num_init(&na_1);
214 secp256k1_num_init(&na_lam);
b1483f87
PW
215 // split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit)
216 secp256k1_gej_split_exp(&na_1, &na_lam, na);
b1483f87 217
399c03f2 218 // build wnaf representation for na_1 and na_lam.
b1483f87
PW
219 int wnaf_na_1[129]; int bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A);
220 int wnaf_na_lam[129]; int bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, &na_lam, WINDOW_A);
399c03f2
PW
221 int bits = bits_na_1;
222 if (bits_na_lam > bits) bits = bits_na_lam;
399c03f2
PW
223#else
224 // build wnaf representation for na.
225 int wnaf_na[257]; int bits_na = secp256k1_ecmult_wnaf(wnaf_na, na, WINDOW_A);
226 int bits = bits_na;
227#endif
b1483f87 228
399c03f2
PW
229 // calculate odd multiples of a
230 secp256k1_gej_t pre_a[ECMULT_TABLE_SIZE(WINDOW_A)];
231 secp256k1_ecmult_table_precomp_gej(pre_a, a, WINDOW_A);
232
d7fd4d0f
PD
233#ifdef USE_ENDOMORPHISM
234 secp256k1_gej_t pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)];
235 for (int i=0; i<ECMULT_TABLE_SIZE(WINDOW_A); i++)
236 secp256k1_gej_mul_lambda(&pre_a_lam[i], &pre_a[i]);
237#endif
238
399c03f2
PW
239 // Splitted G factors.
240 secp256k1_num_t ng_1, ng_128;
241 secp256k1_num_init(&ng_1);
242 secp256k1_num_init(&ng_128);
243
244 // 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)
245 secp256k1_num_split(&ng_1, &ng_128, ng, 128);
246
247 // Build wnaf representation for ng_1 and ng_128
248 int wnaf_ng_1[129]; int bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G);
249 int wnaf_ng_128[129]; int bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, &ng_128, WINDOW_G);
eb0be8ee
PW
250 if (bits_ng_1 > bits) bits = bits_ng_1;
251 if (bits_ng_128 > bits) bits = bits_ng_128;
b1483f87
PW
252
253 secp256k1_gej_set_infinity(r);
f11ff5be
PW
254 secp256k1_gej_t tmpj;
255 secp256k1_ge_t tmpa;
607884fc 256
b1483f87
PW
257 for (int i=bits-1; i>=0; i--) {
258 secp256k1_gej_double(r, r);
259 int n;
399c03f2 260#ifdef USE_ENDOMORPHISM
b1483f87 261 if (i < bits_na_1 && (n = wnaf_na_1[i])) {
399c03f2 262 ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A);
b1483f87 263 secp256k1_gej_add(r, r, &tmpj);
607884fc 264 }
b1483f87
PW
265 if (i < bits_na_lam && (n = wnaf_na_lam[i])) {
266 ECMULT_TABLE_GET_GEJ(&tmpj, pre_a_lam, n, WINDOW_A);
267 secp256k1_gej_add(r, r, &tmpj);
607884fc 268 }
399c03f2
PW
269#else
270 if (i < bits_na && (n = wnaf_na[i])) {
271 ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A);
272 secp256k1_gej_add(r, r, &tmpj);
273 }
274#endif
b1483f87
PW
275 if (i < bits_ng_1 && (n = wnaf_ng_1[i])) {
276 ECMULT_TABLE_GET_GE(&tmpa, c->pre_g, n, WINDOW_G);
277 secp256k1_gej_add_ge(r, r, &tmpa);
607884fc 278 }
b1483f87
PW
279 if (i < bits_ng_128 && (n = wnaf_ng_128[i])) {
280 ECMULT_TABLE_GET_GE(&tmpa, c->pre_g_128, n, WINDOW_G);
281 secp256k1_gej_add_ge(r, r, &tmpa);
607884fc
PW
282 }
283 }
4adf6b2a 284
399c03f2 285#ifdef USE_ENDOMORPHISM
b1483f87
PW
286 secp256k1_num_free(&na_1);
287 secp256k1_num_free(&na_lam);
399c03f2 288#endif
b1483f87
PW
289 secp256k1_num_free(&ng_1);
290 secp256k1_num_free(&ng_128);
607884fc 291}
7a4b7691
PW
292
293#endif
This page took 0.066171 seconds and 4 git commands to generate.