Skip to content

Commit 8920c11

Browse files
committed
fare count fixes
1 parent 63fd432 commit 8920c11

File tree

4 files changed

+69
-28
lines changed

4 files changed

+69
-28
lines changed

barretenberg/cpp/src/barretenberg/dsl/acir_format/gate_count_constants.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ inline constexpr size_t HIDING_KERNEL_ULTRA_OPS = 124;
147147
// ========================================
148148

149149
// Gate count for ECCVM recursive verifier (Ultra-arithmetized)
150-
inline constexpr size_t ECCVM_RECURSIVE_VERIFIER_GATE_COUNT = 220533;
150+
inline constexpr size_t ECCVM_RECURSIVE_VERIFIER_GATE_COUNT = 220399;
151151

152152
// ========================================
153153
// Goblin AVM Recursive Verifier Constants

barretenberg/cpp/src/barretenberg/special_public_inputs/special_public_inputs.hpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,18 @@ class DefaultIO {
2222
using FF = curve::BN254::ScalarField;
2323
using PublicPairingPoints = PublicInputComponent<PairingPoints<curve::BN254>>;
2424

25-
static constexpr size_t PUBLIC_INPUTS_SIZE = DEFAULT_PUBLIC_INPUTS_SIZE;
25+
static constexpr size_t PUBLIC_INPUTS_SIZE = PairingPoints<curve::BN254>::PUBLIC_INPUTS_SIZE;
2626
static constexpr bool HasIPA = false;
2727

2828
PairingPoints<curve::BN254> pairing_inputs;
2929

3030
/**
3131
* @brief Reconstructs the IO components from a public inputs array.
32-
*
33-
* @param public_inputs Public inputs array containing the serialized kernel public inputs.
3432
*/
3533
void reconstruct_from_public(const std::vector<FF>& public_inputs)
3634
{
3735
// Assumes that the app-io public inputs are at the end of the public_inputs vector
3836
uint32_t index = static_cast<uint32_t>(public_inputs.size() - PUBLIC_INPUTS_SIZE);
39-
4037
pairing_inputs = PublicPairingPoints::reconstruct(public_inputs, PublicComponentKey{ index });
4138
}
4239

@@ -61,7 +58,8 @@ class HidingKernelIO {
6158
using PublicPairingPoints = PublicInputComponent<PairingPoints<curve::BN254>>;
6259
using PublicPoint = PublicInputComponent<G1>;
6360

64-
static constexpr size_t PUBLIC_INPUTS_SIZE = HIDING_KERNEL_PUBLIC_INPUTS_SIZE;
61+
static constexpr size_t PUBLIC_INPUTS_SIZE =
62+
PairingPoints<curve::BN254>::PUBLIC_INPUTS_SIZE + G1::PUBLIC_INPUTS_SIZE * (1 + MegaCircuitBuilder::NUM_WIRES);
6563
static constexpr bool HasIPA = false;
6664

6765
PairingPoints<curve::BN254> pairing_inputs;
@@ -70,8 +68,6 @@ class HidingKernelIO {
7068

7169
/**
7270
* @brief Reconstructs the IO components from a public inputs array.
73-
*
74-
* @param public_inputs Public inputs array containing the serialized kernel public inputs.
7571
*/
7672
void reconstruct_from_public(const std::vector<FF>& public_inputs)
7773
{
@@ -108,20 +104,19 @@ class RollupIO {
108104
using PublicPairingPoints = PublicInputComponent<PairingPoints<curve::BN254>>;
109105
using PublicIpaClaim = PublicInputComponent<IpaClaim>;
110106

111-
static constexpr size_t PUBLIC_INPUTS_SIZE = ROLLUP_PUBLIC_INPUTS_SIZE;
107+
static constexpr size_t PUBLIC_INPUTS_SIZE =
108+
PairingPoints<curve::BN254>::PUBLIC_INPUTS_SIZE + IpaClaim::PUBLIC_INPUTS_SIZE;
112109
static constexpr bool HasIPA = true;
113110

114111
PairingPoints<curve::BN254> pairing_inputs;
115112
IpaClaim ipa_claim;
116113

117114
/**
118115
* @brief Reconstructs the IO components from a public inputs array.
119-
*
120-
* @param public_inputs Public inputs array containing the serialized kernel public inputs.
121116
*/
122117
void reconstruct_from_public(const std::vector<FF>& public_inputs)
123118
{
124-
// Assumes that the app-io public inputs are at the end of the public_inputs vector
119+
// Assumes that the rollup-io public inputs are at the end of the public_inputs vector
125120
uint32_t index = static_cast<uint32_t>(public_inputs.size() - PUBLIC_INPUTS_SIZE);
126121

127122
pairing_inputs = PublicPairingPoints::reconstruct(public_inputs, PublicComponentKey{ index });

barretenberg/cpp/src/barretenberg/stdlib/primitives/pairing_points.hpp

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,36 @@
1616

1717
namespace bb::stdlib::recursion {
1818

19+
// Combined limbs for default pairing points: lo = limb0 + limb1 * 2^68, hi = limb2 + limb3 * 2^68
20+
// These are the source of truth, used in set_default_to_public() to avoid expensive bigfield operations.
21+
static constexpr bb::fr DEFAULT_PP_P0_X_LO =
22+
bb::fr("0x000000000000000000000000000000b75c020998797da7842ab5d6d1986846cf");
23+
static constexpr bb::fr DEFAULT_PP_P0_X_HI =
24+
bb::fr("0x0000000000000000000000000000000000031e97a575e9d05a107acb64952eca");
25+
static constexpr bb::fr DEFAULT_PP_P0_Y_LO =
26+
bb::fr("0x000000000000000000000000000000c410db10a01750aebb5666547acf8bd5a4");
27+
static constexpr bb::fr DEFAULT_PP_P0_Y_HI =
28+
bb::fr("0x0000000000000000000000000000000000178cbf4206471d722669117f9758a4");
29+
static constexpr bb::fr DEFAULT_PP_P1_X_LO =
30+
bb::fr("0x0000000000000000000000000000007fd51009034b3357f0e91b8a11e7842c38");
31+
static constexpr bb::fr DEFAULT_PP_P1_X_HI =
32+
bb::fr("0x00000000000000000000000000000000000f94656a2ca489889939f81e9c7402");
33+
static constexpr bb::fr DEFAULT_PP_P1_Y_LO =
34+
bb::fr("0x00000000000000000000000000000093fe27776f50224bd6fb128b46c1ddb67f");
35+
static constexpr bb::fr DEFAULT_PP_P1_Y_HI =
36+
bb::fr("0x00000000000000000000000000000000001b52c2020d7464a0c80c0da527a081");
37+
1938
// TODO(https://github.com/AztecProtocol/barretenberg/issues/911): These are pairing points extracted from a
2039
// valid proof. This is a workaround because we can't represent the point at infinity in biggroup yet.
40+
// Derived from the combined limbs above: fq = lo + hi * 2^136
2141
static constexpr bb::fq DEFAULT_PAIRING_POINT_P0_X =
22-
bb::fq("0x031e97a575e9d05a107acb64952ecab75c020998797da7842ab5d6d1986846cf");
42+
bb::fq(uint256_t(DEFAULT_PP_P0_X_LO) + (uint256_t(DEFAULT_PP_P0_X_HI) << 136));
2343
static constexpr bb::fq DEFAULT_PAIRING_POINT_P0_Y =
24-
bb::fq("0x178cbf4206471d722669117f9758a4c410db10a01750aebb5666547acf8bd5a4");
44+
bb::fq(uint256_t(DEFAULT_PP_P0_Y_LO) + (uint256_t(DEFAULT_PP_P0_Y_HI) << 136));
2545
static constexpr bb::fq DEFAULT_PAIRING_POINT_P1_X =
26-
bb::fq("0x0f94656a2ca489889939f81e9c74027fd51009034b3357f0e91b8a11e7842c38");
46+
bb::fq(uint256_t(DEFAULT_PP_P1_X_LO) + (uint256_t(DEFAULT_PP_P1_X_HI) << 136));
2747
static constexpr bb::fq DEFAULT_PAIRING_POINT_P1_Y =
28-
bb::fq("0x1b52c2020d7464a0c80c0da527a08193fe27776f50224bd6fb128b46c1ddb67f");
48+
bb::fq(uint256_t(DEFAULT_PP_P1_Y_LO) + (uint256_t(DEFAULT_PP_P1_Y_HI) << 136));
2949

3050
/**
3151
* @brief An object storing two EC points that represent the inputs to a pairing check.
@@ -81,11 +101,21 @@ template <typename Curve> struct PairingPoints {
81101
{}
82102

83103
// Array-like accessors for Codec compatibility
84-
Group& operator[](size_t idx) { return idx == 0 ? P0 : P1; }
104+
// Non-const version sets has_data since it's called during assignment (e.g., by Codec deserialization)
105+
Group& operator[](size_t idx)
106+
{
107+
has_data = true;
108+
return idx == 0 ? P0 : P1;
109+
}
85110
const Group& operator[](size_t idx) const { return idx == 0 ? P0 : P1; }
86111

87112
// Iterator support for range-based for (required by Codec)
88-
Group* begin() { return &P0; }
113+
// Non-const begin() sets has_data since it's called during Codec deserialization
114+
Group* begin()
115+
{
116+
has_data = true;
117+
return &P0;
118+
}
89119
Group* end() { return &P1 + 1; }
90120
const Group* begin() const { return &P0; }
91121
const Group* end() const { return &P1 + 1; }
@@ -244,16 +274,34 @@ template <typename Curve> struct PairingPoints {
244274

245275
/**
246276
* @brief Set the witness indices for the default limbs of the pairing points to public.
247-
* @details Creates default pairing points as witnesses, then sets them public.
277+
* @details Optimized version that directly sets precomputed Fr limb values as public inputs,
278+
* avoiding expensive bigfield operations. The default pairing points satisfy the
279+
* pairing equation, which is verified at compile time via static assertion.
248280
*
249281
* @return uint32_t The index into the public inputs array at which the representation is stored
250282
*/
251283
static uint32_t set_default_to_public(Builder* builder)
252284
{
253-
PairingPoints pp = construct_default();
254-
pp.P0.convert_constant_to_fixed_witness(builder);
255-
pp.P1.convert_constant_to_fixed_witness(builder);
256-
return pp.set_public();
285+
// Directly add precomputed combined limbs as public inputs, bypassing bigfield's self_reduce.
286+
// These values encode the default pairing points in the format used by bigfield::set_public().
287+
// Order: P0.x (lo, hi), P0.y (lo, hi), P1.x (lo, hi), P1.y (lo, hi)
288+
// Each fix_witness call adds 1 gate to constrain the value at the VK level.
289+
auto add_fixed_public = [&](const bb::fr& value) {
290+
uint32_t idx = builder->add_public_variable(value);
291+
builder->fix_witness(idx, value);
292+
return idx;
293+
};
294+
295+
uint32_t start_idx = add_fixed_public(DEFAULT_PP_P0_X_LO);
296+
add_fixed_public(DEFAULT_PP_P0_X_HI);
297+
add_fixed_public(DEFAULT_PP_P0_Y_LO);
298+
add_fixed_public(DEFAULT_PP_P0_Y_HI);
299+
add_fixed_public(DEFAULT_PP_P1_X_LO);
300+
add_fixed_public(DEFAULT_PP_P1_X_HI);
301+
add_fixed_public(DEFAULT_PP_P1_Y_LO);
302+
add_fixed_public(DEFAULT_PP_P1_Y_HI);
303+
304+
return start_idx;
257305
}
258306

259307
/**

barretenberg/cpp/src/barretenberg/stdlib/primitives/pairing_points.test.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,9 @@ TYPED_TEST_SUITE(PairingPointsTests, Curves);
1919
TYPED_TEST(PairingPointsTests, ConstructDefault)
2020
{
2121
using Builder = typename TypeParam::Builder;
22-
// Ultra uses bigfield which requires range constraints for self_reduce() when setting public inputs.
23-
// This looks expensive (1853 gates) but gets amortized in real circuits since most range tables
24-
// already exist from other bigfield operations.
25-
// Mega uses goblin_field (2 limbs) which is much cheaper (8 gates).
26-
static constexpr size_t NUM_GATES_ADDED = IsMegaBuilder<Builder> ? 8 : 1853;
22+
// Both builders now use the optimized path: 8 fix_witness gates for the 8 combined limbs.
23+
// This bypasses bigfield's expensive self_reduce() for Ultra.
24+
static constexpr size_t NUM_GATES_ADDED = 8;
2725

2826
Builder builder;
2927

0 commit comments

Comments
 (0)