Bitcoin Core 31.99.0
P2P Digital Currency
scalar_low_impl.h
Go to the documentation of this file.
1/***********************************************************************
2 * Copyright (c) 2015 Andrew Poelstra *
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_SCALAR_REPR_IMPL_H
8#define SECP256K1_SCALAR_REPR_IMPL_H
9
10#include "checkmem.h"
11#include "scalar.h"
12#include "util.h"
13
14#include <string.h>
15
18
19 return !(*a & 1);
20}
21
23 *r = v % EXHAUSTIVE_TEST_ORDER;
24
26}
27
28SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
30 VERIFY_CHECK(count > 0 && count <= 32);
31 VERIFY_CHECK(offset <= 256 - count);
32 VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5);
33
34 if (offset < 32) {
35 return (*a >> offset) & (0xFFFFFFFF >> (32 - count));
36 } else {
37 return 0;
38 }
39}
40
41SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
43 VERIFY_CHECK(count > 0 && count <= 32);
44 VERIFY_CHECK(offset <= 256 - count);
45
46 if (offset < 32) {
47 return (*a >> offset) & (0xFFFFFFFF >> (32 - count));
48 } else {
49 return 0;
50 }
51}
52
54
58
59 *r = (*a + *b) % EXHAUSTIVE_TEST_ORDER;
60
62 return *r < *b;
63}
64
65static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) {
67 VERIFY_CHECK(flag == 0 || flag == 1);
68
69 if (flag && bit < 32)
70 *r += ((uint32_t)1 << bit);
71
73 VERIFY_CHECK(bit < 32);
74 /* Verify that adding (1 << bit) will not overflow any in-range scalar *r by overflowing the underlying uint32_t. */
75 VERIFY_CHECK(((uint32_t)1 << bit) - 1 <= UINT32_MAX - EXHAUSTIVE_TEST_ORDER);
76}
77
78static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) {
79 int i;
80 int over = 0;
81 *r = 0;
82 for (i = 0; i < 32; i++) {
83 *r = (*r * 0x100) + b32[i];
84 if (*r >= EXHAUSTIVE_TEST_ORDER) {
85 over = 1;
87 }
88 }
89 if (overflow) *overflow = over;
90
92}
93
94static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) {
96
97 memset(bin, 0, 32);
98 bin[28] = *a >> 24; bin[29] = *a >> 16; bin[30] = *a >> 8; bin[31] = *a;
99}
100
103
104 return *a == 0;
105}
106
109
110 if (*a == 0) {
111 *r = 0;
112 } else {
113 *r = EXHAUSTIVE_TEST_ORDER - *a;
114 }
115
117}
118
121
122 return *a == 1;
123}
124
127
128 return *a > EXHAUSTIVE_TEST_ORDER / 2;
129}
130
133 VERIFY_CHECK(flag == 0 || flag == 1);
134
135 if (flag) secp256k1_scalar_negate(r, r);
136
138 return flag ? -1 : 1;
139}
140
144
145 *r = (*a * *b) % EXHAUSTIVE_TEST_ORDER;
146
148}
149
152
153 *r1 = *a;
154 *r2 = 0;
155
158}
159
163
164 return *a == *b;
165}
166
168 uint32_t mask0, mask1;
169 volatile int vflag = flag;
170 VERIFY_CHECK(flag == 0 || flag == 1);
172 SECP256K1_CHECKMEM_CHECK_VERIFY(r, sizeof(*r));
173
174 mask0 = vflag + ~((uint32_t)0);
175 mask1 = ~mask0;
176 *r = (*r & mask0) | (*a & mask1);
177
179}
180
182 int i;
183 uint32_t res = 0;
185
186 for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) {
187 if ((i * *x) % EXHAUSTIVE_TEST_ORDER == 1) {
188 res = i;
189 break;
190 }
191 }
192
193 /* If this VERIFY_CHECK triggers we were given a noninvertible scalar (and thus
194 * have a composite group order; fix it in exhaustive_tests.c). */
195 VERIFY_CHECK(res != 0);
196 *r = res;
197
199}
200
203
205
207}
208
211
212 *r = (*a + ((-(uint32_t)(*a & 1)) & EXHAUSTIVE_TEST_ORDER)) >> 1;
213
215}
216
217#endif /* SECP256K1_SCALAR_REPR_IMPL_H */
#define SECP256K1_CHECKMEM_CHECK_VERIFY(p, len)
Definition: checkmem.h:114
#define SECP256K1_SCALAR_VERIFY(r)
Definition: scalar.h:103
static SECP256K1_INLINE int secp256k1_scalar_is_even(const secp256k1_scalar *a)
static SECP256K1_INLINE int secp256k1_scalar_check_overflow(const secp256k1_scalar *a)
static void secp256k1_scalar_half(secp256k1_scalar *r, const secp256k1_scalar *a)
static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow)
static SECP256K1_INLINE uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count)
static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x)
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar *a)
static SECP256K1_INLINE void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v)
static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x)
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag)
static SECP256K1_INLINE int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b)
static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b)
static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag)
static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b)
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a)
static SECP256K1_INLINE int secp256k1_scalar_is_zero(const secp256k1_scalar *a)
static int secp256k1_scalar_is_high(const secp256k1_scalar *a)
static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a)
static SECP256K1_INLINE uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count)
static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag)
static SECP256K1_INLINE int secp256k1_scalar_is_one(const secp256k1_scalar *a)
#define SECP256K1_INLINE
Definition: util.h:53
#define VERIFY_CHECK(cond)
Definition: util.h:169
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
static int count
#define EXHAUSTIVE_TEST_ORDER