Skip to content

Commit 5ab003f

Browse files
authored
feat: merge-train/barretenberg (#16672)
BEGIN_COMMIT_OVERRIDE chore: preliminary clean up and reorg of cycle_group (#16645) END_COMMIT_OVERRIDE
2 parents 2841e2b + 2f3f861 commit 5ab003f

File tree

8 files changed

+860
-862
lines changed

8 files changed

+860
-862
lines changed

barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.cpp

Lines changed: 1 addition & 700 deletions
Large diffs are not rendered by default.

barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.hpp

Lines changed: 6 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include "barretenberg/stdlib/primitives/bool/bool.hpp"
1313
#include "barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp"
1414
#include "barretenberg/stdlib/primitives/field/field.hpp"
15+
#include "barretenberg/stdlib/primitives/group/cycle_scalar.hpp"
16+
#include "barretenberg/stdlib/primitives/group/straus_lookup_table.hpp"
17+
#include "barretenberg/stdlib/primitives/group/straus_scalar_slice.hpp"
1518
#include "barretenberg/stdlib_circuit_builders/plookup_tables/fixed_base/fixed_base_params.hpp"
1619
#include "barretenberg/transcript/origin_tag.hpp"
1720
#include <optional>
@@ -20,8 +23,6 @@ namespace bb::stdlib {
2023

2124
template <typename Builder>
2225
concept IsUltraArithmetic = (Builder::CIRCUIT_TYPE == CircuitType::ULTRA);
23-
template <typename Builder>
24-
concept IsNotUltraArithmetic = (Builder::CIRCUIT_TYPE != CircuitType::ULTRA);
2526

2627
/**
2728
* @brief cycle_group represents a group Element of the proving system's embedded curve
@@ -57,157 +58,9 @@ template <typename Builder> class cycle_group {
5758
// Since the cycle_group base field is the circuit's native field, it can be stored using two public inputs.
5859
static constexpr size_t PUBLIC_INPUTS_SIZE = 2;
5960

60-
private:
61-
public:
62-
/**
63-
* @brief cycle_scalar represents a member of the cycle curve SCALAR FIELD.
64-
* This is NOT the native circuit field type.
65-
* i.e. for a BN254 circuit, cycle_group will be Grumpkin and cycle_scalar will be Grumpkin::ScalarField
66-
* (BN254 native field is BN254::ScalarField == Grumpkin::BaseField)
67-
*
68-
* @details We convert scalar multiplication inputs into cycle_scalars to enable scalar multiplication to be
69-
* *complete* i.e. Grumpkin points multiplied by BN254 scalars does not produce a cyclic group
70-
* as BN254::ScalarField < Grumpkin::ScalarField
71-
* This complexity *should* not leak outside the cycle_group / cycle_scalar implementations, as cycle_scalar
72-
* performs all required conversions if the input scalars are stdlib::field_t elements
73-
*
74-
* @note We opted to create a new class to represent `cycle_scalar` instead of using `bigfield`,
75-
* as `bigfield` is inefficient in this context. All required range checks for `cycle_scalar` can be obtained for
76-
* free from the `batch_mul` algorithm, making the range checks performed by `bigfield` largely redundant.
77-
*/
78-
struct cycle_scalar {
79-
static constexpr size_t LO_BITS = field_t::native::Params::MAX_BITS_PER_ENDOMORPHISM_SCALAR;
80-
static constexpr size_t HI_BITS = NUM_BITS - LO_BITS;
81-
field_t lo;
82-
field_t hi;
83-
84-
private:
85-
size_t _num_bits = NUM_BITS;
86-
bool _skip_primality_test = false;
87-
// if our scalar multiplier is a bn254 FF scalar (e.g. pedersen hash),
88-
// we want to validate the cycle_scalar < bn254::fr::modulus *not* grumpkin::fr::modulus
89-
bool _use_bn254_scalar_field_for_primality_test = false;
90-
91-
public:
92-
cycle_scalar(const field_t& _lo,
93-
const field_t& _hi,
94-
const size_t bits,
95-
const bool skip_primality_test,
96-
const bool use_bn254_scalar_field_for_primality_test)
97-
: lo(_lo)
98-
, hi(_hi)
99-
, _num_bits(bits)
100-
, _skip_primality_test(skip_primality_test)
101-
, _use_bn254_scalar_field_for_primality_test(use_bn254_scalar_field_for_primality_test) {};
102-
cycle_scalar(const ScalarField& _in = 0);
103-
cycle_scalar(const field_t& _lo, const field_t& _hi);
104-
cycle_scalar(const field_t& _in);
105-
static cycle_scalar from_witness(Builder* context, const ScalarField& value);
106-
static cycle_scalar from_witness_bitstring(Builder* context, const uint256_t& bitstring, size_t num_bits);
107-
static cycle_scalar create_from_bn254_scalar(const field_t& _in, bool skip_primality_test = false);
108-
[[nodiscard]] bool is_constant() const;
109-
ScalarField get_value() const;
110-
Builder* get_context() const { return lo.get_context() != nullptr ? lo.get_context() : hi.get_context(); }
111-
[[nodiscard]] size_t num_bits() const { return _num_bits; }
112-
[[nodiscard]] bool skip_primality_test() const { return _skip_primality_test; }
113-
[[nodiscard]] bool use_bn254_scalar_field_for_primality_test() const
114-
{
115-
return _use_bn254_scalar_field_for_primality_test;
116-
}
117-
void validate_scalar_is_in_field() const;
118-
119-
explicit cycle_scalar(BigScalarField&);
120-
/**
121-
* @brief Get the origin tag of the cycle_scalar (a merge of the lo and hi tags)
122-
*
123-
* @return OriginTag
124-
*/
125-
OriginTag get_origin_tag() const { return OriginTag(lo.get_origin_tag(), hi.get_origin_tag()); }
126-
/**
127-
* @brief Set the origin tag of lo and hi members of cycle scalar
128-
*
129-
* @param tag
130-
*/
131-
void set_origin_tag(const OriginTag& tag) const
132-
{
133-
lo.set_origin_tag(tag);
134-
hi.set_origin_tag(tag);
135-
}
136-
/**
137-
* @brief Set the free witness flag for the cycle scalar's tags
138-
*/
139-
void set_free_witness_tag()
140-
{
141-
lo.set_free_witness_tag();
142-
hi.set_free_witness_tag();
143-
}
144-
/**
145-
* @brief Unset the free witness flag for the cycle scalar's tags
146-
*/
147-
void unset_free_witness_tag()
148-
{
149-
lo.unset_free_witness_tag();
150-
hi.unset_free_witness_tag();
151-
}
152-
};
153-
154-
/**
155-
* @brief straus_scalar_slice decomposes an input scalar into `table_bits` bit-slices.
156-
* Used in `batch_mul`, which ses the Straus multiscalar multiplication algorithm.
157-
*
158-
*/
159-
struct straus_scalar_slice {
160-
straus_scalar_slice(Builder* context, const cycle_scalar& scalars, size_t table_bits);
161-
std::optional<field_t> read(size_t index);
162-
size_t _table_bits;
163-
std::vector<field_t> slices;
164-
std::vector<uint64_t> slices_native;
165-
};
166-
167-
/**
168-
* @brief straus_lookup_table computes a lookup table of size 1 << table_bits
169-
*
170-
* @details for an input base_point [P] and offset_generator point [G], where N = 1 << table_bits, the following is
171-
* computed:
172-
*
173-
* { [G] + 0.[P], [G] + 1.[P], ..., [G] + (N - 1).[P] }
174-
*
175-
* The point [G] is used to ensure that we do not have to handle the point at infinity associated with 0.[P].
176-
*
177-
* For an HONEST Prover, the probability of [G] and [P] colliding is equivalent to solving the dlog problem.
178-
* This allows us to partially ignore the incomplete addition formula edge-cases for short Weierstrass curves.
179-
*
180-
* When adding group elements in `batch_mul`, we can constrain+assert the x-coordinates of the operand points do not
181-
* match. An honest prover will never trigger the case where x-coordinates match due to the above. Validating
182-
* x-coordinates do not match is much cheaper than evaluating the full complete addition formulae for short
183-
* Weierstrass curves.
184-
*
185-
* @note For the case of fixed-base scalar multipliation, all input points are defined at circuit compile.
186-
* We can ensure that all Provers cannot create point collisions between the base points and offset generators.
187-
* For this restricted case we can skip the x-coordiante collision checks when performing group operations.
188-
*
189-
* @note straus_lookup_table uses Ultra ROM tables if available. If not, we use simple conditional assignment
190-
* constraints and restrict the table size to be 1 bit.
191-
*/
192-
struct straus_lookup_table {
193-
public:
194-
static std::vector<Element> compute_straus_lookup_table_hints(const Element& base_point,
195-
const Element& offset_generator,
196-
size_t table_bits);
197-
198-
straus_lookup_table() = default;
199-
straus_lookup_table(Builder* context,
200-
const cycle_group& base_point,
201-
const cycle_group& offset_generator,
202-
size_t table_bits,
203-
std::optional<std::span<AffineElement>> hints = std::nullopt);
204-
cycle_group read(const field_t& index);
205-
size_t _table_bits;
206-
Builder* _context;
207-
std::vector<cycle_group> point_table;
208-
size_t rom_id = 0;
209-
OriginTag tag{};
210-
};
61+
using cycle_scalar = ::bb::stdlib::cycle_scalar<Builder>;
62+
using straus_lookup_table = ::bb::stdlib::straus_lookup_table<Builder>;
63+
using straus_scalar_slice = ::bb::stdlib::straus_scalar_slice<Builder>;
21164

21265
private:
21366
/**
@@ -239,14 +92,9 @@ template <typename Builder> class cycle_group {
23992
void validate_is_on_curve() const;
24093
cycle_group dbl(const std::optional<AffineElement> hint = std::nullopt) const
24194
requires IsUltraArithmetic<Builder>;
242-
cycle_group dbl(const std::optional<AffineElement> hint = std::nullopt) const
243-
requires IsNotUltraArithmetic<Builder>;
24495
cycle_group unconditional_add(const cycle_group& other,
24596
const std::optional<AffineElement> hint = std::nullopt) const
24697
requires IsUltraArithmetic<Builder>;
247-
cycle_group unconditional_add(const cycle_group& other,
248-
const std::optional<AffineElement> hint = std::nullopt) const
249-
requires IsNotUltraArithmetic<Builder>;
25098
cycle_group unconditional_subtract(const cycle_group& other,
25199
const std::optional<AffineElement> hint = std::nullopt) const;
252100
cycle_group checked_unconditional_add(const cycle_group& other,
@@ -384,10 +232,6 @@ template <typename Builder> class cycle_group {
384232
std::span<AffineElement> base_points,
385233
std::span<AffineElement const> offset_generators)
386234
requires IsUltraArithmetic<Builder>;
387-
static batch_mul_internal_output _fixed_base_batch_mul_internal(std::span<cycle_scalar> scalars,
388-
std::span<AffineElement> base_points,
389-
std::span<AffineElement const> offset_generators)
390-
requires IsNotUltraArithmetic<Builder>;
391235
};
392236

393237
template <typename Builder> inline std::ostream& operator<<(std::ostream& os, cycle_group<Builder> const& v)

0 commit comments

Comments
 (0)