Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
straus_scalar_slice.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
8#include "./cycle_scalar.hpp"
12
13namespace bb::stdlib {
14
27template <typename Builder>
29 Builder* context, const field_t& scalar, const size_t num_bits, const size_t table_bits)
30{
32 const size_t num_slices = numeric::ceil_div(num_bits, table_bits);
33
34 // We record the scalar slices both as field_t circuit elements and u64 values. (u64 values are used to index
35 // arrays and we don't want to repeatedly cast a stdlib value to a numeric primitive as this gets expensive when
36 // done repeatedly)
37 std::vector<field_ct> stdlib_slices;
38 std::vector<uint64_t> native_slices;
39 stdlib_slices.reserve(num_slices);
40 native_slices.reserve(num_slices);
41
42 if (num_bits == 0) {
43 return { stdlib_slices, native_slices };
44 }
45 // Case 1: If the scalar is constant, compute the slices natively
46 if (scalar.is_constant()) {
47 const uint64_t table_mask = (1ULL << table_bits) - 1ULL;
48 uint256_t raw_value = scalar.get_value();
49 for (size_t i = 0; i < num_slices; ++i) {
50 uint64_t slice_value = static_cast<uint64_t>(raw_value.data[0]) & table_mask;
51 stdlib_slices.push_back(field_ct(slice_value)); // constants equal to slice_value
52 native_slices.push_back(slice_value);
53 raw_value = raw_value >> table_bits;
54 }
55 return { stdlib_slices, native_slices };
56 }
57
58 // Case 2: If the scalar is non-constant, perform the decomposition in-circuit
59 const auto slice_indices = context->decompose_into_default_range(
60 scalar.get_witness_index(), num_bits, table_bits, "straus_scalar_slice decompose_into_default_range");
61 for (auto const& idx : slice_indices) {
63 stdlib_slices.push_back(slice);
64 native_slices.push_back(static_cast<uint64_t>(slice.get_value()));
65 }
66 return { stdlib_slices, native_slices };
67}
68
78template <typename Builder>
80 const cycle_scalar<Builder>& scalar,
81 const size_t table_bits)
82 : _table_bits(table_bits)
83{
84 constexpr size_t lo_bits = cycle_scalar<Builder>::LO_BITS;
85 constexpr size_t hi_bits = cycle_scalar<Builder>::HI_BITS;
86 auto hi_slices = compute_scalar_slices(context, scalar.hi(), hi_bits, table_bits);
87 auto lo_slices = compute_scalar_slices(context, scalar.lo(), lo_bits, table_bits);
88
89 std::copy(lo_slices.first.begin(), lo_slices.first.end(), std::back_inserter(slices));
90 std::copy(hi_slices.first.begin(), hi_slices.first.end(), std::back_inserter(slices));
91 std::copy(lo_slices.second.begin(), lo_slices.second.end(), std::back_inserter(slices_native));
92 std::copy(hi_slices.second.begin(), hi_slices.second.end(), std::back_inserter(slices_native));
93
94 const auto tag = scalar.get_origin_tag();
95 for (auto& element : slices) {
96 // All slices need to have the same origin tag
97 element.set_origin_tag(tag);
98 }
99}
100
111{
112 BB_ASSERT_LT(index, slices.size(), "Straus scalar slice index out of bounds!");
113 return slices[index];
114}
115
118
119} // namespace bb::stdlib
#define BB_ASSERT_LT(left, right,...)
Definition assert.hpp:137
Represents a member of the Grumpkin curve scalar field (i.e. BN254 base field).
const field_t & hi() const
const field_t & lo() const
OriginTag get_origin_tag() const
Get the origin tag of the cycle_scalar (a merge of the lo and hi tags)
static field_t from_witness_index(Builder *ctx, uint32_t witness_index)
Definition field.cpp:62
bb::fr get_value() const
Given a := *this, compute its value given by a.v * a.mul + a.add.
Definition field.cpp:828
bool is_constant() const
Definition field.hpp:429
uint32_t get_witness_index() const
Get the witness index of the current field element.
Definition field.hpp:506
straus_scalar_slices decomposes an input scalar into bit-slices of size table_bits....
static std::pair< std::vector< field_t >, std::vector< uint64_t > > compute_scalar_slices(Builder *context, const field_t &scalar, size_t num_bits, size_t table_bits)
Convert an input cycle_scalar field element into a vector of bit-slices.
field_t operator[](size_t index)
Return a bit-slice associated with round index.
straus_scalar_slices(Builder *context, const cycle_scalar< Builder > &scalars, size_t table_bits)
Construct straus_scalar_slices from an input cycle_scalar and specified table_bits.
StrictMock< MockContext > context
stdlib::field_t< Builder > field_ct
constexpr T ceil_div(const T &numerator, const T &denominator)
Computes the ceiling of the division of two integral types.
Definition general.hpp:23
std::conditional_t< IsGoblinBigGroup< C, Fq, Fr, G >, element_goblin::goblin_element< C, goblin_field< C >, Fr, G >, element_default::element< C, Fq, Fr, G > > element
element wraps either element_default::element or element_goblin::goblin_element depending on parametr...
Definition biggroup.hpp:995
C slice(C const &container, size_t start)
Definition container.hpp:9
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13