Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
constants.test.cpp
Go to the documentation of this file.
1
8#include "fq.hpp"
9#include "fr.hpp"
10#include <array>
11#include <gtest/gtest.h>
12
13using namespace bb;
14namespace {
15uint256_t native_q{
17};
18uint256_t native_r{
20};
21
22// Helper to convert a decimal string to uint256_t
23uint256_t from_decimal(const std::string& dec_str)
24{
25 uint256_t result = 0;
26 for (char c : dec_str) {
27 result = result * 10 + static_cast<uint64_t>(c - '0');
28 }
29 return result;
30}
31} // namespace
32
33TEST(FqConstants, Modulus)
34{
35 // BN254 base field prime: q = 21888242871839275222246405745257275088696311157297823662689037894645226208583
36 // References:
37 // [eip-196](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-196.md)
38 // [ark-works](https://docs.rs/ark-bn254/latest/ark_bn254/)
39 // [BN-254 for the rest of us](https://hackmd.io/@jpw/bn254)
40 uint256_t expected_q =
41 from_decimal("21888242871839275222246405745257275088696311157297823662689037894645226208583");
42 EXPECT_EQ(expected_q, native_q);
43}
44
45TEST(FqConstants, RSquared)
46{
47 // R^2 = (2^256)^2 mod q.
48 uint512_t R = (uint512_t(1) << 256) % native_q;
49 uint512_t expected_r_sqr_mod_q = (R * R) % native_q;
50 uint256_t actual_r_sqr_mod_q{
52 };
53 EXPECT_EQ(expected_r_sqr_mod_q.lo, actual_r_sqr_mod_q);
54}
55
56TEST(FqConstants, RInv)
57{
58 // r_inv = -q^{-1} mod 2^64
59 uint512_t r{ 0, 1 };
60 uint512_t q{ -native_q, 0 };
61 uint256_t q_inv = q.invmod(r).lo;
62 uint64_t expected = q_inv.data[0];
63 uint64_t result = Bn254FqParams::r_inv;
64 EXPECT_EQ(result, expected);
65}
66
67TEST(FqConstants, CubeRootOfUnity)
68{
70
71 // Verify beta^3 = 1 and beta != 1
72 EXPECT_EQ(beta * beta * beta, fq::one());
73 EXPECT_NE(beta, fq::one());
74}
75
76// ================================
77// WASM Consistency Tests
78// ================================
79
80TEST(FqConstants, WasmModulusConsistency)
81{
82 // WASM uses 9 x 29-bit limbs to represent the modulus
83 // Verify that the 29-bit limb representation reconstructs to the same value as the 4 x 64-bit limb representation
84 constexpr std::array<uint64_t, 9> wasm_limbs = { Bn254FqParams::modulus_wasm_0, Bn254FqParams::modulus_wasm_1,
89
90 uint512_t wasm_modulus = 0;
91 for (size_t i = 0; i < 9; i++) {
92 wasm_modulus += uint512_t(wasm_limbs[i]) << (29UL * i);
93 // Verify each limb fits in 29 bits
94 EXPECT_LT(wasm_limbs[i], uint64_t(1) << 29);
95 }
96
97 EXPECT_EQ(wasm_modulus.lo, native_q);
98 EXPECT_EQ(wasm_modulus.hi, uint256_t(0));
99}
100
101TEST(FqConstants, WasmRSquared)
102{
103 // WASM uses R = 2^261 (since 261 = 29 * 9)
104 // r_squared_wasm should be (2^261)^2 mod q = 2^522 mod q
105 uint512_t R_wasm = uint512_t(1) << 261;
106 uint512_t R_wasm_mod_q = R_wasm % native_q;
107 uint512_t expected_r_squared_wasm = (R_wasm_mod_q * R_wasm_mod_q) % native_q;
108
109 uint256_t actual_r_squared_wasm{ Bn254FqParams::r_squared_wasm_0,
113
114 EXPECT_EQ(expected_r_squared_wasm.lo, actual_r_squared_wasm);
115}
116
117TEST(FqConstants, WasmCubeRootConsistency)
118{
119 // The cube root in WASM Montgomery form should represent the same field element
120 // as the cube root in native Montgomery form.
121 //
122 // Native Montgomery form: cube_root_native = beta * R_native mod q, where R_native = 2^256
123 // WASM Montgomery form: cube_root_wasm = beta * R_wasm mod q, where R_wasm = 2^261
124 //
125 // Therefore: cube_root_wasm = cube_root_native * (R_wasm / R_native) mod q
126 // = cube_root_native * 2^5 mod q
127
128 uint256_t cube_root_native{
130 };
131
136
137 // R_wasm / R_native = 2^261 / 2^256 = 2^5 = 32
138 uint512_t expected_cube_root_wasm = (uint512_t(cube_root_native) * 32) % native_q;
139
140 EXPECT_EQ(expected_cube_root_wasm.lo, cube_root_wasm);
141}
142// r_inv_wasm represents 2^(-29) mod q in 9 x 29-bit limbs
143// this tests checks that that r_inv_wasm < q/2 (and in particular less than q).
144TEST(FqConstants, WasmRInvLessThanModulus)
145{
146 // Verify that when reconstructed as a uint512_t, it is less than the modulus q
147 constexpr std::array<uint64_t, 9> r_inv_wasm_limbs = { Bn254FqParams::r_inv_wasm_0, Bn254FqParams::r_inv_wasm_1,
152
153 uint512_t r_inv_wasm = 0;
154 for (size_t i = 0; i < 9; i++) {
155 r_inv_wasm += uint512_t(r_inv_wasm_limbs[i]) << (29UL * i);
156 // Verify each limb fits in 29 bits
157 EXPECT_LT(r_inv_wasm_limbs[i], uint64_t(1) << 29);
158 }
159
160 // Verify r_inv_wasm < q/2
161 EXPECT_LT(r_inv_wasm, uint512_t(native_q) / 2);
162}
163
164// ================================
165// Fr Constants Tests
166// ================================
167
168TEST(FrConstants, Modulus)
169{
170 // BN254 scalar field prime (also the Baby Jubjub base field):
171 // r = 21888242871839275222246405745257275088548364400416034343698204186575808495617
172 // References:
173 // [eip-196](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-196.md)
174 // [ark-works](https://docs.rs/ark-bn254/latest/ark_bn254/)
175 // [BN-254 for the rest of us](https://hackmd.io/@jpw/bn254)
176 uint256_t expected_r =
177 from_decimal("21888242871839275222246405745257275088548364400416034343698204186575808495617");
178 EXPECT_EQ(expected_r, native_r);
179}
180
181TEST(FrConstants, RSquared)
182{
183 // R^2 = (2^256)^2 mod r.
184 uint512_t R = (uint512_t(1) << 256) % native_r;
185 uint512_t expected_r_sqr_mod_r = (R * R) % native_r;
186 uint256_t actual_r_sqr_mod_r{
188 };
189 EXPECT_EQ(expected_r_sqr_mod_r.lo, actual_r_sqr_mod_r);
190}
191
192TEST(FrConstants, RInv)
193{
194 // r_inv = -r^{-1} mod 2^64
195 uint512_t two_64{ 0, 1 };
196 uint512_t neg_r{ -native_r, 0 };
197 uint256_t r_inv = neg_r.invmod(two_64).lo;
198 uint64_t expected = r_inv.data[0];
199 uint64_t result = Bn254FrParams::r_inv;
200 EXPECT_EQ(result, expected);
201}
202
203TEST(FrConstants, CubeRootOfUnity)
204{
205 fr beta = fr::cube_root_of_unity();
206
207 // Verify beta^3 = 1 and beta != 1
208 EXPECT_EQ(beta * beta * beta, fr::one());
209 EXPECT_NE(beta, fr::one());
210}
211
212// ================================
213// Fr WASM Consistency Tests
214// ================================
215
216TEST(FrConstants, WasmModulusConsistency)
217{
218 // WASM uses 9 x 29-bit limbs to represent the modulus
219 constexpr std::array<uint64_t, 9> wasm_limbs = { Bn254FrParams::modulus_wasm_0, Bn254FrParams::modulus_wasm_1,
224
225 uint512_t wasm_modulus = 0;
226 for (size_t i = 0; i < 9; i++) {
227 wasm_modulus += uint512_t(wasm_limbs[i]) << (29UL * i);
228 EXPECT_LT(wasm_limbs[i], uint64_t(1) << 29);
229 }
230
231 EXPECT_EQ(wasm_modulus.lo, native_r);
232 EXPECT_EQ(wasm_modulus.hi, uint256_t(0));
233}
234
235TEST(FrConstants, WasmRSquared)
236{
237 // WASM uses R = 2^261 (since 261 = 29 * 9)
238 uint512_t R_wasm = uint512_t(1) << 261;
239 uint512_t R_wasm_mod_r = R_wasm % native_r;
240 uint512_t expected_r_squared_wasm = (R_wasm_mod_r * R_wasm_mod_r) % native_r;
241
242 uint256_t actual_r_squared_wasm{ Bn254FrParams::r_squared_wasm_0,
246
247 EXPECT_EQ(expected_r_squared_wasm.lo, actual_r_squared_wasm);
248}
249
250TEST(FrConstants, WasmCubeRootConsistency)
251{
252 // The cube root in WASM Montgomery form should represent the same field element
253 // as the cube root in native Montgomery form.
254 uint256_t cube_root_native{
256 };
257
262
263 // R_wasm / R_native = 2^261 / 2^256 = 2^5 = 32
264 uint512_t expected_cube_root_wasm = (uint512_t(cube_root_native) * 32) % native_r;
265
266 EXPECT_EQ(expected_cube_root_wasm.lo, cube_root_wasm);
267}
268
269// r_inv_wasm represents 2^(-29) mod r in 9 x 29-bit limbs
270// this tests verifies that r_inv_wasm < r/2.
271TEST(FrConstants, WasmRInvLessThanModulus)
272{
273 // Verify that when reconstructed as a uint512_t, it is less than the modulus r
274 constexpr std::array<uint64_t, 9> r_inv_wasm_limbs = { Bn254FrParams::r_inv_wasm_0, Bn254FrParams::r_inv_wasm_1,
279
280 uint512_t r_inv_wasm = 0;
281 for (size_t i = 0; i < 9; i++) {
282 r_inv_wasm += uint512_t(r_inv_wasm_limbs[i]) << (29UL * i);
283 // Verify each limb fits in 29 bits
284 EXPECT_LT(r_inv_wasm_limbs[i], uint64_t(1) << 29);
285 }
286
287 // Verify r_inv_wasm < r/2
288 EXPECT_LT(r_inv_wasm, uint512_t(native_r) / 2);
289}
static constexpr uint64_t cube_root_wasm_1
Definition fq.hpp:64
static constexpr uint64_t modulus_0
Definition fq.hpp:24
static constexpr uint64_t r_inv_wasm_6
Definition fq.hpp:118
static constexpr uint64_t r_inv_wasm_4
Definition fq.hpp:116
static constexpr uint64_t modulus_wasm_0
Definition fq.hpp:44
static constexpr uint64_t modulus_wasm_5
Definition fq.hpp:49
static constexpr uint64_t modulus_wasm_4
Definition fq.hpp:48
static constexpr uint64_t r_squared_3
Definition fq.hpp:34
static constexpr uint64_t r_inv_wasm_8
Definition fq.hpp:120
static constexpr uint64_t r_inv_wasm_2
Definition fq.hpp:114
static constexpr uint64_t r_squared_2
Definition fq.hpp:33
static constexpr uint64_t cube_root_wasm_3
Definition fq.hpp:66
static constexpr uint64_t modulus_wasm_7
Definition fq.hpp:51
static constexpr uint64_t modulus_wasm_1
Definition fq.hpp:45
static constexpr uint64_t modulus_3
Definition fq.hpp:27
static constexpr uint64_t r_squared_wasm_0
Definition fq.hpp:56
static constexpr uint64_t modulus_1
Definition fq.hpp:25
static constexpr uint64_t r_inv_wasm_0
Definition fq.hpp:112
static constexpr uint64_t cube_root_wasm_0
Definition fq.hpp:63
static constexpr uint64_t r_inv_wasm_7
Definition fq.hpp:119
static constexpr uint64_t r_squared_0
Definition fq.hpp:31
static constexpr uint64_t cube_root_wasm_2
Definition fq.hpp:65
static constexpr uint64_t modulus_2
Definition fq.hpp:26
static constexpr uint64_t modulus_wasm_8
Definition fq.hpp:52
static constexpr uint64_t r_squared_1
Definition fq.hpp:32
static constexpr uint64_t modulus_wasm_2
Definition fq.hpp:46
static constexpr uint64_t r_inv_wasm_3
Definition fq.hpp:115
static constexpr uint64_t r_squared_wasm_1
Definition fq.hpp:57
static constexpr uint64_t cube_root_1
Definition fq.hpp:38
static constexpr uint64_t cube_root_0
Definition fq.hpp:37
static constexpr uint64_t r_squared_wasm_3
Definition fq.hpp:59
static constexpr uint64_t cube_root_2
Definition fq.hpp:39
static constexpr uint64_t r_squared_wasm_2
Definition fq.hpp:58
static constexpr uint64_t r_inv_wasm_5
Definition fq.hpp:117
static constexpr uint64_t cube_root_3
Definition fq.hpp:40
static constexpr uint64_t r_inv_wasm_1
Definition fq.hpp:113
static constexpr uint64_t modulus_wasm_6
Definition fq.hpp:50
static constexpr uint64_t modulus_wasm_3
Definition fq.hpp:47
static constexpr uint64_t r_inv
Definition fq.hpp:97
static constexpr uint64_t r_inv_wasm_0
Definition fr.hpp:83
static constexpr uint64_t modulus_wasm_8
Definition fr.hpp:121
static constexpr uint64_t r_inv
Definition fr.hpp:68
static constexpr uint64_t modulus_wasm_3
Definition fr.hpp:116
static constexpr uint64_t r_inv_wasm_2
Definition fr.hpp:85
static constexpr uint64_t modulus_wasm_4
Definition fr.hpp:117
static constexpr uint64_t cube_root_wasm_0
Definition fr.hpp:132
static constexpr uint64_t cube_root_wasm_3
Definition fr.hpp:135
static constexpr uint64_t r_squared_wasm_3
Definition fr.hpp:128
static constexpr uint64_t r_inv_wasm_7
Definition fr.hpp:90
static constexpr uint64_t r_squared_3
Definition fr.hpp:37
static constexpr uint64_t r_inv_wasm_8
Definition fr.hpp:91
static constexpr uint64_t modulus_0
Definition fr.hpp:28
static constexpr uint64_t r_squared_1
Definition fr.hpp:35
static constexpr uint64_t r_inv_wasm_6
Definition fr.hpp:89
static constexpr uint64_t cube_root_3
Definition fr.hpp:43
static constexpr uint64_t modulus_wasm_6
Definition fr.hpp:119
static constexpr uint64_t modulus_wasm_0
Definition fr.hpp:113
static constexpr uint64_t cube_root_1
Definition fr.hpp:41
static constexpr uint64_t r_squared_wasm_1
Definition fr.hpp:126
static constexpr uint64_t r_inv_wasm_4
Definition fr.hpp:87
static constexpr uint64_t r_squared_0
Definition fr.hpp:34
static constexpr uint64_t r_squared_2
Definition fr.hpp:36
static constexpr uint64_t cube_root_0
Definition fr.hpp:40
static constexpr uint64_t modulus_3
Definition fr.hpp:31
static constexpr uint64_t cube_root_wasm_1
Definition fr.hpp:133
static constexpr uint64_t modulus_wasm_5
Definition fr.hpp:118
static constexpr uint64_t r_inv_wasm_3
Definition fr.hpp:86
static constexpr uint64_t modulus_wasm_2
Definition fr.hpp:115
static constexpr uint64_t modulus_wasm_1
Definition fr.hpp:114
static constexpr uint64_t r_inv_wasm_1
Definition fr.hpp:84
static constexpr uint64_t cube_root_2
Definition fr.hpp:42
static constexpr uint64_t r_squared_wasm_0
Definition fr.hpp:125
static constexpr uint64_t r_squared_wasm_2
Definition fr.hpp:127
static constexpr uint64_t modulus_wasm_7
Definition fr.hpp:120
static constexpr uint64_t modulus_2
Definition fr.hpp:30
static constexpr uint64_t cube_root_wasm_2
Definition fr.hpp:134
static constexpr uint64_t modulus_1
Definition fr.hpp:29
static constexpr uint64_t r_inv_wasm_5
Definition fr.hpp:88
uintx< uint256_t > uint512_t
Definition uintx.hpp:306
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)
static constexpr field cube_root_of_unity()
static constexpr field one()