Dash Core  0.12.2.1
P2P Digital Currency
scalar_impl.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (c) 2014 Pieter Wuille *
3  * Distributed under the MIT software license, see the accompanying *
4  * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
5  **********************************************************************/
6 
7 #ifndef _SECP256K1_SCALAR_IMPL_H_
8 #define _SECP256K1_SCALAR_IMPL_H_
9 
10 #include <string.h>
11 
12 #include "group.h"
13 #include "scalar.h"
14 
15 #if defined HAVE_CONFIG_H
16 #include "libsecp256k1-config.h"
17 #endif
18 
19 #if defined(USE_SCALAR_4X64)
20 #include "scalar_4x64_impl.h"
21 #elif defined(USE_SCALAR_8X32)
22 #include "scalar_8x32_impl.h"
23 #else
24 #error "Please select scalar implementation"
25 #endif
26 
27 #ifndef USE_NUM_NONE
29  unsigned char c[32];
31  secp256k1_num_set_bin(r, c, 32);
32 }
33 
36  static const unsigned char order[32] = {
37  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
38  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
39  0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
40  0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41
41  };
42  secp256k1_num_set_bin(r, order, 32);
43 }
44 #endif
45 
48  int i;
49  /* First compute x ^ (2^N - 1) for some values of N. */
50  secp256k1_scalar x2, x3, x4, x6, x7, x8, x15, x30, x60, x120, x127;
51 
52  secp256k1_scalar_sqr(&x2, x);
53  secp256k1_scalar_mul(&x2, &x2, x);
54 
55  secp256k1_scalar_sqr(&x3, &x2);
56  secp256k1_scalar_mul(&x3, &x3, x);
57 
58  secp256k1_scalar_sqr(&x4, &x3);
59  secp256k1_scalar_mul(&x4, &x4, x);
60 
61  secp256k1_scalar_sqr(&x6, &x4);
62  secp256k1_scalar_sqr(&x6, &x6);
63  secp256k1_scalar_mul(&x6, &x6, &x2);
64 
65  secp256k1_scalar_sqr(&x7, &x6);
66  secp256k1_scalar_mul(&x7, &x7, x);
67 
68  secp256k1_scalar_sqr(&x8, &x7);
69  secp256k1_scalar_mul(&x8, &x8, x);
70 
71  secp256k1_scalar_sqr(&x15, &x8);
72  for (i = 0; i < 6; i++) {
73  secp256k1_scalar_sqr(&x15, &x15);
74  }
75  secp256k1_scalar_mul(&x15, &x15, &x7);
76 
77  secp256k1_scalar_sqr(&x30, &x15);
78  for (i = 0; i < 14; i++) {
79  secp256k1_scalar_sqr(&x30, &x30);
80  }
81  secp256k1_scalar_mul(&x30, &x30, &x15);
82 
83  secp256k1_scalar_sqr(&x60, &x30);
84  for (i = 0; i < 29; i++) {
85  secp256k1_scalar_sqr(&x60, &x60);
86  }
87  secp256k1_scalar_mul(&x60, &x60, &x30);
88 
89  secp256k1_scalar_sqr(&x120, &x60);
90  for (i = 0; i < 59; i++) {
91  secp256k1_scalar_sqr(&x120, &x120);
92  }
93  secp256k1_scalar_mul(&x120, &x120, &x60);
94 
95  secp256k1_scalar_sqr(&x127, &x120);
96  for (i = 0; i < 6; i++) {
97  secp256k1_scalar_sqr(&x127, &x127);
98  }
99  secp256k1_scalar_mul(&x127, &x127, &x7);
100 
101  /* Then accumulate the final result (t starts at x127). */
102  t = &x127;
103  for (i = 0; i < 2; i++) { /* 0 */
104  secp256k1_scalar_sqr(t, t);
105  }
106  secp256k1_scalar_mul(t, t, x); /* 1 */
107  for (i = 0; i < 4; i++) { /* 0 */
108  secp256k1_scalar_sqr(t, t);
109  }
110  secp256k1_scalar_mul(t, t, &x3); /* 111 */
111  for (i = 0; i < 2; i++) { /* 0 */
112  secp256k1_scalar_sqr(t, t);
113  }
114  secp256k1_scalar_mul(t, t, x); /* 1 */
115  for (i = 0; i < 2; i++) { /* 0 */
116  secp256k1_scalar_sqr(t, t);
117  }
118  secp256k1_scalar_mul(t, t, x); /* 1 */
119  for (i = 0; i < 2; i++) { /* 0 */
120  secp256k1_scalar_sqr(t, t);
121  }
122  secp256k1_scalar_mul(t, t, x); /* 1 */
123  for (i = 0; i < 4; i++) { /* 0 */
124  secp256k1_scalar_sqr(t, t);
125  }
126  secp256k1_scalar_mul(t, t, &x3); /* 111 */
127  for (i = 0; i < 3; i++) { /* 0 */
128  secp256k1_scalar_sqr(t, t);
129  }
130  secp256k1_scalar_mul(t, t, &x2); /* 11 */
131  for (i = 0; i < 4; i++) { /* 0 */
132  secp256k1_scalar_sqr(t, t);
133  }
134  secp256k1_scalar_mul(t, t, &x3); /* 111 */
135  for (i = 0; i < 5; i++) { /* 00 */
136  secp256k1_scalar_sqr(t, t);
137  }
138  secp256k1_scalar_mul(t, t, &x3); /* 111 */
139  for (i = 0; i < 4; i++) { /* 00 */
140  secp256k1_scalar_sqr(t, t);
141  }
142  secp256k1_scalar_mul(t, t, &x2); /* 11 */
143  for (i = 0; i < 2; i++) { /* 0 */
144  secp256k1_scalar_sqr(t, t);
145  }
146  secp256k1_scalar_mul(t, t, x); /* 1 */
147  for (i = 0; i < 2; i++) { /* 0 */
148  secp256k1_scalar_sqr(t, t);
149  }
150  secp256k1_scalar_mul(t, t, x); /* 1 */
151  for (i = 0; i < 5; i++) { /* 0 */
152  secp256k1_scalar_sqr(t, t);
153  }
154  secp256k1_scalar_mul(t, t, &x4); /* 1111 */
155  for (i = 0; i < 2; i++) { /* 0 */
156  secp256k1_scalar_sqr(t, t);
157  }
158  secp256k1_scalar_mul(t, t, x); /* 1 */
159  for (i = 0; i < 3; i++) { /* 00 */
160  secp256k1_scalar_sqr(t, t);
161  }
162  secp256k1_scalar_mul(t, t, x); /* 1 */
163  for (i = 0; i < 4; i++) { /* 000 */
164  secp256k1_scalar_sqr(t, t);
165  }
166  secp256k1_scalar_mul(t, t, x); /* 1 */
167  for (i = 0; i < 2; i++) { /* 0 */
168  secp256k1_scalar_sqr(t, t);
169  }
170  secp256k1_scalar_mul(t, t, x); /* 1 */
171  for (i = 0; i < 10; i++) { /* 0000000 */
172  secp256k1_scalar_sqr(t, t);
173  }
174  secp256k1_scalar_mul(t, t, &x3); /* 111 */
175  for (i = 0; i < 4; i++) { /* 0 */
176  secp256k1_scalar_sqr(t, t);
177  }
178  secp256k1_scalar_mul(t, t, &x3); /* 111 */
179  for (i = 0; i < 9; i++) { /* 0 */
180  secp256k1_scalar_sqr(t, t);
181  }
182  secp256k1_scalar_mul(t, t, &x8); /* 11111111 */
183  for (i = 0; i < 2; i++) { /* 0 */
184  secp256k1_scalar_sqr(t, t);
185  }
186  secp256k1_scalar_mul(t, t, x); /* 1 */
187  for (i = 0; i < 3; i++) { /* 00 */
188  secp256k1_scalar_sqr(t, t);
189  }
190  secp256k1_scalar_mul(t, t, x); /* 1 */
191  for (i = 0; i < 3; i++) { /* 00 */
192  secp256k1_scalar_sqr(t, t);
193  }
194  secp256k1_scalar_mul(t, t, x); /* 1 */
195  for (i = 0; i < 5; i++) { /* 0 */
196  secp256k1_scalar_sqr(t, t);
197  }
198  secp256k1_scalar_mul(t, t, &x4); /* 1111 */
199  for (i = 0; i < 2; i++) { /* 0 */
200  secp256k1_scalar_sqr(t, t);
201  }
202  secp256k1_scalar_mul(t, t, x); /* 1 */
203  for (i = 0; i < 5; i++) { /* 000 */
204  secp256k1_scalar_sqr(t, t);
205  }
206  secp256k1_scalar_mul(t, t, &x2); /* 11 */
207  for (i = 0; i < 4; i++) { /* 00 */
208  secp256k1_scalar_sqr(t, t);
209  }
210  secp256k1_scalar_mul(t, t, &x2); /* 11 */
211  for (i = 0; i < 2; i++) { /* 0 */
212  secp256k1_scalar_sqr(t, t);
213  }
214  secp256k1_scalar_mul(t, t, x); /* 1 */
215  for (i = 0; i < 8; i++) { /* 000000 */
216  secp256k1_scalar_sqr(t, t);
217  }
218  secp256k1_scalar_mul(t, t, &x2); /* 11 */
219  for (i = 0; i < 3; i++) { /* 0 */
220  secp256k1_scalar_sqr(t, t);
221  }
222  secp256k1_scalar_mul(t, t, &x2); /* 11 */
223  for (i = 0; i < 3; i++) { /* 00 */
224  secp256k1_scalar_sqr(t, t);
225  }
226  secp256k1_scalar_mul(t, t, x); /* 1 */
227  for (i = 0; i < 6; i++) { /* 00000 */
228  secp256k1_scalar_sqr(t, t);
229  }
230  secp256k1_scalar_mul(t, t, x); /* 1 */
231  for (i = 0; i < 8; i++) { /* 00 */
232  secp256k1_scalar_sqr(t, t);
233  }
234  secp256k1_scalar_mul(r, t, &x6); /* 111111 */
235 }
236 
238  /* d[0] is present and is the lowest word for all representations */
239  return !(a->d[0] & 1);
240 }
241 
243 #if defined(USE_SCALAR_INV_BUILTIN)
245 #elif defined(USE_SCALAR_INV_NUM)
246  unsigned char b[32];
247  secp256k1_num n, m;
248  secp256k1_scalar t = *x;
250  secp256k1_num_set_bin(&n, b, 32);
253  secp256k1_num_get_bin(b, 32, &n);
254  secp256k1_scalar_set_b32(r, b, NULL);
255  /* Verify that the inverse was computed correctly, without GMP code. */
256  secp256k1_scalar_mul(&t, &t, r);
258 #else
259 #error "Please select scalar inverse implementation"
260 #endif
261 }
262 
263 #ifdef USE_ENDOMORPHISM
264 
302 static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) {
303  secp256k1_scalar c1, c2;
304  static const secp256k1_scalar minus_lambda = SECP256K1_SCALAR_CONST(
305  0xAC9C52B3UL, 0x3FA3CF1FUL, 0x5AD9E3FDUL, 0x77ED9BA4UL,
306  0xA880B9FCUL, 0x8EC739C2UL, 0xE0CFC810UL, 0xB51283CFUL
307  );
308  static const secp256k1_scalar minus_b1 = SECP256K1_SCALAR_CONST(
309  0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
310  0xE4437ED6UL, 0x010E8828UL, 0x6F547FA9UL, 0x0ABFE4C3UL
311  );
312  static const secp256k1_scalar minus_b2 = SECP256K1_SCALAR_CONST(
313  0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL,
314  0x8A280AC5UL, 0x0774346DUL, 0xD765CDA8UL, 0x3DB1562CUL
315  );
316  static const secp256k1_scalar g1 = SECP256K1_SCALAR_CONST(
317  0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00003086UL,
318  0xD221A7D4UL, 0x6BCDE86CUL, 0x90E49284UL, 0xEB153DABUL
319  );
320  static const secp256k1_scalar g2 = SECP256K1_SCALAR_CONST(
321  0x00000000UL, 0x00000000UL, 0x00000000UL, 0x0000E443UL,
322  0x7ED6010EUL, 0x88286F54UL, 0x7FA90ABFUL, 0xE4C42212UL
323  );
324  VERIFY_CHECK(r1 != a);
325  VERIFY_CHECK(r2 != a);
326  /* these _var calls are constant time since the shift amount is constant */
327  secp256k1_scalar_mul_shift_var(&c1, a, &g1, 272);
328  secp256k1_scalar_mul_shift_var(&c2, a, &g2, 272);
329  secp256k1_scalar_mul(&c1, &c1, &minus_b1);
330  secp256k1_scalar_mul(&c2, &c2, &minus_b2);
331  secp256k1_scalar_add(r2, &c1, &c2);
332  secp256k1_scalar_mul(r1, r2, &minus_lambda);
333  secp256k1_scalar_add(r1, r1, a);
334 }
335 #endif
336 
337 #endif
static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b)
#define VERIFY_CHECK(cond)
Definition: util.h:64
static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen)
static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x)
Definition: scalar_impl.h:46
static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow)
static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m)
static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift)
#define SECP256K1_INLINE
Definition: secp256k1.h:116
static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x)
Definition: scalar_impl.h:242
#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0)
Definition: scalar_4x64.h:17
static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a)
#define CHECK(cond)
Definition: util.h:52
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar *a)
uint64_t d[4]
Definition: scalar_4x64.h:14
static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b)
static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a)
Definition: scalar_impl.h:28
static void secp256k1_scalar_order_get_num(secp256k1_num *r)
Definition: scalar_impl.h:35
static SECP256K1_INLINE int secp256k1_scalar_is_even(const secp256k1_scalar *a)
Definition: scalar_impl.h:237
static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a)
static int secp256k1_scalar_is_one(const secp256k1_scalar *a)