Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
secp256r1.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Completed, auditors: [Federico], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
8
9#include "../../fields/field.hpp"
10#include "../../groups/group.hpp"
11
12// NOLINTBEGIN(cppcoreguidelines-avoid-c-arrays)
13namespace bb::secp256r1 {
14
24struct FqParams {
25 static constexpr const char* schema_name = "secp256r1_fq";
26
27 // A little-endian representation of the modulus split into 4 64-bit words
28 static constexpr uint64_t modulus_0 = 0xFFFFFFFFFFFFFFFFULL;
29 static constexpr uint64_t modulus_1 = 0x00000000FFFFFFFFULL;
30 static constexpr uint64_t modulus_2 = 0x0000000000000000ULL;
31 static constexpr uint64_t modulus_3 = 0xFFFFFFFF00000001ULL;
32
33 // A little-endian representation of R^2 modulo the modulus (R=2^256 mod modulus) split into 4 64-bit words
34 static constexpr uint64_t r_squared_0 = 3ULL;
35 static constexpr uint64_t r_squared_1 = 18446744056529682431ULL;
36 static constexpr uint64_t r_squared_2 = 18446744073709551614ULL;
37 static constexpr uint64_t r_squared_3 = 21474836477ULL;
38
39 // -(Modulus^-1) mod 2^64
40 // This constant is used during multiplication: given an 8-limb representation of the multiplication of two field
41 // elements, for each of the lowest four limbs we compute: k_i = r_inv * limb_i and we add 2^{64 * i} * k_i * p to
42 // the result of the multiplication. In this way we zero out the lowest four limbs of the multiplication and we can
43 // divide by 2^256 by taking the highest four limbs. See field_docs.hpp for more details.
44 static constexpr uint64_t r_inv = 1;
45
46 // 2^(-64) mod Modulus
47 // Used in the reduction mechanism, see field_docs.md
48 // Instead of computing k, we multiply the lowest limb by this value and then add to the following 5 limbs.
49 // This saves us from having to compute k
50 static constexpr uint64_t r_inv_0 = 0x100000000UL;
51 static constexpr uint64_t r_inv_1 = 0x0UL;
52 static constexpr uint64_t r_inv_2 = 0xffffffff00000001UL;
53 static constexpr uint64_t r_inv_3 = 0x0UL;
54
55 // Not used for secp256r1
56 static constexpr uint64_t cube_root_0 = 0UL;
57 static constexpr uint64_t cube_root_1 = 0UL;
58 static constexpr uint64_t cube_root_2 = 0UL;
59 static constexpr uint64_t cube_root_3 = 0UL;
60
61 // Not used for secp256r1
62 static constexpr uint64_t primitive_root_0 = 0UL;
63 static constexpr uint64_t primitive_root_1 = 0UL;
64 static constexpr uint64_t primitive_root_2 = 0UL;
65 static constexpr uint64_t primitive_root_3 = 0UL;
66
67 // Coset generators in Montgomery form for R=2^256 mod Modulus. Used in FFT-based proving systems, don't really need
68 // them here
69 static constexpr uint64_t coset_generator_0 = 0x3ULL;
70 static constexpr uint64_t coset_generator_1 = 0xfffffffd00000000ULL;
71 static constexpr uint64_t coset_generator_2 = 0xffffffffffffffffULL;
72 static constexpr uint64_t coset_generator_3 = 0x2fffffffcULL;
73
74 // A little-endian representation of the modulus split into 9 29-bit limbs
75 // This is used in wasm because we can only do multiplication with 64-bit result instead of 128-bit like in x86_64
76 static constexpr uint64_t modulus_wasm_0 = 0x1fffffff;
77 static constexpr uint64_t modulus_wasm_1 = 0x1fffffff;
78 static constexpr uint64_t modulus_wasm_2 = 0x1fffffff;
79 static constexpr uint64_t modulus_wasm_3 = 0x1ff;
80 static constexpr uint64_t modulus_wasm_4 = 0x0;
81 static constexpr uint64_t modulus_wasm_5 = 0x0;
82 static constexpr uint64_t modulus_wasm_6 = 0x40000;
83 static constexpr uint64_t modulus_wasm_7 = 0x1fe00000;
84 static constexpr uint64_t modulus_wasm_8 = 0xffffff;
85
86 // A little-endian representation of R^2 modulo the modulus (R=2^261 mod modulus) split into 4 64-bit words
87 // We use 2^261 in wasm, because 261=29*9, the 9 29-bit limbs used for arithmetic
88 static constexpr uint64_t r_squared_wasm_0 = 0x0000000000000c00UL;
89 static constexpr uint64_t r_squared_wasm_1 = 0xffffeffffffffc00UL;
90 static constexpr uint64_t r_squared_wasm_2 = 0xfffffffffffffbffUL;
91 static constexpr uint64_t r_squared_wasm_3 = 0x000013fffffff7ffUL;
92
93 // 2^(-29) mod Modulus
94 // Used in the reduction mechanism, see field_docs.md
95 // Instead of computing k, we multiply the lowest limb by this value and then add to the following 10 limbs.
96 // This saves us from having to compute k
97 static constexpr uint64_t r_inv_wasm_0 = 0x0;
98 static constexpr uint64_t r_inv_wasm_1 = 0x0;
99 static constexpr uint64_t r_inv_wasm_2 = 0x200;
100 static constexpr uint64_t r_inv_wasm_3 = 0x0;
101 static constexpr uint64_t r_inv_wasm_4 = 0x0;
102 static constexpr uint64_t r_inv_wasm_5 = 0x40000;
103 static constexpr uint64_t r_inv_wasm_6 = 0x1fe00000;
104 static constexpr uint64_t r_inv_wasm_7 = 0xffffff;
105 static constexpr uint64_t r_inv_wasm_8 = 0x0;
106
107 // Not used for secp256r1
108 static constexpr uint64_t cube_root_wasm_0 = 0x0000000000000000UL;
109 static constexpr uint64_t cube_root_wasm_1 = 0x0000000000000000UL;
110 static constexpr uint64_t cube_root_wasm_2 = 0x0000000000000000UL;
111 static constexpr uint64_t cube_root_wasm_3 = 0x0000000000000000UL;
112
113 // Not used for secp256r1
114 static constexpr uint64_t primitive_root_wasm_0 = 0x0000000000000000UL;
115 static constexpr uint64_t primitive_root_wasm_1 = 0x0000000000000000UL;
116 static constexpr uint64_t primitive_root_wasm_2 = 0x0000000000000000UL;
117 static constexpr uint64_t primitive_root_wasm_3 = 0x0000000000000000UL;
118
119 // Coset generators in Montgomery form for R=2^261 mod Modulus. Used in FFT-based proving systems, don't really need
120 // them here
121 static constexpr uint64_t coset_generator_wasm_0 = 0x0000000000000060ULL;
122 static constexpr uint64_t coset_generator_wasm_1 = 0xffffffa000000000ULL;
123 static constexpr uint64_t coset_generator_wasm_2 = 0xffffffffffffffffULL;
124 static constexpr uint64_t coset_generator_wasm_3 = 0x0000005fffffff9fULL;
125
126 // For consistency with bb::fq, if we ever represent an element of bb::secp256r1::fq in the public inputs, we do so
127 // as a bigfield element, so with 4 public inputs
128 static constexpr size_t PUBLIC_INPUTS_SIZE = BIGFIELD_PUBLIC_INPUTS_SIZE;
129};
131
141struct FrParams {
142 static constexpr const char* schema_name = "secp256r1_fr";
143
144 // A little-endian representation of the modulus split into 4 64-bit words
145 static constexpr uint64_t modulus_0 = 0xF3B9CAC2FC632551ULL;
146 static constexpr uint64_t modulus_1 = 0xBCE6FAADA7179E84ULL;
147 static constexpr uint64_t modulus_2 = 0xFFFFFFFFFFFFFFFFULL;
148 static constexpr uint64_t modulus_3 = 0xFFFFFFFF00000000ULL;
149
150 // A little-endian representation of R^2 modulo the modulus (R=2^256 mod modulus) split into 4 64-bit words
151 static constexpr uint64_t r_squared_0 = 9449762124159643298ULL;
152 static constexpr uint64_t r_squared_1 = 5087230966250696614ULL;
153 static constexpr uint64_t r_squared_2 = 2901921493521525849ULL;
154 static constexpr uint64_t r_squared_3 = 7413256579398063648ULL;
155
156 // -(Modulus^-1) mod 2^64
157 // This is used to compute k = r_inv * lower_limb(scalar), such that scalar + k*modulus in integers would have 0 in
158 // the lowest limb By performing this sequentially for 4 limbs, we get an 8-limb representation of the scalar, where
159 // the lowest 4 limbs are zeros. Then we can immediately divide by 2^256 by simply getting rid of the lowest 4 limbs
160 static constexpr uint64_t r_inv = 14758798090332847183ULL;
161
162 // 2^(-64) mod Modulus
163 // Used in the reduction mechanism, see field_docs.md
164 // Instead of computing k, we multiply the lowest limb by this value and then add to the following 5 limbs.
165 // This saves us from having to compute k
166 static constexpr uint64_t r_inv_0 = 0x230102a06d6251dcUL;
167 static constexpr uint64_t r_inv_1 = 0xca5113bcafc4ea28UL;
168 static constexpr uint64_t r_inv_2 = 0xded10c5bee00bc4eUL;
169 static constexpr uint64_t r_inv_3 = 0xccd1c8aa212ef3a4UL;
170
171 // Not used for secp256r1
172 static constexpr uint64_t cube_root_0 = 0UL;
173 static constexpr uint64_t cube_root_1 = 0UL;
174 static constexpr uint64_t cube_root_2 = 0UL;
175 static constexpr uint64_t cube_root_3 = 0UL;
176
177 // Not used for secp256r1
178 static constexpr uint64_t primitive_root_0 = 0UL;
179 static constexpr uint64_t primitive_root_1 = 0UL;
180 static constexpr uint64_t primitive_root_2 = 0UL;
181 static constexpr uint64_t primitive_root_3 = 0UL;
182
183 // Coset generator in Montgomery form for R=2^256 mod Modulus. Used in FFT-based proving systems, don't really need
184 // them here
185 static constexpr uint64_t coset_generator_0 = 0x55eb74ab1949fac9ULL;
186 static constexpr uint64_t coset_generator_1 = 0xd5af25406e5aaa5dULL;
187 static constexpr uint64_t coset_generator_2 = 0x1ULL;
188 static constexpr uint64_t coset_generator_3 = 0x6fffffff9ULL;
189
190 // A little-endian representation of the modulus split into 9 29-bit limbs
191 // This is used in wasm because we can only do multiplication with 64-bit result instead of 128-bit like in x86_64
192 static constexpr uint64_t modulus_wasm_0 = 0x1c632551;
193 static constexpr uint64_t modulus_wasm_1 = 0x1dce5617;
194 static constexpr uint64_t modulus_wasm_2 = 0x5e7a13c;
195 static constexpr uint64_t modulus_wasm_3 = 0xdf55b4e;
196 static constexpr uint64_t modulus_wasm_4 = 0x1ffffbce;
197 static constexpr uint64_t modulus_wasm_5 = 0x1fffffff;
198 static constexpr uint64_t modulus_wasm_6 = 0x3ffff;
199 static constexpr uint64_t modulus_wasm_7 = 0x1fe00000;
200 static constexpr uint64_t modulus_wasm_8 = 0xffffff;
201
202 // A little-endian representation of R^2 modulo the modulus (R=2^261 mod modulus) split into 4 64-bit words
203 // We use 2^261 in wasm, because 261=29*9, the 9 29-bit limbs used for arithmetic
204 static constexpr uint64_t r_squared_wasm_0 = 0x45e9cfeeb48d9ef5UL;
205 static constexpr uint64_t r_squared_wasm_1 = 0x1f11fc5bb2d31a99UL;
206 static constexpr uint64_t r_squared_wasm_2 = 0x16c8e4adafb16586UL;
207 static constexpr uint64_t r_squared_wasm_3 = 0x84b6556a65587f06UL;
208
209 // 2^(-29) mod Modulus
210 // Used in the reduction mechanism, see field_docs.md
211 // Instead of computing k, we multiply the lowest limb by this value and then add to the following 5 limbs.
212 // This saves us from having to compute k
213 static constexpr uint64_t r_inv_wasm_0 = 0x8517c79;
214 static constexpr uint64_t r_inv_wasm_1 = 0x1edc694;
215 static constexpr uint64_t r_inv_wasm_2 = 0x459ee5c;
216 static constexpr uint64_t r_inv_wasm_3 = 0x705a6a8;
217 static constexpr uint64_t r_inv_wasm_4 = 0x1ffffe2a;
218 static constexpr uint64_t r_inv_wasm_5 = 0x113bffff;
219 static constexpr uint64_t r_inv_wasm_6 = 0x1621c017;
220 static constexpr uint64_t r_inv_wasm_7 = 0xef1ff43;
221 static constexpr uint64_t r_inv_wasm_8 = 0x7005e2;
222
223 // Not used for secp256r1
224 static constexpr uint64_t cube_root_wasm_0 = 0x0000000000000000UL;
225 static constexpr uint64_t cube_root_wasm_1 = 0x0000000000000000UL;
226 static constexpr uint64_t cube_root_wasm_2 = 0x0000000000000000UL;
227 static constexpr uint64_t cube_root_wasm_3 = 0x0000000000000000UL;
228
229 // Not used for secp256r1
230 static constexpr uint64_t primitive_root_wasm_0 = 0x0000000000000000UL;
231 static constexpr uint64_t primitive_root_wasm_1 = 0x0000000000000000UL;
232 static constexpr uint64_t primitive_root_wasm_2 = 0x0000000000000000UL;
233 static constexpr uint64_t primitive_root_wasm_3 = 0x0000000000000000UL;
234
235 // Coset generators in Montgomery form for R=2^261 mod Modulus. Used in FFT-based proving systems, don't really need
236 // them here
237 static constexpr uint64_t coset_generator_wasm_0 = 0xbd6e9563293f5920ULL;
238 static constexpr uint64_t coset_generator_wasm_1 = 0xb5e4a80dcb554baaULL;
239 static constexpr uint64_t coset_generator_wasm_2 = 0x000000000000003aULL;
240 static constexpr uint64_t coset_generator_wasm_3 = 0x000000dfffffff20ULL;
241
242 // For consistency with bb::fq, if we ever represent an element of bb::secp256r1::fq in the public inputs, we do so
243 // as a bigfield element, so with 4 public inputs
244 static constexpr size_t PUBLIC_INPUTS_SIZE = BIGFIELD_PUBLIC_INPUTS_SIZE;
245};
247
248struct G1Params {
249 static constexpr bool USE_ENDOMORPHISM = false;
250 static constexpr bool can_hash_to_curve = true;
251 static constexpr bool small_elements = true;
252 static constexpr bool has_a = true;
253
254 static constexpr fq b =
255 fq(0x3BCE3C3E27D2604B, 0x651D06B0CC53B0F6, 0xB3EBBD55769886BC, 0x5AC635D8AA3A93E7).to_montgomery_form();
256 static constexpr fq a =
257 fq(0xFFFFFFFFFFFFFFFC, 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000001).to_montgomery_form();
258
259 static constexpr fq one_x =
260 fq(0xF4A13945D898C296, 0x77037D812DEB33A0, 0xF8BCE6E563A440F2, 0x6B17D1F2E12C4247).to_montgomery_form();
261 static constexpr fq one_y =
262 fq(0xCBB6406837BF51F5, 0x2BCE33576B315ECE, 0x8EE7EB4A7C0F9E16, 0x4FE342E2FE1A7F9B).to_montgomery_form();
263};
265
266// specialize the name in msgpack schema generation
267// consumed by the typescript schema compiler, helps disambiguate templates
268inline std::string msgpack_schema_name(g1::affine_element const& /*unused*/)
269{
270 return "Secp256r1Point";
271}
272
273} // namespace bb::secp256r1
274
275namespace bb::curve {
284} // namespace bb::curve
285
286// NOLINTEND(cppcoreguidelines-avoid-c-arrays)
typename Group::affine_element AffineElement
typename Group::element Element
group class. Represents an elliptic curve group element. Group is parametrised by Fq and Fr
Definition group.hpp:36
group_elements::affine_element< Fq, Fr, Params > affine_element
Definition group.hpp:42
group_elements::element< Fq, Fr, Params > element
Definition group.hpp:41
field< FrParams > fr
group< fq, fr, G1Params > g1
std::string msgpack_schema_name(g1::affine_element const &)
field< FqParams > fq
General class for prime fields see Prime field documentation["field documentation"] for general imple...
BB_INLINE constexpr field to_montgomery_form() const noexcept
Parameters defining the base field of the secp256r1 curve.
Definition secp256r1.hpp:24
static constexpr uint64_t modulus_wasm_2
Definition secp256r1.hpp:78
static constexpr uint64_t r_squared_1
Definition secp256r1.hpp:35
static constexpr uint64_t primitive_root_wasm_3
static constexpr size_t PUBLIC_INPUTS_SIZE
static constexpr uint64_t coset_generator_2
Definition secp256r1.hpp:71
static constexpr uint64_t cube_root_3
Definition secp256r1.hpp:59
static constexpr uint64_t primitive_root_0
Definition secp256r1.hpp:62
static constexpr uint64_t r_squared_0
Definition secp256r1.hpp:34
static constexpr uint64_t cube_root_wasm_1
static constexpr uint64_t r_inv_3
Definition secp256r1.hpp:53
static constexpr uint64_t r_inv_0
Definition secp256r1.hpp:50
static constexpr uint64_t primitive_root_3
Definition secp256r1.hpp:65
static constexpr uint64_t r_inv_wasm_8
static constexpr uint64_t modulus_3
Definition secp256r1.hpp:31
static constexpr uint64_t r_squared_wasm_1
Definition secp256r1.hpp:89
static constexpr uint64_t primitive_root_1
Definition secp256r1.hpp:63
static constexpr uint64_t primitive_root_wasm_2
static constexpr uint64_t modulus_wasm_8
Definition secp256r1.hpp:84
static constexpr uint64_t r_squared_wasm_3
Definition secp256r1.hpp:91
static constexpr uint64_t coset_generator_0
Definition secp256r1.hpp:69
static constexpr uint64_t modulus_wasm_3
Definition secp256r1.hpp:79
static constexpr uint64_t cube_root_1
Definition secp256r1.hpp:57
static constexpr uint64_t modulus_wasm_7
Definition secp256r1.hpp:83
static constexpr const char * schema_name
Definition secp256r1.hpp:25
static constexpr uint64_t cube_root_0
Definition secp256r1.hpp:56
static constexpr uint64_t modulus_wasm_5
Definition secp256r1.hpp:81
static constexpr uint64_t r_squared_wasm_2
Definition secp256r1.hpp:90
static constexpr uint64_t cube_root_wasm_2
static constexpr uint64_t modulus_wasm_1
Definition secp256r1.hpp:77
static constexpr uint64_t primitive_root_wasm_1
static constexpr uint64_t primitive_root_2
Definition secp256r1.hpp:64
static constexpr uint64_t cube_root_wasm_3
static constexpr uint64_t r_inv
Definition secp256r1.hpp:44
static constexpr uint64_t coset_generator_3
Definition secp256r1.hpp:72
static constexpr uint64_t r_inv_wasm_7
static constexpr uint64_t r_squared_3
Definition secp256r1.hpp:37
static constexpr uint64_t coset_generator_wasm_2
static constexpr uint64_t modulus_2
Definition secp256r1.hpp:30
static constexpr uint64_t r_inv_wasm_4
static constexpr uint64_t modulus_0
Definition secp256r1.hpp:28
static constexpr uint64_t cube_root_2
Definition secp256r1.hpp:58
static constexpr uint64_t r_inv_wasm_5
static constexpr uint64_t coset_generator_wasm_3
static constexpr uint64_t coset_generator_1
Definition secp256r1.hpp:70
static constexpr uint64_t cube_root_wasm_0
static constexpr uint64_t r_squared_2
Definition secp256r1.hpp:36
static constexpr uint64_t coset_generator_wasm_0
static constexpr uint64_t r_inv_wasm_6
static constexpr uint64_t r_inv_wasm_2
Definition secp256r1.hpp:99
static constexpr uint64_t r_squared_wasm_0
Definition secp256r1.hpp:88
static constexpr uint64_t r_inv_2
Definition secp256r1.hpp:52
static constexpr uint64_t r_inv_1
Definition secp256r1.hpp:51
static constexpr uint64_t r_inv_wasm_0
Definition secp256r1.hpp:97
static constexpr uint64_t coset_generator_wasm_1
static constexpr uint64_t primitive_root_wasm_0
static constexpr uint64_t modulus_wasm_4
Definition secp256r1.hpp:80
static constexpr uint64_t modulus_wasm_6
Definition secp256r1.hpp:82
static constexpr uint64_t modulus_1
Definition secp256r1.hpp:29
static constexpr uint64_t r_inv_wasm_3
static constexpr uint64_t r_inv_wasm_1
Definition secp256r1.hpp:98
static constexpr uint64_t modulus_wasm_0
Definition secp256r1.hpp:76
Parameters defining the scalar field of the secp256r1 curve.
static constexpr uint64_t r_squared_wasm_0
static constexpr uint64_t r_inv_1
static constexpr uint64_t r_squared_1
static constexpr uint64_t r_inv
static constexpr uint64_t primitive_root_wasm_0
static constexpr uint64_t modulus_wasm_6
static constexpr uint64_t coset_generator_2
static constexpr uint64_t modulus_2
static constexpr uint64_t primitive_root_wasm_3
static constexpr uint64_t r_inv_wasm_5
static constexpr uint64_t primitive_root_0
static constexpr uint64_t coset_generator_3
static constexpr uint64_t modulus_wasm_7
static constexpr uint64_t r_inv_wasm_0
static constexpr uint64_t r_squared_0
static constexpr uint64_t modulus_wasm_0
static constexpr uint64_t coset_generator_wasm_0
static constexpr uint64_t modulus_wasm_8
static constexpr uint64_t coset_generator_wasm_1
static constexpr uint64_t r_inv_2
static constexpr uint64_t cube_root_0
static constexpr uint64_t primitive_root_3
static constexpr uint64_t r_inv_wasm_3
static constexpr uint64_t r_inv_wasm_8
static constexpr uint64_t modulus_wasm_1
static constexpr uint64_t primitive_root_1
static constexpr uint64_t r_inv_wasm_7
static constexpr uint64_t modulus_wasm_5
static constexpr const char * schema_name
static constexpr uint64_t primitive_root_wasm_1
static constexpr uint64_t primitive_root_wasm_2
static constexpr uint64_t cube_root_wasm_1
static constexpr uint64_t modulus_wasm_2
static constexpr uint64_t coset_generator_wasm_2
static constexpr uint64_t cube_root_wasm_3
static constexpr uint64_t r_inv_wasm_4
static constexpr uint64_t modulus_1
static constexpr uint64_t r_inv_wasm_2
static constexpr size_t PUBLIC_INPUTS_SIZE
static constexpr uint64_t r_inv_3
static constexpr uint64_t modulus_3
static constexpr uint64_t modulus_wasm_3
static constexpr uint64_t coset_generator_1
static constexpr uint64_t r_squared_wasm_2
static constexpr uint64_t r_inv_wasm_1
static constexpr uint64_t coset_generator_wasm_3
static constexpr uint64_t r_inv_0
static constexpr uint64_t cube_root_2
static constexpr uint64_t r_squared_2
static constexpr uint64_t modulus_wasm_4
static constexpr uint64_t r_squared_3
static constexpr uint64_t r_inv_wasm_6
static constexpr uint64_t cube_root_wasm_0
static constexpr uint64_t r_squared_wasm_3
static constexpr uint64_t cube_root_1
static constexpr uint64_t coset_generator_0
static constexpr uint64_t cube_root_wasm_2
static constexpr uint64_t modulus_0
static constexpr uint64_t r_squared_wasm_1
static constexpr uint64_t primitive_root_2
static constexpr uint64_t cube_root_3
static constexpr fq a
static constexpr bool can_hash_to_curve
static constexpr bool has_a
static constexpr fq one_y
static constexpr bool USE_ENDOMORPHISM
static constexpr fq b
static constexpr bool small_elements
static constexpr fq one_x