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

Commit 58647db

Browse files
tshchelovekIluvmagick
authored andcommitted
bit_(de)composition #308
1 parent cffaa2d commit 58647db

File tree

6 files changed

+120
-4
lines changed

6 files changed

+120
-4
lines changed

include/nil/blueprint/components/algebra/fields/plonk/non_native/bit_composition.hpp

+52
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,12 @@ namespace nil {
106106
bits_amount, check_input);
107107
}
108108

109+
constexpr static std::size_t get_empty_rows_amount() {
110+
return 1;
111+
}
112+
109113
const bit_composition_mode mode;
114+
const std::size_t empty_rows_amount = get_empty_rows_amount();
110115

111116
struct input_type {
112117
std::vector<var> bits;
@@ -126,6 +131,9 @@ namespace nil {
126131
auto pos = component.sum_bit_position(start_row_index, component.sum_bits_amount() - 1);
127132
output = var(component.W(pos.second), pos.first, false);
128133
}
134+
result_type(const bit_composition &component, std::uint32_t start_row_index, bool skip) {
135+
output = var(component.W(0), start_row_index, false);
136+
}
129137

130138
std::vector<var> all_vars() const {
131139
return {output};
@@ -164,6 +172,26 @@ namespace nil {
164172

165173
check_params(bits_amount, mode);
166174
};
175+
176+
static typename BlueprintFieldType::value_type calculate(std::vector<bool> input_bits,
177+
bit_composition_mode mode = bit_composition_mode::MSB) {
178+
using field_value_type = typename BlueprintFieldType::value_type;
179+
180+
std::vector<bool> true_input_bits(input_bits.size());
181+
auto bit_index = [&mode, &input_bits](std::size_t i) {
182+
return mode == bit_composition_mode::MSB ? i : input_bits.size() - i - 1;
183+
};
184+
185+
for (std::uint32_t i = 0; i < input_bits.size(); ++i) {
186+
true_input_bits[i] = input_bits[bit_index(i)] != 0 ? true : false;
187+
}
188+
189+
field_value_type sum = 0;
190+
for (std::size_t i = 0; i < true_input_bits.size(); i++) {
191+
sum = 2 * sum + static_cast<bool>(true_input_bits[i]);
192+
}
193+
return sum;
194+
}
167195
};
168196

169197
template<typename BlueprintFieldType, typename ArithmetizationParams>
@@ -198,6 +226,30 @@ namespace nil {
198226
component, start_row_index);
199227
}
200228

229+
template<typename BlueprintFieldType, typename ArithmetizationParams>
230+
typename plonk_bit_composition<BlueprintFieldType, ArithmetizationParams>::result_type
231+
generate_empty_assignments(
232+
const plonk_bit_composition<BlueprintFieldType, ArithmetizationParams>
233+
&component,
234+
assignment<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>>
235+
&assignment,
236+
const typename plonk_bit_composition<BlueprintFieldType, ArithmetizationParams>::input_type
237+
&instance_input,
238+
const std::uint32_t start_row_index) {
239+
using component_type = plonk_bit_composition<BlueprintFieldType, ArithmetizationParams>;
240+
241+
std::vector<bool> input_bits(component.bits_amount);
242+
243+
for (std::uint32_t i = 0; i < component.bits_amount; ++i) {
244+
input_bits[i] = var_value(assignment, instance_input.bits[i]) != 0 ? true : false;
245+
}
246+
247+
assignment.witness(component.W(0), start_row_index) = component_type::calculate(input_bits, component.mode);
248+
249+
return typename plonk_bit_composition<BlueprintFieldType, ArithmetizationParams>::result_type(
250+
component, start_row_index, true);
251+
}
252+
201253
template<typename BlueprintFieldType, typename ArithmetizationParams>
202254
void generate_copy_constraints(
203255
const plonk_bit_composition<BlueprintFieldType, ArithmetizationParams>

include/nil/blueprint/components/algebra/fields/plonk/non_native/bit_decomposition.hpp

+58
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,12 @@ namespace nil {
103103
bits_amount, true);
104104
}
105105

106+
constexpr static std::size_t get_empty_rows_amount(std::size_t bits_amount) {
107+
return bits_amount / 9 + (bits_amount % 9 != 0);
108+
}
109+
106110
const bit_composition_mode mode;
111+
const std::size_t empty_rows_amount = get_empty_rows_amount(this->bits_amount);
107112

108113
struct input_type {
109114
var input;
@@ -129,6 +134,13 @@ namespace nil {
129134
output[i] = var(component.W(pos.second), pos.first, false);
130135
}
131136
}
137+
result_type(const bit_decomposition &component, std::uint32_t start_row_index, bool skip) {
138+
output.resize(component.bits_amount);
139+
140+
for (std::size_t i = 0; i < component.bits_amount; i++) {
141+
output[i] = var(component.W(i % 9), start_row_index + i / 9, false);
142+
}
143+
}
132144

133145
std::vector<var> all_vars() const {
134146
return output;
@@ -167,6 +179,26 @@ namespace nil {
167179

168180
check_params(bits_amount, mode);
169181
};
182+
183+
static std::vector<bool> calculate(typename BlueprintFieldType::value_type input,
184+
std::uint32_t bits_amount, bit_composition_mode mode) {
185+
auto bit_index = [&mode, &bits_amount](std::size_t i) {
186+
return mode == bit_composition_mode::MSB ? i : bits_amount - i - 1;
187+
};
188+
std::vector<bool> bits(bits_amount);
189+
{
190+
nil::marshalling::status_type status;
191+
std::array<bool, BlueprintFieldType::modulus_bits> bytes_all =
192+
nil::marshalling::pack<nil::marshalling::option::big_endian>(input, status);
193+
std::copy(bytes_all.end() - bits_amount, bytes_all.end(), bits.begin());
194+
assert(status == nil::marshalling::status_type::success);
195+
}
196+
std::vector<bool> true_bits(bits_amount);
197+
for (std::size_t i = 0; i < bits_amount; i++) {
198+
true_bits[i] = bits[bit_index(i)];
199+
}
200+
return true_bits;
201+
}
170202
};
171203

