Skip to content
This repository was archived by the owner on Feb 17, 2025. It is now read-only.

Commit 9980a34

Browse files
committed
Refactor the part of getting variable value from assignment table.
1 parent 93edae7 commit 9980a34

File tree

7 files changed

+252
-228
lines changed

7 files changed

+252
-228
lines changed

libs/hash/include/nil/crypto3/hash/detail/stream_processors/block_stream_processor.hpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,11 @@ namespace nil {
6666
constexpr static const std::size_t value_bits = ValueBits;
6767
typedef typename boost::uint_t<value_bits>::least value_type;
6868
BOOST_STATIC_ASSERT(word_bits % value_bits == 0);
69+
6970
constexpr static const std::size_t block_values = block_bits / value_bits;
7071
typedef std::array<value_type, block_values> cache_type;
7172

7273
protected:
73-
BOOST_STATIC_ASSERT(block_bits % value_bits == 0);
74-
7574
inline void process_block(std::size_t block_seen = block_bits) {
7675
using namespace nil::crypto3::detail;
7776
// Convert the input into words

libs/zk/include/nil/crypto3/zk/math/expression_evaluator.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ namespace nil {
9595
*/
9696
expression_evaluator(
9797
const math::expression<VariableType>& expr,
98-
std::function<ValueType(const VariableType&)> get_var_value)
98+
std::function<const ValueType&(const VariableType&)> get_var_value)
9999
: expr(expr)
100100
, get_var_value(get_var_value) {
101101
}
@@ -140,7 +140,7 @@ namespace nil {
140140
const math::expression<VariableType>& expr;
141141

142142
// A function used to retrieve the value of a variable.
143-
std::function<ValueType(const VariableType &var)> get_var_value;
143+
std::function<const ValueType&(const VariableType &var)> get_var_value;
144144

145145
};
146146

@@ -207,7 +207,7 @@ namespace nil {
207207
*/
208208
cached_expression_evaluator(
209209
const math::expression<VariableType>& expr,
210-
std::function<ValueType(const VariableType&)> get_var_value)
210+
std::function<const ValueType&(const VariableType&)> get_var_value)
211211
: _expr(expr)
212212
, _get_var_value(get_var_value) {
213213
}
@@ -304,7 +304,7 @@ namespace nil {
304304
const math::expression<VariableType>& _expr;
305305

306306
// A function used to retrieve the value of a variable.
307-
std::function<ValueType(const VariableType &var)> _get_var_value;
307+
std::function<const ValueType&(const VariableType &var)> _get_var_value;
308308

309309
// Shows how many times each subexpression appears. We count have the expression
310310
// itself as a key, but apparently it's waay too slow. Just map the hash->count, assume

libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp

+55
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,14 @@
3232
#include <nil/crypto3/zk/snark/arithmetization/plonk/padding.hpp>
3333
#include <nil/crypto3/random/algebraic_engine.hpp>
3434
#include <nil/crypto3/math/polynomial/polynomial_dfs.hpp>
35+
#include <nil/crypto3/zk/snark/arithmetization/plonk/variable.hpp>
3536

3637
namespace nil {
3738
namespace blueprint {
3839
template<typename ArithmetizationType>
3940
class assignment;
4041
} // namespace blueprint
42+
4143
namespace crypto3 {
4244
namespace zk {
4345
namespace snark {
@@ -55,6 +57,7 @@ namespace nil {
5557
class plonk_private_table {
5658
public:
5759
using witnesses_container_type = std::vector<ColumnType>;
60+
using VariableType = plonk_variable<ColumnType>;
5861

5962
protected:
6063

@@ -82,6 +85,31 @@ namespace nil {
8285
return _witnesses[index].size();
8386
}
8487

88+
const ColumnType& get_variable_value_without_rotation(const VariableType& var) const {
89+
switch (var.type) {
90+
case VariableType::column_type::witness:
91+
return witness(var.index);
92+
case VariableType::column_type::public_input:
93+
return public_input(var.index);
94+
case VariableType::column_type::constant:
95+
return constant(var.index);
96+
case VariableType::column_type::selector:
97+
return selector(var.index);
98+
default:
99+
std::cerr << "Invalid column type" << std::endl;
100+
abort();
101+
}
102+
}
103+
104+
ColumnType get_variable_value(const VariableType& var, std::shared_ptr<math::evaluation_domain<FieldType>> domain) const {
105+
if (var.rotation == 0) {
106+
return get_variable_value_without_rotation(var);
107+
}
108+
return math::polynomial_shift(
109+
this->get_variable_value_without_rotation(var),
110+
var.rotation, domain->m);
111+
}
112+
85113
const ColumnType& witness(std::uint32_t index) const {
86114
assert(index < _witnesses.size());
87115
return _witnesses[index];
@@ -126,6 +154,7 @@ namespace nil {
126154
using public_input_container_type = std::vector<ColumnType>;
127155
using constant_container_type = std::vector<ColumnType>;
128156
using selector_container_type = std::vector<ColumnType>;
157+
using VariableType = plonk_variable<ColumnType>;
129158

130159
protected:
131160

@@ -286,6 +315,7 @@ namespace nil {
286315
using public_input_container_type = typename public_table_type::public_input_container_type;
287316
using constant_container_type = typename public_table_type::constant_container_type;
288317
using selector_container_type = typename public_table_type::selector_container_type;
318+
using VariableType = plonk_variable<ColumnType>;
289319

290320
protected:
291321
// These are normally created by the assigner, or read from a file.
@@ -309,6 +339,31 @@ namespace nil {
309339
, _public_table(public_inputs_amount, constants_amount, selectors_amount) {
310340
}
311341

342+
const ColumnType& get_variable_value_without_rotation(const VariableType& var) const {
343+
switch (var.type) {
344+
case VariableType::column_type::witness:
345+
return witness(var.index);
346+
case VariableType::column_type::public_input:
347+
return public_input(var.index);
348+
case VariableType::column_type::constant:
349+
return constant(var.index);
350+
case VariableType::column_type::selector:
351+
return selector(var.index);
352+
default:
353+
std::cerr << "Invalid column type" << std::endl;
354+
abort();
355+
}
356+
}
357+
358+
ColumnType get_variable_value(const VariableType& var, std::shared_ptr<math::evaluation_domain<FieldType>> domain) const {
359+
if (var.rotation == 0) {
360+
return get_variable_value_without_rotation(var);
361+
}
362+
return math::polynomial_shift(
363+
this->get_variable_value_without_rotation(var),
364+
var.rotation, domain->m);
365+
}
366+
312367
const ColumnType& witness(std::uint32_t index) const {
313368
return _private_table.witness(index);
314369
}

libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint.hpp

+52-60
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ namespace nil {
8888
const plonk_assignment_table<FieldType> &assignments) const {
8989
math::expression_evaluator<VariableType> evaluator(
9090
*this,
91-
[&assignments, row_index](const VariableType &var) {
91+
[&assignments, row_index](const VariableType &var) -> const typename VariableType::assignment_type& {
9292
std::size_t rows_amount = assignments.rows_amount();
9393
switch (var.type) {
9494
case VariableType::column_type::witness:
@@ -100,8 +100,8 @@ namespace nil {
100100
case VariableType::column_type::selector:
101101
return assignments.selector(var.index)[(rows_amount + row_index + var.rotation) % rows_amount];
102102
default:
103-
BOOST_ASSERT_MSG(false, "Invalid column type");
104-
return VariableType::assignment_type::zero();
103+
std::cerr << "Invalid column type" << std::endl;
104+
abort();
105105
}
106106
});
107107

@@ -110,38 +110,33 @@ namespace nil {
110110

111111
math::polynomial<typename VariableType::assignment_type>
112112
evaluate(const plonk_polynomial_table<FieldType> &assignments,
113-
std::shared_ptr<math::evaluation_domain<FieldType>>
114-
domain) const {
115-
using polynomial_type = math::polynomial<typename VariableType::assignment_type>;
116-
using polynomial_variable_type = plonk_variable<polynomial_type>;
117-
math::expression_variable_type_converter<VariableType, polynomial_variable_type> converter;
118-
119-
math::expression_evaluator<polynomial_variable_type> evaluator(
120-
converter.convert(*this),
121-
[&domain, &assignments](const VariableType &var) {
122-
polynomial_type assignment;
123-
switch (var.type) {
124-
case VariableType::column_type::witness:
125-
assignment = assignments.witness(var.index);
126-
break;
127-
case VariableType::column_type::public_input:
128-
assignment = assignments.public_input(var.index);
129-
break;
130-
case VariableType::column_type::constant:
131-
assignment = assignments.constant(var.index);
132-
break;
133-
case VariableType::column_type::selector:
134-
assignment = assignments.selector(var.index);
135-
break;
136-
default:
137-
BOOST_ASSERT_MSG(false, "Invalid column type");
113+
std::shared_ptr<math::evaluation_domain<FieldType>> domain) const {
114+
using polynomial_type = math::polynomial<typename VariableType::assignment_type>;
115+
using polynomial_variable_type = plonk_variable<polynomial_type>;
116+
117+
// Convert scalar values to polynomials inside the expression.
118+
math::expression_variable_type_converter<VariableType, polynomial_variable_type> converter;
119+
auto converted_expression = converter.convert(*this);
120+
121+
// For each variable with a rotation pre-compute its value.
122+
std::unordered_map<polynomial_variable_type, polynomial_type> rotated_variable_values;
123+
124+
math::expression_for_each_variable_visitor<polynomial_variable_type> visitor(
125+
[&rotated_variable_values, &assignments, &domain](const polynomial_variable_type& var) {
126+
if (var.rotation == 0)
127+
return;
128+
rotated_variable_values[var] = assignments.get_variable_value(var, domain);
129+
});
130+
visitor.visit(converted_expression);
131+
132+
math::expression_evaluator<polynomial_variable_type> evaluator(
133+
converted_expression,
134+
[&domain, &assignments, &rotated_variable_values]
135+
(const VariableType &var) -> const polynomial_type& {
136+
if (var.rotation == 0) {
137+
return assignments.get_variable_value_without_rotation(var, domain);
138138
}
139-
140-
if (var.rotation != 0) {
141-
assignment =
142-
math::polynomial_shift(assignment, domain->get_domain_element(var.rotation));
143-
}
144-
return assignment;
139+
return rotated_variable_values[var];
145140
});
146141
return evaluator.evaluate();
147142
}
@@ -152,46 +147,43 @@ namespace nil {
152147
using polynomial_dfs_type = math::polynomial_dfs<typename VariableType::assignment_type>;
153148
using polynomial_dfs_variable_type = plonk_variable<polynomial_dfs_type>;
154149

150+
// Convert scalar values to polynomials inside the expression.
155151
math::expression_variable_type_converter<variable_type, polynomial_dfs_variable_type> converter(
156152
[&assignments](const typename VariableType::assignment_type& coeff) {
157153
polynomial_dfs_type(0, assignments.rows_amount(), coeff);
158154
});
159-
math::expression_evaluator<polynomial_dfs_variable_type> evaluator(
160-
converter.convert(*this),
161-
[&domain, &assignments](const polynomial_dfs_variable_type &var) {
162-
polynomial_dfs_type assignment;
163-
switch (var.type) {
164-
case VariableType::column_type::witness:
165-
assignment = assignments.witness(var.index);
166-
break;
167-
case VariableType::column_type::public_input:
168-
assignment = assignments.public_input(var.index);
169-
break;
170-
case VariableType::column_type::constant:
171-
assignment = assignments.constant(var.index);
172-
break;
173-
case VariableType::column_type::selector:
174-
assignment = assignments.selector(var.index);
175-
break;
176-
default:
177-
BOOST_ASSERT_MSG(false, "Invalid column type");
178-
}
179155

180-
if (var.rotation != 0) {
181-
assignment = math::polynomial_shift(assignment, var.rotation, domain->m);
156+
auto converted_expression = converter.convert(*this);
157+
158+
// For each variable with a rotation pre-compute its value.
159+
std::unordered_map<polynomial_dfs_variable_type, polynomial_dfs_type> rotated_variable_values;
160+
161+
math::expression_for_each_variable_visitor<polynomial_dfs_variable_type> visitor(
162+
[&rotated_variable_values, &assignments, &domain](const polynomial_dfs_variable_type& var) {
163+
if (var.rotation == 0)
164+
return ;
165+
rotated_variable_values[var] = assignments.get_variable_value(var, domain);
166+
});
167+
visitor.visit(converted_expression);
168+
169+
math::expression_evaluator<polynomial_dfs_variable_type> evaluator(
170+
converted_expression,
171+
[&domain, &assignments, &rotated_variable_values]
172+
(const polynomial_dfs_variable_type &var) -> const polynomial_dfs_type& {
173+
if (var.rotation == 0) {
174+
return assignments.get_variable_value_without_rotation(var, domain);
182175
}
183-
return assignment;
176+
return rotated_variable_values[var];
184177
}
185178
);
186179

187180
return evaluator.evaluate();
188181
}
189182

190-
typename VariableType::assignment_type
191-
evaluate(detail::plonk_evaluation_map<VariableType> &assignments) const {
183+
typename VariableType::assignment_type evaluate(detail::plonk_evaluation_map<VariableType> &assignments) const {
192184
math::expression_evaluator<VariableType> evaluator(
193185
*this,
194-
[&assignments](const VariableType &var) {
186+
[&assignments](const VariableType &var) -> const typename VariableType::assignment_type& {
195187
std::tuple<std::size_t, int, typename VariableType::column_type> key =
196188
std::make_tuple(var.index, var.rotation, var.type);
197189

0 commit comments

Comments
 (0)