Bitcoin Core 28.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
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
149static void secp256k1_fe_verify(const secp256k1_fe *a) { (void)a; }
150static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m) { (void)a; (void)m; }
151#else
152static void secp256k1_fe_impl_verify(const secp256k1_fe *a);
153static 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
164static 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
216static void secp256k1_fe_impl_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
227static void secp256k1_fe_impl_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
239static int secp256k1_fe_impl_is_zero(const secp256k1_fe *a);
242 VERIFY_CHECK(a->normalized);
243
245}
246
247static 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
255static int secp256k1_fe_impl_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b);
256SECP256K1_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
265static void secp256k1_fe_impl_set_b32_mod(secp256k1_fe *r, const unsigned char *a);
266SECP256K1_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
274static int secp256k1_fe_impl_set_b32_limit(secp256k1_fe *r, const unsigned char *a);
275SECP256K1_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
288static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a);
289SECP256K1_INLINE static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) {
291 VERIFY_CHECK(a->normalized);
292
294}
295
296static 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
322static void secp256k1_fe_impl_add(secp256k1_fe *r, const secp256k1_fe *a);
326 VERIFY_CHECK(r->magnitude + a->magnitude <= 32);
327
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
351static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp256k1_fe *a);
355
357 r->magnitude = 1;
358 r->normalized = 0;
359
361}
362
363static void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag);
364SECP256K1_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
393static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x);
395 int input_is_zero = secp256k1_fe_normalizes_to_zero(x);
397
399 r->magnitude = x->magnitude > 0;
400 r->normalized = 1;
401
404}
405
406static 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
417}
418
421 int ret;
422 secp256k1_fe tmp = *x, sqrt;
424
427 VERIFY_CHECK(ret == secp256k1_fe_sqrt(&sqrt, &tmp));
428 return ret;
429}
430
431static 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
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 */
int ret
#define secp256k1_fe_cmov
Definition: field.h:95
#define secp256k1_fe_negate(r, a, m)
Negate a field element.
Definition: field.h:211
#define secp256k1_fe_normalizes_to_zero_var
Definition: field.h:82
#define secp256k1_fe_cmp_var
Definition: field.h:86
#define secp256k1_fe_normalize_weak
Definition: field.h:79
#define secp256k1_fe_is_odd
Definition: field.h:85
#define SECP256K1_FE_VERIFY_MAGNITUDE(a, m)
Definition: field.h:348
#define secp256k1_fe_mul
Definition: field.h:93
#define secp256k1_fe_add
Definition: field.h:92
#define secp256k1_fe_normalize_var
Definition: field.h:80
#define secp256k1_fe_half
Definition: field.h:101
#define secp256k1_fe_to_storage
Definition: field.h:96
#define secp256k1_fe_inv_var
Definition: field.h:99
#define secp256k1_fe_is_zero
Definition: field.h:84
#define secp256k1_fe_mul_int_unchecked
Definition: field.h:91
#define secp256k1_fe_set_b32_limit
Definition: field.h:88
#define SECP256K1_FE_VERIFY(a)
Definition: field.h:344
#define secp256k1_fe_is_square_var
Definition: field.h:103
#define secp256k1_fe_get_bounds
Definition: field.h:100
#define secp256k1_fe_from_storage
Definition: field.h:97
#define secp256k1_fe_set_b32_mod
Definition: field.h:87
#define secp256k1_fe_negate_unchecked
Definition: field.h:90
#define secp256k1_fe_get_b32
Definition: field.h:89
#define secp256k1_fe_normalizes_to_zero
Definition: field.h:81
#define secp256k1_fe_inv
Definition: field.h:98
#define secp256k1_fe_sqr
Definition: field.h:94
#define secp256k1_fe_normalize
Definition: field.h:78
#define secp256k1_fe_add_int
Definition: field.h:102
#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_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:150
static void secp256k1_fe_verify(const secp256k1_fe *a)
Definition: field_impl.h:149
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_equal(const secp256k1_fe *a, const secp256k1_fe *b)
Definition: field_impl.h:25
static SECP256K1_INLINE void secp256k1_fe_clear(secp256k1_fe *a)
Definition: field_impl.h:21
#define SECP256K1_INLINE
Definition: util.h:54
static SECP256K1_INLINE void secp256k1_memclear(void *ptr, size_t len)
Definition: util.h:223
#define VERIFY_CHECK(cond)
Definition: util.h:159
#define SECP256K1_RESTRICT
Definition: util.h:194
This field implementation represents the value as 10 uint32_t limbs in base 2^26.
Definition: field_10x26.h:14