Bitcoin ABC 0.33.3
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;
23#ifdef VERIFY
26 VERIFY_CHECK(a->magnitude <= 1);
27 VERIFY_CHECK(b->magnitude <= 31);
28#endif
29 secp256k1_fe_negate(&na, a, 1);
30 secp256k1_fe_add(&na, b);
32}
33
35 secp256k1_fe na;
36#ifdef VERIFY
39 VERIFY_CHECK(a->magnitude <= 1);
40 VERIFY_CHECK(b->magnitude <= 31);
41#endif
42 secp256k1_fe_negate(&na, a, 1);
43 secp256k1_fe_add(&na, b);
45}
46
57 secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1;
58 int j, ret;
59
60#ifdef VERIFY
61 VERIFY_CHECK(r != a);
63 VERIFY_CHECK(a->magnitude <= 8);
64#endif
65
71 secp256k1_fe_sqr(&x2, a);
72 secp256k1_fe_mul(&x2, &x2, a);
73
74 secp256k1_fe_sqr(&x3, &x2);
75 secp256k1_fe_mul(&x3, &x3, a);
76
77 x6 = x3;
78 for (j=0; j<3; j++) {
79 secp256k1_fe_sqr(&x6, &x6);
80 }
81 secp256k1_fe_mul(&x6, &x6, &x3);
82
83 x9 = x6;
84 for (j=0; j<3; j++) {
85 secp256k1_fe_sqr(&x9, &x9);
86 }
87 secp256k1_fe_mul(&x9, &x9, &x3);
88
89 x11 = x9;
90 for (j=0; j<2; j++) {
91 secp256k1_fe_sqr(&x11, &x11);
92 }
93 secp256k1_fe_mul(&x11, &x11, &x2);
94
95 x22 = x11;
96 for (j=0; j<11; j++) {
97 secp256k1_fe_sqr(&x22, &x22);
98 }
99 secp256k1_fe_mul(&x22, &x22, &x11);
100
101 x44 = x22;
102 for (j=0; j<22; j++) {
103 secp256k1_fe_sqr(&x44, &x44);
104 }
105 secp256k1_fe_mul(&x44, &x44, &x22);
106
107 x88 = x44;
108 for (j=0; j<44; j++) {
109 secp256k1_fe_sqr(&x88, &x88);
110 }
111 secp256k1_fe_mul(&x88, &x88, &x44);
112
113 x176 = x88;
114 for (j=0; j<88; j++) {
115 secp256k1_fe_sqr(&x176, &x176);
116 }
117 secp256k1_fe_mul(&x176, &x176, &x88);
118
119 x220 = x176;
120 for (j=0; j<44; j++) {
121 secp256k1_fe_sqr(&x220, &x220);
122 }
123 secp256k1_fe_mul(&x220, &x220, &x44);
124
125 x223 = x220;
126 for (j=0; j<3; j++) {
127 secp256k1_fe_sqr(&x223, &x223);
128 }
129 secp256k1_fe_mul(&x223, &x223, &x3);
130
131 /* The final result is then assembled using a sliding window over the blocks. */
132
133 t1 = x223;
134 for (j=0; j<23; j++) {
135 secp256k1_fe_sqr(&t1, &t1);
136 }
137 secp256k1_fe_mul(&t1, &t1, &x22);
138 for (j=0; j<6; j++) {
139 secp256k1_fe_sqr(&t1, &t1);
140 }
141 secp256k1_fe_mul(&t1, &t1, &x2);
142 secp256k1_fe_sqr(&t1, &t1);
143 secp256k1_fe_sqr(r, &t1);
144
145 /* Check that a square root was actually calculated */
146
147 secp256k1_fe_sqr(&t1, r);
148 ret = secp256k1_fe_equal(&t1, a);
149
150#ifdef VERIFY
151 if (!ret) {
152 secp256k1_fe_negate(&t1, &t1, 1);
155 }
156#endif
157 return ret;
158}
159
161 secp256k1_fe r;
162 return secp256k1_fe_sqrt(&r, a);
163}
164
165#ifndef VERIFY
166static void secp256k1_fe_verify(const secp256k1_fe *a) { (void)a; }
167#else
168static void secp256k1_fe_verify(const secp256k1_fe *a) {
169 /* Magnitude between 0 and 32. */
170 VERIFY_CHECK((a->magnitude >= 0) && (a->magnitude <= 32));
171 /* Normalized is 0 or 1. */
172 VERIFY_CHECK((a->normalized == 0) || (a->normalized == 1));
173 /* If normalized, magnitude must be 0 or 1. */
174 if (a->normalized) VERIFY_CHECK(a->magnitude <= 1);
175 /* Invoke implementation-specific checks. */
176 secp256k1_fe_impl_verify(a);
177}
178
182 r->magnitude = 1;
183 r->normalized = 1;
185}
186
190 r->magnitude = 1;
192}
193
197 r->magnitude = 1;
198 r->normalized = 1;
200}
201
205}
206
210}
211
213 VERIFY_CHECK(0 <= a && a <= 0x7FFF);
215 r->magnitude = (a != 0);
216 r->normalized = 1;
218}
219
221 VERIFY_CHECK(0 <= a && a <= 0x7FFF);
224 r->magnitude += 1;
225 r->normalized = 0;
227}
228
230 a->magnitude = 0;
231 a->normalized = 1;
234}
235
238 VERIFY_CHECK(a->normalized);
240}
241
244 VERIFY_CHECK(a->normalized);
245 return secp256k1_fe_impl_is_odd(a);
246}
247
248SECP256K1_INLINE static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) {
251 VERIFY_CHECK(a->normalized);
252 VERIFY_CHECK(b->normalized);
253 return secp256k1_fe_impl_cmp_var(a, b);
254}
255
256SECP256K1_INLINE static void secp256k1_fe_set_b32_mod(secp256k1_fe *r, const unsigned char *a) {
258 r->magnitude = 1;
259 r->normalized = 0;
261}
262
263SECP256K1_INLINE static int secp256k1_fe_set_b32_limit(secp256k1_fe *r, const unsigned char *a) {
265 r->magnitude = 1;
266 r->normalized = 1;
268 return 1;
269 } else {
270 /* Mark the output field element as invalid. */
271 r->magnitude = -1;
272 return 0;
273 }
274}
275
276SECP256K1_INLINE static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) {
278 VERIFY_CHECK(a->normalized);
280}
281
282SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) {
284 VERIFY_CHECK(m >= 0 && m <= 31);
285 VERIFY_CHECK(a->magnitude <= m);
287 r->magnitude = m + 1;
288 r->normalized = 0;
290}
291
294 VERIFY_CHECK(a >= 0 && a <= 32);
295 VERIFY_CHECK(a*r->magnitude <= 32);
297 r->magnitude *= a;
298 r->normalized = 0;
300}
301
305 VERIFY_CHECK(r->magnitude + a->magnitude <= 32);
307 r->magnitude += a->magnitude;
308 r->normalized = 0;
310}
311
315 VERIFY_CHECK(a->magnitude <= 8);
316 VERIFY_CHECK(b->magnitude <= 8);
317 VERIFY_CHECK(r != b);
318 VERIFY_CHECK(a != b);
319 secp256k1_fe_impl_mul(r, a, b);
320 r->magnitude = 1;
321 r->normalized = 0;
323}
324
327 VERIFY_CHECK(a->magnitude <= 8);
329 r->magnitude = 1;
330 r->normalized = 0;
332}
333
334SECP256K1_INLINE static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
335 VERIFY_CHECK(flag == 0 || flag == 1);
338 secp256k1_fe_impl_cmov(r, a, flag);
339 if (a->magnitude > r->magnitude) r->magnitude = a->magnitude;
340 if (!a->normalized) r->normalized = 0;
342}
343
346 VERIFY_CHECK(a->normalized);
348}
349
352 r->magnitude = 1;
353 r->normalized = 1;
355}
356
358 int input_is_zero = secp256k1_fe_normalizes_to_zero(x);
361 r->magnitude = x->magnitude > 0;
362 r->normalized = 1;
365}
366
368 int input_is_zero = secp256k1_fe_normalizes_to_zero(x);
371 r->magnitude = x->magnitude > 0;
372 r->normalized = 1;
375}
376
378 int ret;
379 secp256k1_fe tmp = *x, sqrt;
383 VERIFY_CHECK(ret == secp256k1_fe_sqrt(&sqrt, &tmp));
384 return ret;
385}
386
388 VERIFY_CHECK(m >= 0);
389 VERIFY_CHECK(m <= 32);
391 r->magnitude = m;
392 r->normalized = (m == 0);
394}
395
398 VERIFY_CHECK(r->magnitude < 32);
400 r->magnitude = (r->magnitude >> 1) + 1;
401 r->normalized = 0;
403}
404
405#endif /* defined(VERIFY) */
406
407#endif /* SECP256K1_FIELD_IMPL_H */
#define secp256k1_fe_cmov
Definition: field.h:96
#define secp256k1_fe_normalizes_to_zero_var
Definition: field.h:82
#define secp256k1_fe_mul_int
Definition: field.h:92
#define secp256k1_fe_negate
Definition: field.h:91
#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_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_set_b32_limit
Definition: field.h:89
#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_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(secp256k1_fe *r, const secp256k1_fe *a, int m)
static SECP256K1_INLINE void secp256k1_fe_impl_mul_int(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 int secp256k1_fe_is_quad_var(const secp256k1_fe *a)
Definition: field_impl.h:160
static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a)
Definition: field_impl.h:47
static SECP256K1_INLINE int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b)
Definition: field_impl.h:34
static void secp256k1_fe_verify(const secp256k1_fe *a)
Definition: field_impl.h:166
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:130
#define SECP256K1_RESTRICT
Definition: util.h:171
This field implementation represents the value as 10 uint32_t limbs in base 2^26.
Definition: field_10x26.h:14