Bitcoin Core  27.99.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_fe na;
27 
28  secp256k1_fe_negate(&na, a, 1);
29  secp256k1_fe_add(&na, b);
31 }
32 
43  secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1;
44  int j, ret;
45 
46  VERIFY_CHECK(r != a);
49 
55  secp256k1_fe_sqr(&x2, a);
56  secp256k1_fe_mul(&x2, &x2, a);
57 
58  secp256k1_fe_sqr(&x3, &x2);
59  secp256k1_fe_mul(&x3, &x3, a);
60 
61  x6 = x3;
62  for (j=0; j<3; j++) {
63  secp256k1_fe_sqr(&x6, &x6);
64  }
65  secp256k1_fe_mul(&x6, &x6, &x3);
66 
67  x9 = x6;
68  for (j=0; j<3; j++) {
69  secp256k1_fe_sqr(&x9, &x9);
70  }
71  secp256k1_fe_mul(&x9, &x9, &x3);
72 
73  x11 = x9;
74  for (j=0; j<2; j++) {
75  secp256k1_fe_sqr(&x11, &x11);
76  }
77  secp256k1_fe_mul(&x11, &x11, &x2);
78 
79  x22 = x11;
80  for (j=0; j<11; j++) {
81  secp256k1_fe_sqr(&x22, &x22);
82  }
83  secp256k1_fe_mul(&x22, &x22, &x11);
84 
85  x44 = x22;
86  for (j=0; j<22; j++) {
87  secp256k1_fe_sqr(&x44, &x44);
88  }
89  secp256k1_fe_mul(&x44, &x44, &x22);
90 
91  x88 = x44;
92  for (j=0; j<44; j++) {
93  secp256k1_fe_sqr(&x88, &x88);
94  }
95  secp256k1_fe_mul(&x88, &x88, &x44);
96 
97  x176 = x88;
98  for (j=0; j<88; j++) {
99  secp256k1_fe_sqr(&x176, &x176);
100  }
101  secp256k1_fe_mul(&x176, &x176, &x88);
102 
103  x220 = x176;
104  for (j=0; j<44; j++) {
105  secp256k1_fe_sqr(&x220, &x220);
106  }
107  secp256k1_fe_mul(&x220, &x220, &x44);
108 
109  x223 = x220;
110  for (j=0; j<3; j++) {
111  secp256k1_fe_sqr(&x223, &x223);
112  }
113  secp256k1_fe_mul(&x223, &x223, &x3);
114 
115  /* The final result is then assembled using a sliding window over the blocks. */
116 
117  t1 = x223;
118  for (j=0; j<23; j++) {
119  secp256k1_fe_sqr(&t1, &t1);
120  }
121  secp256k1_fe_mul(&t1, &t1, &x22);
122  for (j=0; j<6; j++) {
123  secp256k1_fe_sqr(&t1, &t1);
124  }
125  secp256k1_fe_mul(&t1, &t1, &x2);
126  secp256k1_fe_sqr(&t1, &t1);
127  secp256k1_fe_sqr(r, &t1);
128 
129  /* Check that a square root was actually calculated */
130 
131  secp256k1_fe_sqr(&t1, r);
132  ret = secp256k1_fe_equal(&t1, a);
133 
134 #ifdef VERIFY
135  if (!ret) {
136  secp256k1_fe_negate(&t1, &t1, 1);
139  }
140 #endif
141  return ret;
142 }
143 
144 #ifndef VERIFY
145 static void secp256k1_fe_verify(const secp256k1_fe *a) { (void)a; }
146 static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m) { (void)a; (void)m; }
147 #else
148 static void secp256k1_fe_impl_verify(const secp256k1_fe *a);
149 static void secp256k1_fe_verify(const secp256k1_fe *a) {
150  /* Magnitude between 0 and 32. */
152  /* Normalized is 0 or 1. */
153  VERIFY_CHECK((a->normalized == 0) || (a->normalized == 1));
154  /* If normalized, magnitude must be 0 or 1. */
155  if (a->normalized) SECP256K1_FE_VERIFY_MAGNITUDE(a, 1);
156  /* Invoke implementation-specific checks. */
157  secp256k1_fe_impl_verify(a);
158 }
159 
160 static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m) {
161  VERIFY_CHECK(m >= 0);
162  VERIFY_CHECK(m <= 32);
163  VERIFY_CHECK(a->magnitude <= m);
164 }
165 
169 
171  r->magnitude = 1;
172  r->normalized = 1;
173 
175 }
176 
180 
182  r->magnitude = 1;
183 
185 }
186 
190 
192  r->magnitude = 1;
193  r->normalized = 1;
194 
196 }
197 
201 
203 }
204 
208 
210 }
211 
212 static void secp256k1_fe_impl_set_int(secp256k1_fe *r, int a);
213 SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) {
214  VERIFY_CHECK(0 <= a && a <= 0x7FFF);
215 
217  r->magnitude = (a != 0);
218  r->normalized = 1;
219 
221 }
222 
223 static void secp256k1_fe_impl_add_int(secp256k1_fe *r, int a);
224 SECP256K1_INLINE static void secp256k1_fe_add_int(secp256k1_fe *r, int a) {
225  VERIFY_CHECK(0 <= a && a <= 0x7FFF);
227 
229  r->magnitude += 1;
230  r->normalized = 0;
231 
233 }
234 
235 static void secp256k1_fe_impl_clear(secp256k1_fe *a);
237  a->magnitude = 0;
238  a->normalized = 1;
240 
242 }
243 
244 static int secp256k1_fe_impl_is_zero(const secp256k1_fe *a);
247  VERIFY_CHECK(a->normalized);
248 
249  return secp256k1_fe_impl_is_zero(a);
250 }
251 
252 static int secp256k1_fe_impl_is_odd(const secp256k1_fe *a);
255  VERIFY_CHECK(a->normalized);
256 
257  return secp256k1_fe_impl_is_odd(a);
258 }
259 
260 static int secp256k1_fe_impl_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b);
261 SECP256K1_INLINE static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) {
264  VERIFY_CHECK(a->normalized);
265  VERIFY_CHECK(b->normalized);
266 
267  return secp256k1_fe_impl_cmp_var(a, b);
268 }
269 
270 static void secp256k1_fe_impl_set_b32_mod(secp256k1_fe *r, const unsigned char *a);
271 SECP256K1_INLINE static void secp256k1_fe_set_b32_mod(secp256k1_fe *r, const unsigned char *a) {
273  r->magnitude = 1;
274  r->normalized = 0;
275 
277 }
278 
279 static int secp256k1_fe_impl_set_b32_limit(secp256k1_fe *r, const unsigned char *a);
280 SECP256K1_INLINE static int secp256k1_fe_set_b32_limit(secp256k1_fe *r, const unsigned char *a) {
282  r->magnitude = 1;
283  r->normalized = 1;
285  return 1;
286  } else {
287  /* Mark the output field element as invalid. */
288  r->magnitude = -1;
289  return 0;
290  }
291 }
292 
293 static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a);
294 SECP256K1_INLINE static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) {
296  VERIFY_CHECK(a->normalized);
297 
299 }
300 
301 static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m);
304  VERIFY_CHECK(m >= 0 && m <= 31);
306 
308  r->magnitude = m + 1;
309  r->normalized = 0;
310 
312 }
313 
317 
318  VERIFY_CHECK(a >= 0 && a <= 32);
319  VERIFY_CHECK(a*r->magnitude <= 32);
321  r->magnitude *= a;
322  r->normalized = 0;
323 
325 }
326 
327 static void secp256k1_fe_impl_add(secp256k1_fe *r, const secp256k1_fe *a);
331  VERIFY_CHECK(r->magnitude + a->magnitude <= 32);
332 
333  secp256k1_fe_impl_add(r, a);
334  r->magnitude += a->magnitude;
335  r->normalized = 0;
336 
338 }
339 
346  VERIFY_CHECK(r != b);
347  VERIFY_CHECK(a != b);
348 
349  secp256k1_fe_impl_mul(r, a, b);
350  r->magnitude = 1;
351  r->normalized = 0;
352 
354 }
355 
356 static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp256k1_fe *a);
360 
361  secp256k1_fe_impl_sqr(r, a);
362  r->magnitude = 1;
363  r->normalized = 0;
364 
366 }
367 
368 static void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag);
369 SECP256K1_INLINE static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
370  VERIFY_CHECK(flag == 0 || flag == 1);
373 
374  secp256k1_fe_impl_cmov(r, a, flag);
375  if (a->magnitude > r->magnitude) r->magnitude = a->magnitude;
376  if (!a->normalized) r->normalized = 0;
377 
379 }
380 
384  VERIFY_CHECK(a->normalized);
385 
387 }
388 
392  r->magnitude = 1;
393  r->normalized = 1;
394 
396 }
397 
398 static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x);
400  int input_is_zero = secp256k1_fe_normalizes_to_zero(x);
402 
403  secp256k1_fe_impl_inv(r, x);
404  r->magnitude = x->magnitude > 0;
405  r->normalized = 1;
406 
407  VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == input_is_zero);
409 }
410 
411 static void secp256k1_fe_impl_inv_var(secp256k1_fe *r, const secp256k1_fe *x);
413  int input_is_zero = secp256k1_fe_normalizes_to_zero(x);
415 
417  r->magnitude = x->magnitude > 0;
418  r->normalized = 1;
419 
420  VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == input_is_zero);
422 }
423 
424 static int secp256k1_fe_impl_is_square_var(const secp256k1_fe *x);
426  int ret;
427  secp256k1_fe tmp = *x, sqrt;
429 
432  VERIFY_CHECK(ret == secp256k1_fe_sqrt(&sqrt, &tmp));
433  return ret;
434 }
435 
436 static void secp256k1_fe_impl_get_bounds(secp256k1_fe* r, int m);
438  VERIFY_CHECK(m >= 0);
439  VERIFY_CHECK(m <= 32);
440 
442  r->magnitude = m;
443  r->normalized = (m == 0);
444 
446 }
447 
448 static void secp256k1_fe_impl_half(secp256k1_fe *r);
452 
454  r->magnitude = (r->magnitude >> 1) + 1;
455  r->normalized = 0;
456 
458 }
459 
460 #endif /* defined(VERIFY) */
461 
462 #endif /* SECP256K1_FIELD_IMPL_H */
int ret
#define secp256k1_fe_cmov
Definition: field.h:96
#define secp256k1_fe_negate(r, a, m)
Negate a field element.
Definition: field.h:216
#define secp256k1_fe_normalizes_to_zero_var
Definition: field.h:82
#define secp256k1_fe_cmp_var
Definition: field.h:87
#define secp256k1_fe_normalize_weak
Definition: field.h:79
#define secp256k1_fe_is_odd
Definition: field.h:86
#define SECP256K1_FE_VERIFY_MAGNITUDE(a, m)
Definition: field.h:353
#define secp256k1_fe_mul
Definition: field.h:94
#define secp256k1_fe_add
Definition: field.h:93
#define secp256k1_fe_clear
Definition: field.h:84
#define secp256k1_fe_normalize_var
Definition: field.h:80
#define secp256k1_fe_half
Definition: field.h:102
#define secp256k1_fe_to_storage
Definition: field.h:97
#define secp256k1_fe_inv_var
Definition: field.h:100
#define secp256k1_fe_is_zero
Definition: field.h:85
#define secp256k1_fe_mul_int_unchecked
Definition: field.h:92
#define secp256k1_fe_set_b32_limit
Definition: field.h:89
#define SECP256K1_FE_VERIFY(a)
Definition: field.h:349
#define secp256k1_fe_is_square_var
Definition: field.h:104
#define secp256k1_fe_get_bounds
Definition: field.h:101
#define secp256k1_fe_from_storage
Definition: field.h:98
#define secp256k1_fe_set_b32_mod
Definition: field.h:88
#define secp256k1_fe_negate_unchecked
Definition: field.h:91
#define secp256k1_fe_get_b32
Definition: field.h:90
#define secp256k1_fe_normalizes_to_zero
Definition: field.h:81
#define secp256k1_fe_inv
Definition: field.h:99
#define secp256k1_fe_sqr
Definition: field.h:95
#define secp256k1_fe_normalize
Definition: field.h:78
#define secp256k1_fe_add_int
Definition: field.h:103
#define secp256k1_fe_set_int
Definition: field.h:83
static SECP256K1_INLINE void secp256k1_fe_impl_half(secp256k1_fe *r)
static void secp256k1_fe_impl_set_b32_mod(secp256k1_fe *r, const unsigned char *a)
static void secp256k1_fe_impl_normalize_weak(secp256k1_fe *r)
static int secp256k1_fe_impl_is_square_var(const secp256k1_fe *x)
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 SECP256K1_INLINE void secp256k1_fe_impl_add(secp256k1_fe *r, const secp256k1_fe *a)
static SECP256K1_INLINE void secp256k1_fe_impl_clear(secp256k1_fe *a)
static SECP256K1_INLINE void secp256k1_fe_impl_set_int(secp256k1_fe *r, int a)
static SECP256K1_INLINE int secp256k1_fe_impl_is_zero(const secp256k1_fe *a)
static void secp256k1_fe_impl_get_bounds(secp256k1_fe *r, int m)
static int secp256k1_fe_impl_set_b32_limit(secp256k1_fe *r, const unsigned char *a)
static SECP256K1_INLINE void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m)
static SECP256K1_INLINE void secp256k1_fe_impl_mul_int_unchecked(secp256k1_fe *r, int a)
static int secp256k1_fe_impl_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b)
static int secp256k1_fe_impl_normalizes_to_zero(const secp256k1_fe *r)
static void secp256k1_fe_impl_inv_var(secp256k1_fe *r, const secp256k1_fe *x)
static SECP256K1_INLINE void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp256k1_fe *a)
static SECP256K1_INLINE void secp256k1_fe_impl_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a)
static void secp256k1_fe_impl_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a)
static SECP256K1_INLINE void secp256k1_fe_impl_add_int(secp256k1_fe *r, int a)
static int secp256k1_fe_impl_normalizes_to_zero_var(const secp256k1_fe *r)
static void secp256k1_fe_impl_normalize(secp256k1_fe *r)
static SECP256K1_INLINE void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag)
static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x)
static void secp256k1_fe_impl_normalize_var(secp256k1_fe *r)
static SECP256K1_INLINE int secp256k1_fe_impl_is_odd(const secp256k1_fe *a)
static SECP256K1_INLINE void secp256k1_fe_impl_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe *SECP256K1_RESTRICT b)
static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m)
Definition: field_impl.h:146
static void secp256k1_fe_verify(const secp256k1_fe *a)
Definition: field_impl.h:145
static int secp256k1_fe_sqrt(secp256k1_fe *SECP256K1_RESTRICT r, const secp256k1_fe *SECP256K1_RESTRICT a)
Definition: field_impl.h:33
static SECP256K1_INLINE int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b)
Definition: field_impl.h:21
#define SECP256K1_INLINE
Definition: util.h:48
#define VERIFY_CHECK(cond)
Definition: util.h:153
#define SECP256K1_RESTRICT
Definition: util.h:185
This field implementation represents the value as 10 uint32_t limbs in base 2^26.
Definition: field_10x26.h:14