Skip to content

Commit 1ef20af

Browse files
committed
move subclasses to their own files
1 parent 1bb5871 commit 1ef20af

File tree

8 files changed

+766
-755
lines changed

8 files changed

+766
-755
lines changed

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

Lines changed: 43 additions & 600 deletions
Large diffs are not rendered by default.

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

Lines changed: 28 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
#pragma once
88

9+
#include "./cycle_scalar.hpp"
10+
#include "./straus_lookup_table.hpp"
11+
#include "./straus_scalar_slice.hpp"
912
#include "barretenberg/crypto/pedersen_commitment/pedersen.hpp"
1013
#include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp"
1114
#include "barretenberg/stdlib/primitives/bigfield/bigfield.hpp"
@@ -55,157 +58,9 @@ template <typename Builder> class cycle_group {
5558
// Since the cycle_group base field is the circuit's native field, it can be stored using two public inputs.
5659
static constexpr size_t PUBLIC_INPUTS_SIZE = 2;
5760

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

21065
private:
21166
/**
@@ -276,23 +131,41 @@ template <typename Builder> class cycle_group {
276131
*
277132
* @param tag
278133
*/
279-
void set_origin_tag(OriginTag tag) const;
134+
void set_origin_tag(OriginTag tag) const
135+
{
136+
x.set_origin_tag(tag);
137+
y.set_origin_tag(tag);
138+
_is_infinity.set_origin_tag(tag);
139+
}
280140
/**
281141
* @brief Get the origin tag of cycle_group (a merege of origin tags of x, y and _is_infinity members)
282142
*
283143
* @return OriginTag
284144
*/
285-
OriginTag get_origin_tag() const;
145+
OriginTag get_origin_tag() const
146+
{
147+
return OriginTag(x.get_origin_tag(), y.get_origin_tag(), _is_infinity.get_origin_tag());
148+
}
286149

287150
/**
288151
* @brief Set the free witness flag for the cycle_group's tags
289152
*/
290-
void set_free_witness_tag();
153+
void set_free_witness_tag()
154+
{
155+
x.set_free_witness_tag();
156+
y.set_free_witness_tag();
157+
_is_infinity.set_free_witness_tag();
158+
}
291159

292160
/**
293161
* @brief Unset the free witness flag for the cycle_group's tags
294162
*/
295-
void unset_free_witness_tag();
163+
void unset_free_witness_tag()
164+
{
165+
x.unset_free_witness_tag();
166+
y.unset_free_witness_tag();
167+
_is_infinity.unset_free_witness_tag();
168+
}
296169

297170
/**
298171
* Fix a witness. The value of the witness is constrained with a selector

0 commit comments

Comments
 (0)