Bitcoin Core 28.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
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
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
145static void secp256k1_fe_verify(const secp256k1_fe *a) { (void)a; }
146static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m) { (void)a; (void)m; }
147#else
148static void secp256k1_fe_impl_verify(const secp256k1_fe *a);
149static 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
160static 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
212static void secp256k1_fe_impl_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
223static void secp256k1_fe_impl_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
237 a->magnitude = 0;
238 a->normalized = 1;
240
242}
243
244static int secp256k1_fe_impl_is_zero(const secp256k1_fe *a);
247 VERIFY_CHECK(a->normalized);
248
250}
251
252static 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
260static int secp256k1_fe_impl_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b);
261SECP256K1_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
270static void secp256k1_fe_impl_set_b32_mod(secp256k1_fe *r, const unsigned char *a);
271SECP256K1_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
279static int secp256k1_fe_impl_set_b32_limit(secp256k1_fe *r, const unsigned char *a);
280SECP256K1_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
293static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a);
294SECP256K1_INLINE static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) {
296 VERIFY_CHECK(a->normalized);
297
299}
300
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
327static void secp256k1_fe_impl_add(secp256k1_fe *r, const secp256k1_fe *a);
331 VERIFY_CHECK(r->magnitude + a->magnitude <= 32);
332
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
356static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp256k1_fe *a);
360
362 r->magnitude = 1;
363 r->normalized = 0;
364
366}
367
368static void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag);
369SECP256K1_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
398static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x);
400 int input_is_zero = secp256k1_fe_normalizes_to_zero(x);
402
404 r->magnitude = x->magnitude > 0;
405 r->normalized = 1;
406
409}
410
411static 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
422}
423
426 int ret;
427 secp256k1_fe tmp = *x, sqrt;
429
432 VERIFY_CHECK(ret == secp256k1_fe_sqrt(&sqrt, &tmp));
433 return ret;
434}
435
436static 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
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:188
This field implementation represents the value as 10 uint32_t limbs in base 2^26.
Definition field_10x26.h:14