Dash Core  0.12.2.1
P2P Digital Currency
field_impl.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (c) 2013, 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_FIELD_IMPL_H_
8 #define _SECP256K1_FIELD_IMPL_H_
9 
10 #if defined HAVE_CONFIG_H
11 #include "libsecp256k1-config.h"
12 #endif
13 
14 #include "util.h"
15 
16 #if defined(USE_FIELD_10X26)
17 #include "field_10x26_impl.h"
18 #elif defined(USE_FIELD_5X52)
19 #include "field_5x52_impl.h"
20 #else
21 #error "Please select field implementation"
22 #endif
23 
25  secp256k1_fe na;
26  secp256k1_fe_negate(&na, a, 1);
27  secp256k1_fe_add(&na, b);
29 }
30 
41  secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1;
42  int j;
43 
49  secp256k1_fe_sqr(&x2, a);
50  secp256k1_fe_mul(&x2, &x2, a);
51 
52  secp256k1_fe_sqr(&x3, &x2);
53  secp256k1_fe_mul(&x3, &x3, a);
54 
55  x6 = x3;
56  for (j=0; j<3; j++) {
57  secp256k1_fe_sqr(&x6, &x6);
58  }
59  secp256k1_fe_mul(&x6, &x6, &x3);
60 
61  x9 = x6;
62  for (j=0; j<3; j++) {
63  secp256k1_fe_sqr(&x9, &x9);
64  }
65  secp256k1_fe_mul(&x9, &x9, &x3);
66 
67  x11 = x9;
68  for (j=0; j<2; j++) {
69  secp256k1_fe_sqr(&x11, &x11);
70  }
71  secp256k1_fe_mul(&x11, &x11, &x2);
72 
73  x22 = x11;
74  for (j=0; j<11; j++) {
75  secp256k1_fe_sqr(&x22, &x22);
76  }
77  secp256k1_fe_mul(&x22, &x22, &x11);
78 
79  x44 = x22;
80  for (j=0; j<22; j++) {
81  secp256k1_fe_sqr(&x44, &x44);
82  }
83  secp256k1_fe_mul(&x44, &x44, &x22);
84 
85  x88 = x44;
86  for (j=0; j<44; j++) {
87  secp256k1_fe_sqr(&x88, &x88);
88  }
89  secp256k1_fe_mul(&x88, &x88, &x44);
90 
91  x176 = x88;
92  for (j=0; j<88; j++) {
93  secp256k1_fe_sqr(&x176, &x176);
94  }
95  secp256k1_fe_mul(&x176, &x176, &x88);
96 
97  x220 = x176;
98  for (j=0; j<44; j++) {
99  secp256k1_fe_sqr(&x220, &x220);
100  }
101  secp256k1_fe_mul(&x220, &x220, &x44);
102 
103  x223 = x220;
104  for (j=0; j<3; j++) {
105  secp256k1_fe_sqr(&x223, &x223);
106  }
107  secp256k1_fe_mul(&x223, &x223, &x3);
108 
109  /* The final result is then assembled using a sliding window over the blocks. */
110 
111  t1 = x223;
112  for (j=0; j<23; j++) {
113  secp256k1_fe_sqr(&t1, &t1);
114  }
115  secp256k1_fe_mul(&t1, &t1, &x22);
116  for (j=0; j<6; j++) {
117  secp256k1_fe_sqr(&t1, &t1);
118  }
119  secp256k1_fe_mul(&t1, &t1, &x2);
120  secp256k1_fe_sqr(&t1, &t1);
121  secp256k1_fe_sqr(r, &t1);
122 
123  /* Check that a square root was actually calculated */
124 
125  secp256k1_fe_sqr(&t1, r);
126  return secp256k1_fe_equal_var(&t1, a);
127 }
128 
129 static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a) {
130  secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1;
131  int j;
132 
138  secp256k1_fe_sqr(&x2, a);
139  secp256k1_fe_mul(&x2, &x2, a);
140 
141  secp256k1_fe_sqr(&x3, &x2);
142  secp256k1_fe_mul(&x3, &x3, a);
143 
144  x6 = x3;
145  for (j=0; j<3; j++) {
146  secp256k1_fe_sqr(&x6, &x6);
147  }
148  secp256k1_fe_mul(&x6, &x6, &x3);
149 
150  x9 = x6;
151  for (j=0; j<3; j++) {
152  secp256k1_fe_sqr(&x9, &x9);
153  }
154  secp256k1_fe_mul(&x9, &x9, &x3);
155 
156  x11 = x9;
157  for (j=0; j<2; j++) {
158  secp256k1_fe_sqr(&x11, &x11);
159  }
160  secp256k1_fe_mul(&x11, &x11, &x2);
161 
162  x22 = x11;
163  for (j=0; j<11; j++) {
164  secp256k1_fe_sqr(&x22, &x22);
165  }
166  secp256k1_fe_mul(&x22, &x22, &x11);
167 
168  x44 = x22;
169  for (j=0; j<22; j++) {
170  secp256k1_fe_sqr(&x44, &x44);
171  }
172  secp256k1_fe_mul(&x44, &x44, &x22);
173 
174  x88 = x44;
175  for (j=0; j<44; j++) {
176  secp256k1_fe_sqr(&x88, &x88);
177  }
178  secp256k1_fe_mul(&x88, &x88, &x44);
179 
180  x176 = x88;
181  for (j=0; j<88; j++) {
182  secp256k1_fe_sqr(&x176, &x176);
183  }
184  secp256k1_fe_mul(&x176, &x176, &x88);
185 
186  x220 = x176;
187  for (j=0; j<44; j++) {
188  secp256k1_fe_sqr(&x220, &x220);
189  }
190  secp256k1_fe_mul(&x220, &x220, &x44);
191 
192  x223 = x220;
193  for (j=0; j<3; j++) {
194  secp256k1_fe_sqr(&x223, &x223);
195  }
196  secp256k1_fe_mul(&x223, &x223, &x3);
197 
198  /* The final result is then assembled using a sliding window over the blocks. */
199 
200  t1 = x223;
201  for (j=0; j<23; j++) {
202  secp256k1_fe_sqr(&t1, &t1);
203  }
204  secp256k1_fe_mul(&t1, &t1, &x22);
205  for (j=0; j<5; j++) {
206  secp256k1_fe_sqr(&t1, &t1);
207  }
208  secp256k1_fe_mul(&t1, &t1, a);
209  for (j=0; j<3; j++) {
210  secp256k1_fe_sqr(&t1, &t1);
211  }
212  secp256k1_fe_mul(&t1, &t1, &x2);
213  for (j=0; j<2; j++) {
214  secp256k1_fe_sqr(&t1, &t1);
215  }
216  secp256k1_fe_mul(r, a, &t1);
217 }
218 
219 static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a) {
220 #if defined(USE_FIELD_INV_BUILTIN)
221  secp256k1_fe_inv(r, a);
222 #elif defined(USE_FIELD_INV_NUM)
223  secp256k1_num n, m;
224  static const secp256k1_fe negone = SECP256K1_FE_CONST(
225  0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL,
226  0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, 0xFFFFFC2EUL
227  );
228  /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */
229  static const unsigned char prime[32] = {
230  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
231  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
232  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
233  0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F
234  };
235  unsigned char b[32];
236  int res;
237  secp256k1_fe c = *a;
239  secp256k1_fe_get_b32(b, &c);
240  secp256k1_num_set_bin(&n, b, 32);
241  secp256k1_num_set_bin(&m, prime, 32);
243  secp256k1_num_get_bin(b, 32, &n);
244  res = secp256k1_fe_set_b32(r, b);
245  (void)res;
246  VERIFY_CHECK(res);
247  /* Verify the result is the (unique) valid inverse using non-GMP code. */
248  secp256k1_fe_mul(&c, &c, r);
249  secp256k1_fe_add(&c, &negone);
251 #else
252 #error "Please select field inverse implementation"
253 #endif
254 }
255 
256 static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe *r, const secp256k1_fe *a) {
257  secp256k1_fe u;
258  size_t i;
259  if (len < 1) {
260  return;
261  }
262 
263  VERIFY_CHECK((r + len <= a) || (a + len <= r));
264 
265  r[0] = a[0];
266 
267  i = 0;
268  while (++i < len) {
269  secp256k1_fe_mul(&r[i], &r[i - 1], &a[i]);
270  }
271 
272  secp256k1_fe_inv_var(&u, &r[--i]);
273 
274  while (i > 0) {
275  size_t j = i--;
276  secp256k1_fe_mul(&r[j], &r[i], &u);
277  secp256k1_fe_mul(&u, &u, &a[j]);
278  }
279 
280  r[0] = u;
281 }
282 
283 #endif
#define VERIFY_CHECK(cond)
Definition: util.h:64
static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe *SECP256K1_RESTRICT b)
static void secp256k1_fe_normalize_var(secp256k1_fe *r)
static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen)
static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m)
static SECP256K1_INLINE int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b)
Definition: field_impl.h:24
static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m)
#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0)
Definition: field_10x26.h:38
static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a)
#define SECP256K1_INLINE
Definition: secp256k1.h:116
static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a)
Definition: field_impl.h:129
static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a)
Definition: field_impl.h:219
#define CHECK(cond)
Definition: util.h:52
static int secp256k1_fe_sqrt_var(secp256k1_fe *r, const secp256k1_fe *a)
Definition: field_impl.h:31
static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a)
static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a)
static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe *r, const secp256k1_fe *a)
Definition: field_impl.h:256
static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a)
static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a)
static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r)