172204
template<typename BlueprintFieldType, typename ArithmetizationParams>
@@ -183,6 +215,7 @@ namespace nil {
183215
const typename plonk_bit_decomposition<BlueprintFieldType, ArithmetizationParams>::input_type
184216
&instance_input,
185217
const std::uint32_t start_row_index) {
218+
using component_type = plonk_bit_decomposition<BlueprintFieldType, ArithmetizationParams>;
186219

187220
typename BlueprintFieldType::integral_type input_data =
188221
typename BlueprintFieldType::integral_type(var_value(assignment, instance_input.input).data);
@@ -204,6 +237,31 @@ namespace nil {
204237
component, start_row_index);
205238
}
206239

240+
template<typename BlueprintFieldType, typename ArithmetizationParams>
241+
typename plonk_bit_decomposition<BlueprintFieldType, ArithmetizationParams>::result_type
242+
generate_empty_assignments(
243+
const plonk_bit_decomposition<BlueprintFieldType, ArithmetizationParams>
244+
&component,
245+
assignment<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>>
246+
&assignment,
247+
const typename plonk_bit_decomposition<BlueprintFieldType, ArithmetizationParams>::input_type
248+
&instance_input,
249+
const std::uint32_t start_row_index) {
250+
using component_type = plonk_bit_decomposition<BlueprintFieldType, ArithmetizationParams>;
251+
using value_type = typename BlueprintFieldType::value_type;
252+
253+
value_type input_data = var_value(assignment, instance_input.input);
254+
255+
std::vector<bool> bits = component_type::calculate(input_data, component.bits_amount, component.mode);
256+
257+
for (std::size_t i = 0; i < component.bits_amount; i++) {
258+
assignment.witness(component.W(i % 9), start_row_index + i / 9) = value_type(bits[i] ? 1 : 0);
259+
}
260+
261+
return typename plonk_bit_decomposition<BlueprintFieldType, ArithmetizationParams>::result_type(
262+
component, start_row_index, true);
263+
}
264+
207265
template<typename BlueprintFieldType, typename ArithmetizationParams>
208266
void generate_copy_constraints(
209267
const plonk_bit_decomposition<BlueprintFieldType, ArithmetizationParams>

include/nil/blueprint/components/algebra/fields/plonk/non_native/detail/bit_builder_component.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ namespace nil {
4444
namespace detail {
4545
/*
4646
This is a component base, which is used for both bit_decomposition and
47-
bit_builder_component components, as they are similar.
47+
bit_composition components, as they are similar.
4848
4949
Only the case of bits_amount < BlueprintFieldType::modulus_bits is supported.
5050

test/algebra/fields/plonk/non_native/bit_composition.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ void test_bit_composition(const std::vector<typename BlueprintFieldType::value_t
108108
crypto3::test_component<component_type, BlueprintFieldType, ArithmetizationParams, hash_type, Lambda>(
109109
component_instance, bits, result_check, instance_input,
110110
crypto3::detail::connectedness_check_type::STRONG, BitsAmount, CheckInput);
111+
crypto3::test_empty_component<component_type, BlueprintFieldType, ArithmetizationParams, hash_type, Lambda>(
112+
component_instance, bits, result_check, instance_input,
113+
crypto3::detail::connectedness_check_type::STRONG, BitsAmount, CheckInput);
111114
} else {
112115
crypto3::test_component_to_fail<component_type, BlueprintFieldType, ArithmetizationParams, hash_type, Lambda>(
113116
component_instance, bits, result_check, instance_input,

test/algebra/fields/plonk/non_native/bit_decomposition.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ void test_bit_decomposition(typename BlueprintFieldType::value_type input,
112112
crypto3::test_component<component_type, BlueprintFieldType, ArithmetizationParams, hash_type, Lambda>(
113113
component_instance, public_input, result_check, instance_input,
114114
crypto3::detail::connectedness_check_type::STRONG, BitsAmount);
115+
crypto3::test_empty_component<component_type, BlueprintFieldType, ArithmetizationParams, hash_type, Lambda>(
116+
component_instance, public_input, result_check, instance_input,
117+
crypto3::detail::connectedness_check_type::STRONG, BitsAmount);
115118
} else {
116119
crypto3::test_component_to_fail<component_type, BlueprintFieldType, ArithmetizationParams, hash_type, Lambda>(
117120
component_instance, public_input, result_check, instance_input,

test/test_plonk_component.hpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -350,13 +350,13 @@ namespace nil {
350350
auto component_result = boost::get<typename component_type::result_type>(
351351
blueprint::components::generate_empty_assignments<BlueprintFieldType, ArithmetizationParams>(
352352
component_instance, assignment, instance_input, start_row));
353-
assignment.export_table(std::cout);
354-
bp.export_circuit(std::cout);
353+
// assignment.export_table(std::cout);
354+
// bp.export_circuit(std::cout);
355355
result_check(assignment, component_result);
356356

357357
zk::snark::plonk_table_description<BlueprintFieldType, ArithmetizationParams> desc;
358358
desc.usable_rows_amount = assignment.rows_amount();
359-
359+
360360
if (start_row + component_instance.empty_rows_amount >= public_input.size()) {
361361
BOOST_ASSERT_MSG(assignment.rows_amount() - start_row == component_instance.empty_rows_amount,
362362
"Component rows amount does not match actual rows amount.");

0 commit comments

Comments
 (0)