Bitcoin Core  29.1.0
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 https://www.opensource.org/licenses/mit-license.php.*
5  ***********************************************************************/
6 
7 #ifndef SECP256K1_FIELD_IMPL_H
8 #define SECP256K1_FIELD_IMPL_H
9 
10 #include "field.h"
11 #include "util.h"
12 
13 #if defined(SECP256K1_WIDEMUL_INT128)
14 #include "field_5x52_impl.h"
15 #elif defined(SECP256K1_WIDEMUL_INT64)
16 #include "field_10x26_impl.h"
17 #else
18 #error "Please select wide multiplication implementation"
19 #endif
20 
22  secp256k1_memclear(a, sizeof(secp256k1_fe));
23 }
24 
26  secp256k1_fe na;
31 
32  secp256k1_fe_negate(&na, a, 1);
33  secp256k1_fe_add(&na, b);
35 }
36 
47  secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1;
48  int j, ret;
49 
50  VERIFY_CHECK(r != a);
53 
59  secp256k1_fe_sqr(&x2, a);
60  secp256k1_fe_mul(&x2, &x2, a);
61 
62  secp256k1_fe_sqr(&x3, &x2);
63  secp256k1_fe_mul(&x3, &x3, a);
64 
65  x6 = x3;
66  for (j=0; j<3; j++) {
67  secp256k1_fe_sqr(&x6, &x6);
68  }
69  secp256k1_fe_mul(&x6, &x6, &x3);
70 
71  x9 = x6;
72  for (j=0; j<3; j++) {
73  secp256k1_fe_sqr(&x9, &x9);
74  }
75  secp256k1_fe_mul(&x9, &x9, &x3);
76 
77  x11 = x9;
78  for (j=0; j<2; j++) {
79  secp256k1_fe_sqr(&x11, &x11);
80  }
81  secp256k1_fe_mul(&x11, &x11, &x2);
82 
83  x22 = x11;
84  for (j=0; j<11; j++) {
85  secp256k1_fe_sqr(&x22, &x22);
86  }
87  secp256k1_fe_mul(&x22, &x22, &x11);
88 
89  x44 = x22;
90  for (j=0; j<22; j++) {
91  secp256k1_fe_sqr(&x44, &x44);
92  }
93  secp256k1_fe_mul(&x44, &x44, &x22);
94 
95  x88 = x44;
96  for (j=0; j<44; j++) {
97  secp256k1_fe_sqr(&x88, &x88);
98  }
99  secp256k1_fe_mul(&x88, &x88, &x44);
100 
101  x176 = x88;
102  for (j=0; j<88; j++) {
103  secp256k1_fe_sqr(&x176, &x176);
104  }
105  secp256k1_fe_mul(&x176, &x176, &x88);
106 
107  x220 = x176;
108  for (j=0; j<44; j++) {
109  secp256k1_fe_sqr(&x220, &x220);
110  }
111  secp256k1_fe_mul(&x220, &x220, &x44);
112 
113  x223 = x220;
114  for (j=0; j<3; j++) {
115  secp256k1_fe_sqr(&x223, &x223);
116  }
117  secp256k1_fe_mul(&x223, &x223, &x3);
118 
119  /* The final result is then assembled using a sliding window over the blocks. */
120 
121  t1 = x223;
122  for (j=0; j<23; j++) {
123  secp256k1_fe_sqr(&t1, &t1);
124  }
125  secp256k1_fe_mul(&t1, &t1, &x22);
126  for (j=0; j<6; j++) {
127  secp256k1_fe_sqr(&t1, &t1);
128  }
129  secp256k1_fe_mul(&t1, &t1, &x2);
130  secp256k1_fe_sqr(&t1, &t1);
131  secp256k1_fe_sqr(r, &t1);
132 
133  /* Check that a square root was actually calculated */
134 
135  secp256k1_fe_sqr(&t1, r);
136  ret = secp256k1_fe_equal(&t1, a);
137 
138 #ifdef VERIFY
139  if (!ret) {
140  secp256k1_fe_negate(&t1, &t1, 1);
143  }
144 #endif
145  return ret;
146 }
147 
148 #ifndef VERIFY
149 static void secp256k1_fe_verify(const secp256k1_fe *a) { (void)a; }
150 static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m) { (void)a; (void)m; }
151 #else
152 static void secp256k1_fe_impl_verify(const secp256k1_fe *a);
153 static void secp256k1_fe_verify(const secp256k1_fe *a) {
154  /* Magnitude between 0 and 32. */
156  /* Normalized is 0 or 1. */
157  VERIFY_CHECK((a->normalized == 0) || (a->normalized == 1));
158  /* If normalized, magnitude must be 0 or 1. */
159  if (a->normalized) SECP256K1_FE_VERIFY_MAGNITUDE(a, 1);
160  /* Invoke implementation-specific checks. */
161  secp256k1_fe_impl_verify(a);
162 }
163 
164 static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m) {
165  VERIFY_CHECK(m >= 0);
166  VERIFY_CHECK(m <= 32);
167  VERIFY_CHECK(a->magnitude <= m);
168 }
169 
173 
175  r->magnitude = 1;
176  r->normalized = 1;
177 
179 }
180 
184 
186  r->magnitude = 1;
187 
189 }
190 
194 
196  r->magnitude = 1;
197  r->normalized = 1;
198 
200 }
201 
205 
207 }
208 
212 
214 }
215 
216 static void secp256k1_fe_impl_set_int(secp256k1_fe *r, int a);
217 SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) {
218  VERIFY_CHECK(0 <= a && a <= 0x7FFF);
219 
221  r->magnitude = (a != 0);
222  r->normalized = 1;
223 
225 }
226 
227 static void secp256k1_fe_impl_add_int(secp256k1_fe *r, int a);
228 SECP256K1_INLINE static void secp256k1_fe_add_int(secp256k1_fe *r, int a) {
229  VERIFY_CHECK(0 <= a && a <= 0x7FFF);
231 
233  r->magnitude += 1;
234  r->normalized = 0;
235 
237 }
238 
239 static int secp256k1_fe_impl_is_zero(const secp256k1_fe *a);
242  VERIFY_CHECK(a->normalized);
243 
244  return secp256k1_fe_impl_is_zero(a);
245 }
246 
247 static int secp256k1_fe_impl_is_odd(const secp256k1_fe *a);
250  VERIFY_CHECK(a->normalized);
251 
252  return secp256k1_fe_impl_is_odd(a);
253 }
254 
255 static int secp256k1_fe_impl_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b);
256 SECP256K1_INLINE static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) {
259  VERIFY_CHECK(a->normalized);
260  VERIFY_CHECK(b->normalized);
261 
262  return secp256k1_fe_impl_cmp_var(a, b);
263 }
264 
265 static void secp256k1_fe_impl_set_b32_mod(secp256k1_fe *r, const unsigned char *a);
266 SECP256K1_INLINE static void secp256k1_fe_set_b32_mod(secp256k1_fe *r, const unsigned char *a) {
268  r->magnitude = 1;
269  r->normalized = 0;
270 
272 }
273 
274 static int secp256k1_fe_impl_set_b32_limit(secp256k1_fe *r, const unsigned char *a);
275 SECP256K1_INLINE static int secp256k1_fe_set_b32_limit(secp256k1_fe *r, const unsigned char *a) {
277  r->magnitude = 1;
278  r->normalized = 1;
280  return 1;
281  } else {
282  /* Mark the output field element as invalid. */
283  r->magnitude = -1;
284  return 0;
285  }
286 }
287 
288 static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a);
289 SECP256K1_INLINE static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) {
291  VERIFY_CHECK(a->normalized);
292 
294 }
295 
296 static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m);
299  VERIFY_CHECK(m >= 0 && m <= 31);
301 
303  r->magnitude = m + 1;
304  r->normalized = 0;
305 
307 }
308 
312 
313  VERIFY_CHECK(a >= 0 && a <= 32);
314  VERIFY_CHECK(a*r->magnitude <= 32);
316  r->magnitude *= a;
317  r->normalized = 0;
318 
320 }
321 
322 static void secp256k1_fe_impl_add(secp256k1_fe *r, const secp256k1_fe *a);
326  VERIFY_CHECK(r->magnitude + a->magnitude <= 32);
327 
328  secp256k1_fe_impl_add(r, a);
329  r->magnitude += a->magnitude;
330  r->normalized = 0;
331 
333 }
334 
341  VERIFY_CHECK(r != b);
342  VERIFY_CHECK(a != b);
343 
344  secp256k1_fe_impl_mul(r, a, b);
345  r->magnitude = 1;
346  r->normalized = 0;
347 
349 }
350 
351 static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp256k1_fe *a);
355 
356  secp256k1_fe_impl_sqr(r, a);
357  r->magnitude = 1;
358  r->normalized = 0;
359 
361 }
362 
363 static void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag);
364 SECP256K1_INLINE static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
365  VERIFY_CHECK(flag == 0 || flag == 1);
368 
369  secp256k1_fe_impl_cmov(r, a, flag);
370  if (a->magnitude > r->magnitude) r->magnitude = a->magnitude;
371  if (!a->normalized) r->normalized = 0;
372 
374 }
375 
379  VERIFY_CHECK(a->normalized);
380 
382 }
383 
387  r->magnitude = 1;
388  r->normalized = 1;
389 
391 }
392 
393 static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x);
395  int input_is_zero = secp256k1_fe_normalizes_to_zero(x);
397 
398  secp256k1_fe_impl_inv(r, x);
399  r->magnitude = x->magnitude > 0;
400  r->normalized = 1;
401 
402  VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == input_is_zero);
404 }
405 
406 static void secp256k1_fe_impl_inv_var(secp256k1_fe *r, const secp256k1_fe *x);
408  int input_is_zero = secp256k1_fe_normalizes_to_zero(x);
410 
412  r->magnitude = x->magnitude > 0;
413  r->normalized = 1;
414 
415  VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == input_is_zero);
417 }
418 
419 static int secp256k1_fe_impl_is_square_var(const secp256k1_fe *x);
421  int ret;
422  secp256k1_fe tmp = *x, sqrt;
424 
427  VERIFY_CHECK(ret == secp256k1_fe_sqrt(&sqrt, &tmp));
428  return ret;
429 }
430 
431 static void secp256k1_fe_impl_get_bounds(secp256k1_fe* r, int m);
433  VERIFY_CHECK(m >= 0);
434  VERIFY_CHECK(m <= 32);
435 
437  r->magnitude = m;
438  r->normalized = (m == 0);
439 
441 }
442 
443 static void secp256k1_fe_impl_half(secp256k1_fe *r);
447 
449  r->magnitude = (r->magnitude >> 1) + 1;
450  r->normalized = 0;
451 
453 }
454 
455 #endif /* defined(VERIFY) */
456 
457 #endif /* SECP256K1_FIELD_IMPL_H */
#define VERIFY_CHECK(cond)
Definition: util.h:159
static SECP256K1_INLINE void secp256k1_fe_impl_half(secp256k1_fe *r)
#define secp256k1_fe_set_b32_mod
Definition: field.h:87
This field implementation represents the value as 10 uint32_t limbs in base 2^26. ...
Definition: field_10x26.h:14
int ret
#define secp256k1_fe_add_int
Definition: field.h:102
#define secp256k1_fe_negate_unchecked
Definition: field.h:90
static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m)
Definition: field_impl.h:150
static SECP256K1_INLINE void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag)
#define secp256k1_fe_set_b32_limit
Definition: field.h:88
static SECP256K1_INLINE void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp256k1_fe *a)
static int secp256k1_fe_impl_normalizes_to_zero_var(const secp256k1_fe *r)
#define SECP256K1_FE_VERIFY_MAGNITUDE(a, m)
Definition: field.h:348
#define secp256k1_fe_is_zero
Definition: field.h:84
#define secp256k1_fe_inv_var
Definition: field.h:99
#define secp256k1_fe_mul
Definition: field.h:93
#define secp256k1_fe_normalizes_to_zero
Definition: field.h:81
static int secp256k1_fe_impl_normalizes_to_zero(const secp256k1_fe *r)
#define secp256k1_fe_mul_int_unchecked
Definition: field.h:91
static SECP256K1_INLINE void secp256k1_fe_impl_add_int(secp256k1_fe *r, int a)
static SECP256K1_INLINE void secp256k1_fe_impl_set_int(secp256k1_fe *r, int a)
static void secp256k1_fe_impl_set_b32_mod(secp256k1_fe *r, const unsigned char *a)
static void secp256k1_fe_impl_get_bounds(secp256k1_fe *r, int m)
#define secp256k1_fe_half
Definition: field.h:101
#define secp256k1_fe_is_square_var
Definition: field.h:103
#define secp256k1_fe_sqr
Definition: field.h:94
static void secp256k1_fe_impl_normalize(secp256k1_fe *r)
#define secp256k1_fe_normalize_weak
Definition: field.h:79
static SECP256K1_INLINE int secp256k1_fe_impl_is_zero(const secp256k1_fe *a)
#define secp256k1_fe_add
Definition: field.h:92
static SECP256K1_INLINE int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b)
Definition: field_impl.h:25
static void secp256k1_fe_impl_normalize_weak(secp256k1_fe *r)
static void secp256k1_fe_impl_inv_var(secp256k1_fe *r, const secp256k1_fe *x)
static SECP256K1_INLINE void secp256k1_fe_impl_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a)
static int secp256k1_fe_impl_is_square_var(const secp256k1_fe *x)
#define secp256k1_fe_cmov
Definition: field.h:95
#define SECP256K1_INLINE
Definition: util.h:54
static int secp256k1_fe_impl_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b)
static SECP256K1_INLINE void secp256k1_fe_impl_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe *SECP256K1_RESTRICT b)
#define secp256k1_fe_normalizes_to_zero_var
Definition: field.h:82
static void secp256k1_fe_impl_normalize_var(secp256k1_fe *r)
static int secp256k1_fe_sqrt(secp256k1_fe *SECP256K1_RESTRICT r, const secp256k1_fe *SECP256K1_RESTRICT a)
Definition: field_impl.h:37
static SECP256K1_INLINE int secp256k1_fe_impl_is_odd(const secp256k1_fe *a)
#define secp256k1_fe_inv
Definition: field.h:98
#define SECP256K1_RESTRICT
Definition: util.h:194
#define secp256k1_fe_is_odd
Definition: field.h:85
static SECP256K1_INLINE void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m)
#define SECP256K1_FE_VERIFY(a)
Definition: field.h:344
#define secp256k1_fe_get_bounds
Definition: field.h:100
#define secp256k1_fe_set_int
Definition: field.h:83
static void secp256k1_fe_impl_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a)
static SECP256K1_INLINE void secp256k1_fe_clear(secp256k1_fe *a)
Definition: field_impl.h:21
#define secp256k1_fe_to_storage
Definition: field.h:96
static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a)
Convert a field element to a 32-byte big endian value.
static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x)
#define secp256k1_fe_normalize
Definition: field.h:78
#define secp256k1_fe_normalize_var
Definition: field.h:80
#define secp256k1_fe_negate(r, a, m)
Negate a field element.
Definition: field.h:211
static SECP256K1_INLINE void secp256k1_fe_impl_add(secp256k1_fe *r, const secp256k1_fe *a)
#define secp256k1_fe_get_b32
Definition: field.h:89
static SECP256K1_INLINE void secp256k1_memclear(void *ptr, size_t len)
Definition: util.h:223
static void secp256k1_fe_verify(const secp256k1_fe *a)
Definition: field_impl.h:149
#define secp256k1_fe_cmp_var
Definition: field.h:86
static SECP256K1_INLINE void secp256k1_fe_impl_mul_int_unchecked(secp256k1_fe *r, int a)
static int secp256k1_fe_impl_set_b32_limit(secp256k1_fe *r, const unsigned char *a)
#define secp256k1_fe_from_storage
Definition: field.h:97