-
Notifications
You must be signed in to change notification settings - Fork 599
chore: cycle group cleanup #5 #17026
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
6b23fd2
remove unused cycle_scalar interfaces and use bigfield in test suite
ledwards2225 4832bd6
remove option to skip primality in construct from bn254
ledwards2225 bf3eacb
use from_witness for consistency
ledwards2225 c6292e0
add split_at_unrestricted (bad name!)
ledwards2225 14c1400
add split method to field and bring back from witness for fuzzer build
ledwards2225 fb17bdf
bring back constructor for fuzzer
ledwards2225 ce5e3da
update plsit at naming and fix tests
ledwards2225 dd1401e
use split_at in create_from_bn254_scalar
ledwards2225 3035add
cleanup
ledwards2225 984cb44
Merge branch 'merge-train/barretenberg' into lde/cycle-group-5
ledwards2225 d1d440e
Merge branch 'next' into lde/cycle-group-5
ledwards2225 d9eb676
implement split unique in field utils
ledwards2225 7c563b0
Merge branch 'merge-train/barretenberg' into lde/cycle-group-5
ledwards2225 5da71f1
fix wasm build
ledwards2225 6001747
Merge branch 'merge-train/barretenberg' into lde/cycle-group-5
ledwards2225 e690fd2
revert test changes for now
ledwards2225 83be28b
add num gates pinning to cycle group tests
ledwards2225 1de5c17
use evaluate linear identity; no gate change
ledwards2225 50808c0
Merge branch 'merge-train/barretenberg' into lde/cycle-group-5
ledwards2225 12c79de
vk hash
ledwards2225 1b5047e
Merge branch 'merge-train/barretenberg' into lde/cycle-group-5
ledwards2225 739ad72
vk hash
ledwards2225 99c1cd1
try again
ledwards2225 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1271,10 +1271,13 @@ template <typename Builder> field_t<Builder> field_t<Builder>::accumulate(const | |
| * @brief Splits the field element into (lo, hi), where: | ||
| * - lo contains bits [0, lsb_index) | ||
| * - hi contains bits [lsb_index, num_bits) | ||
| * @details Max bits is specified as an argument, and must be <= grumpkin::MAX_NO_WRAP_INTEGER_BIT_LENGTH (to ensure no | ||
| * modular wrap). | ||
| * | ||
| */ | ||
| template <typename Builder> | ||
| std::pair<field_t<Builder>, field_t<Builder>> field_t<Builder>::split_at(const size_t lsb_index, | ||
| const size_t num_bits) const | ||
| std::pair<field_t<Builder>, field_t<Builder>> field_t<Builder>::no_wrap_split_at(const size_t lsb_index, | ||
| const size_t num_bits) const | ||
| { | ||
| ASSERT(lsb_index < num_bits); | ||
| ASSERT(num_bits <= grumpkin::MAX_NO_WRAP_INTEGER_BIT_LENGTH); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure why this constant is 252 - would be nice to add some documentation |
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_utils.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| // === AUDIT STATUS === | ||
| // internal: { status: not started, auditors: [], date: YYYY-MM-DD } | ||
| // external_1: { status: not started, auditors: [], date: YYYY-MM-DD } | ||
| // external_2: { status: not started, auditors: [], date: YYYY-MM-DD } | ||
| // ===================== | ||
|
|
||
| #include "./field_utils.hpp" | ||
| #include "./field.hpp" | ||
| #include "barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp" | ||
|
|
||
| namespace bb::stdlib { | ||
|
|
||
| template <typename Builder> | ||
| void validate_split_in_field(const field_t<Builder>& lo, | ||
| const field_t<Builder>& hi, | ||
| const size_t lo_bits, | ||
| const uint256_t& field_modulus) | ||
| { | ||
| const size_t hi_bits = static_cast<size_t>(field_modulus.get_msb()) + 1 - lo_bits; | ||
|
|
||
| // Split the field modulus at the same position | ||
| const uint256_t r_lo = field_modulus.slice(0, lo_bits); | ||
| const uint256_t r_hi = field_modulus.slice(lo_bits, field_modulus.get_msb() + 1); | ||
|
|
||
| // Check if we need to borrow | ||
| bool need_borrow = uint256_t(lo.get_value()) > r_lo; | ||
| field_t<Builder> borrow = | ||
| lo.is_constant() ? need_borrow : field_t<Builder>::from_witness(lo.get_context(), need_borrow); | ||
|
|
||
| // directly call `create_new_range_constraint` to avoid creating an arithmetic gate | ||
| if (!lo.is_constant()) { | ||
| // We need to manually propagate the origin tag | ||
| borrow.set_origin_tag(lo.get_origin_tag()); | ||
| lo.get_context()->create_new_range_constraint(borrow.get_witness_index(), 1, "borrow"); | ||
| } | ||
|
|
||
| // Hi range check = r_hi - hi - borrow | ||
| // Lo range check = r_lo - lo + borrow * 2^lo_bits | ||
| field_t<Builder> hi_diff = (-hi + r_hi) - borrow; | ||
| field_t<Builder> lo_diff = (-lo + r_lo) + (borrow * (uint256_t(1) << lo_bits)); | ||
|
|
||
| hi_diff.create_range_constraint(hi_bits); | ||
| lo_diff.create_range_constraint(lo_bits); | ||
| } | ||
|
|
||
| template <typename Builder> | ||
| std::pair<field_t<Builder>, field_t<Builder>> split_unique(const field_t<Builder>& field, | ||
| const size_t lo_bits, | ||
| const bool skip_range_constraints) | ||
| { | ||
| using native = typename field_t<Builder>::native; | ||
| static constexpr size_t max_bits = native::modulus.get_msb() + 1; | ||
| ASSERT(lo_bits < max_bits); | ||
|
|
||
| const uint256_t value(field.get_value()); | ||
| const uint256_t lo_val = value.slice(0, lo_bits); | ||
| const uint256_t hi_val = value.slice(lo_bits, max_bits); | ||
|
|
||
| Builder* ctx = field.get_context(); | ||
|
|
||
| // If `field` is constant, return constants based on the native hi/lo values | ||
| if (field.is_constant()) { | ||
| return { field_t<Builder>(lo_val), field_t<Builder>(hi_val) }; | ||
| } | ||
|
|
||
| // Create hi/lo witnesses | ||
| auto lo = field_t<Builder>::from_witness(ctx, lo_val); | ||
| auto hi = field_t<Builder>::from_witness(ctx, hi_val); | ||
|
|
||
| // Component 1: Reconstruction constraint lo + hi * 2^lo_bits - field == 0 | ||
| const uint256_t shift = uint256_t(1) << lo_bits; | ||
| auto zero = field_t<Builder>::from_witness_index(ctx, ctx->zero_idx); | ||
| field_t<Builder>::evaluate_linear_identity(lo, hi * shift, -field, zero); | ||
|
|
||
| // Set the origin tag for the limbs | ||
| lo.set_origin_tag(field.get_origin_tag()); | ||
| hi.set_origin_tag(field.get_origin_tag()); | ||
|
|
||
| // Component 2: Field validation against bn254 scalar field modulus | ||
| validate_split_in_field(lo, hi, lo_bits, native::modulus); | ||
|
|
||
| // Component 3: Range constraints (unless skipped) | ||
| if (!skip_range_constraints) { | ||
| lo.create_range_constraint(lo_bits); | ||
| // For bn254 scalar field, hi_bits = 254 - lo_bits | ||
| const size_t hi_bits = 254 - lo_bits; | ||
| hi.create_range_constraint(hi_bits); | ||
| } | ||
|
|
||
| return { lo, hi }; | ||
| } | ||
|
|
||
| // Explicit instantiations for split_unique | ||
| template std::pair<field_t<bb::UltraCircuitBuilder>, field_t<bb::UltraCircuitBuilder>> split_unique( | ||
| const field_t<bb::UltraCircuitBuilder>& field, const size_t lo_bits, const bool skip_range_constraints); | ||
| template std::pair<field_t<bb::MegaCircuitBuilder>, field_t<bb::MegaCircuitBuilder>> split_unique( | ||
| const field_t<bb::MegaCircuitBuilder>& field, const size_t lo_bits, const bool skip_range_constraints); | ||
|
|
||
| // Explicit instantiations for validate_split_in_field | ||
| template void validate_split_in_field(const field_t<bb::UltraCircuitBuilder>& lo, | ||
| const field_t<bb::UltraCircuitBuilder>& hi, | ||
| const size_t lo_bits, | ||
| const uint256_t& field_modulus); | ||
| template void validate_split_in_field(const field_t<bb::MegaCircuitBuilder>& lo, | ||
| const field_t<bb::MegaCircuitBuilder>& hi, | ||
| const size_t lo_bits, | ||
| const uint256_t& field_modulus); | ||
|
|
||
| } // namespace bb::stdlib |
52 changes: 52 additions & 0 deletions
52
barretenberg/cpp/src/barretenberg/stdlib/primitives/field/field_utils.hpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| // === AUDIT STATUS === | ||
| // internal: { status: not started, auditors: [], date: YYYY-MM-DD } | ||
| // external_1: { status: not started, auditors: [], date: YYYY-MM-DD } | ||
| // external_2: { status: not started, auditors: [], date: YYYY-MM-DD } | ||
| // ===================== | ||
|
|
||
| #pragma once | ||
|
|
||
| #include "./field.hpp" | ||
| #include <utility> | ||
|
|
||
| namespace bb::stdlib { | ||
|
|
||
| template <typename Builder> class field_t; | ||
|
|
||
| /** | ||
| * @brief Split a bn254 scalar field element into unique lo and hi limbs | ||
| * | ||
| * @details Splits `field` into a low and high limb at the given bit index with: | ||
| * 1. Reconstruction constraint: lo + hi * 2^lo_bits = field | ||
| * 2. Modulus check: lo + hi * 2^lo_bits < bn254::ScalarField::modulus | ||
| * 3. Range constraints: lo in [0, 2^lo_bits), hi in [0, 2^(254-lo_bits)) (unless skip_range_constraints = true) | ||
| * | ||
| * @note The combination of (2) and (3) establishes the uniqueness of the decomposition. | ||
| * | ||
| * @param field The bn254 scalar field element to split | ||
| * @param lo_bits Number of bits for the low limb | ||
| * @param skip_range_constraints If true, skip range constraints (use when they're implicit, e.g., in lookups) | ||
| * @return std::pair<field_t<Builder>, field_t<Builder>> The (lo, hi) pair | ||
| */ | ||
| template <typename Builder> | ||
| std::pair<field_t<Builder>, field_t<Builder>> split_unique(const field_t<Builder>& field, | ||
| const size_t lo_bits, | ||
| const bool skip_range_constraints = false); | ||
|
|
||
| /** | ||
| * @brief Validates that lo + hi * 2^lo_bits < field_modulus | ||
| * @details Can be used in conjunction with range constraints on lo and hi to establish a unique decomposition of a | ||
| * field element. | ||
| * | ||
| * @param lo The low limb | ||
| * @param hi The high limb | ||
| * @param lo_bits The bit position at which the split occurred | ||
| * @param field_modulus The field modulus to validate against | ||
| */ | ||
| template <typename Builder> | ||
| void validate_split_in_field(const field_t<Builder>& lo, | ||
| const field_t<Builder>& hi, | ||
| const size_t lo_bits, | ||
| const uint256_t& field_modulus); | ||
|
|
||
| } // namespace bb::stdlib |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No change to number of gates, only the details of constant values due to the use of changing the form of operations like a.assert_equal(b) in a couple places (e.g. using
evaluate_linear_identityinstead)