Skip to content

Commit

Permalink
Colinear checks #335
Browse files Browse the repository at this point in the history
  • Loading branch information
ETatuzova authored and Iluvmagick committed Apr 2, 2024
1 parent 7a12a5d commit 41abe68
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,9 @@ namespace nil {
std::vector<var> ys; // array of pairs of elements r+1 pairs
std::vector<var> bs; // array of r+1 signs
std::vector<var> alphas; // array size r
std::size_t r;

input_type(std::size_t r){
ys.reserve(2*r+2);
bs.reserve(r+1);
alphas.reserve(r);
}

std::vector<std::reference_wrapper<var>> all_vars() {
Expand Down Expand Up @@ -135,14 +133,14 @@ namespace nil {
};

template<typename ContainerType>
explicit flexible_colinear_checks(ContainerType witness, std::size_t _r, value_type _omega) :
explicit flexible_colinear_checks(ContainerType witness, std::size_t _r) :
component_type(witness, {}, {}, get_manifest()),
r(_r) {};

template<typename WitnessContainerType, typename ConstantContainerType,
typename PublicInputContainerType>
flexible_colinear_checks(WitnessContainerType witness, ConstantContainerType constant,
PublicInputContainerType public_input, std::size_t _r, value_type _omega) :
PublicInputContainerType public_input, std::size_t _r) :
component_type(witness, constant, public_input, get_manifest()),
r(_r) {};

Expand All @@ -152,7 +150,7 @@ namespace nil {
constants,
std::initializer_list<typename component_type::public_input_container_type::value_type>
public_inputs,
std::size_t _r, value_type _omega) :
std::size_t _r) :
component_type(witnesses, constants, public_inputs, get_manifest()),
r(_r) {};
};
Expand Down Expand Up @@ -186,40 +184,55 @@ namespace nil {

std::size_t cur = 0;
value_type x = var_value(assignment, instance_input.x);
value_type cur_val = 1;
for (std::size_t row = 0, pair_index = 0; row < rows_amount; row++) {
std::size_t block = 0;
for (; block < (witness_amount-4)/5; block++) {
if (cur < component.r){
value_type b = var_value(assignment, instance_input.vs[2*cur]);
value_type b = var_value(assignment, instance_input.bs[cur]);
value_type y0_val = var_value(assignment, instance_input.ys[2*cur]);
value_type y1_val = var_value(assignment, instance_input.ys[2*cur+1]);
value_type alpha_val = var_value(assignment, instance_input.alphas[cur]);
value_type alpha = var_value(assignment, instance_input.alphas[cur]);

value_type s = 2 * b * x - x;
value_type interpolant = ((alpha + s ) * y0_val - (alpha - s) * y1_val ) / (2 * s);
// std::cout << "Interpolant " << cur << " index " << b << ":";
// for( std::size_t k = 0; k < instance_input.bs.size(); k++) {
// std::cout << var_value(assignment, instance_input.bs[k]) << " ";
// }
// std::cout << std::endl << interpolant << std::endl;

assignment.witness(component.W(block*5), start_row_index + row) = x;
assignment.witness(component.W(block*5+2), start_row_index + row) = cur_val;
assignment.witness(component.W(block*5+3), start_row_index + row) = y0_val;
assignment.witness(component.W(block*5+1), start_row_index + row) = b;
assignment.witness(component.W(block*5+2), start_row_index + row) = y0_val;
assignment.witness(component.W(block*5+3), start_row_index + row) = y1_val;
assignment.witness(component.W(block*5+3), start_row_index + row) = alpha_val;
cur_val = cur_val * cur_val * ((1-b) + b*component.omega);
x = x * x;
assignment.witness(component.W(block*5+4), start_row_index + row) = alpha;
cur++;
x = x * x;
y0_val = var_value(assignment, instance_input.ys[2*cur]);
y1_val = var_value(assignment, instance_input.ys[2*cur+1]);
value_type b_val = var_value(assignment, instance_input.bs[cur]);
//std::cout << b_val * y0_val + (1 - b_val) * y1_val << std::endl;
assignment.witness(component.W(block*5 + 5), start_row_index + row) = x;
assignment.witness(component.W(block*5 + 6), start_row_index + row) = b_val;
assignment.witness(component.W(block*5 + 7), start_row_index + row) = y0_val;
assignment.witness(component.W(block*5 + 8), start_row_index + row) = y1_val;
} else {
// Think carefully!
// Fill it with something to prevent new gate from being added
/* assignment.witness(component.W(block*5), start_row_index + row) = 0;
assignment.witness(component.W(block*5 + 1), start_row_index + row) = 0;
assignment.witness(component.W(block*5 + 2), start_row_index + row) = 0;
assignment.witness(component.W(block*5 + 3), start_row_index + row) = 0;
assignment.witness(component.W(block*5 + 4), start_row_index + row) = 0;*/
value_type x = assignment.witness(component.W(block * 5), start_row_index + row);
value_type b = assignment.witness(component.W(block * 5 + 1), start_row_index + row);
value_type y0 = assignment.witness(component.W(block * 5 + 2), start_row_index + row);
value_type y1 = assignment.witness(component.W(block * 5 + 3), start_row_index + row);
value_type alpha = 0;

value_type s = 2 * b * x - x;

assignment.witness(component.W(block*5 + 4), start_row_index + row) = 0; // fake alpha
assignment.witness(component.W(block*5 + 5), start_row_index + row) = x*x; // new fake x
assignment.witness(component.W(block*5 + 6), start_row_index + row) = 0; // new fake b
assignment.witness(component.W(block*5 + 7), start_row_index + row) = 0; // new fake b = 0 so, it doesn't matter
assignment.witness(component.W(block*5 + 8), start_row_index + row) = ((alpha + s ) * y0 - (alpha - s) * y1 ) / (2 * s); // new fake y
x = x * x;
}
value_type y0_val = var_value(assignment, instance_input.ys[2*cur]);
value_type y1_val = var_value(assignment, instance_input.ys[2*cur+1]);
value_type b_val = var_value(assignment, instance_input.bs[cur]);
assignment.witness(component.W(block*5), start_row_index + row) = b_val;
assignment.witness(component.W(block*5 + 1), start_row_index + row) = y0_val;
assignment.witness(component.W(block*5 + 2), start_row_index + row) = y1_val;
assignment.witness(component.W(block*5 + 3), start_row_index + row) = x;
}
}

Expand All @@ -239,20 +252,29 @@ namespace nil {
using var = typename component_type::var;
using constraint_type = crypto3::zk::snark::plonk_constraint<BlueprintFieldType>;

// BOOST_ASSERT(component.n == instance_input.arr.size());

std::vector<constraint_type> constraints;
/* constraints.reserve(component.n);
var t = var(component.W(0), 0, true);
const std::size_t witness_amount = component.witness_amount();
for( std::size_t block = 0; block < witness_amount/3; block++ ) {
var input_a_var = var(component.W(block * 3), 0, true),
input_b_var = var(component.W(block * 3 + 1), 0, true),
output_var = var(component.W(block * 3 + 2), 0, true);
constraints.emplace_back(input_a_var + input_b_var - output_var);
for( std::size_t block = 0; block < (witness_amount-4)/5; block++ ) {
if( block == 0) continue;
var x = var(component.W(block*5), 0, true);
var b = var(component.W(block*5+1), 0, true);
var y0_var = var(component.W(block * 5+2), 0, true);
var y1_var = var(component.W(block * 5+3), 0, true);
var alpha = var(component.W(block * 5+4), 0, true);

auto s = 2 * b * x - x;
auto left = ((alpha + s ) * y0_var - (alpha - s) * y1_var );// / (2 * s);
auto y1 = y1_var * b + (1-b) * y0_var;

var x_next = var(component.W(block * 5 + 5), 0, true);
var b_next = var(component.W(block * 5 + 6), 0, true);
var y0_next = var(component.W(block * 5 + 7), 0, true);
var y1_next = var(component.W(block * 5 + 8), 0, true);

auto right = (b_next * y0_next + (1 - b_next) * y1_next) * 2 * s;

constraints.emplace_back(left - right);
}
*/
return bp.add_gate(constraints);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ namespace nil {
num_gates += constant_pow_gates;
std::cout << "X-index gates " << 1 << std::endl;
num_gates += 1;
// std::cout << "Colinear checks component gate " << 1 << std::endl;
std::cout << "Colinear checks component gate " << 1 << std::endl;
num_gates += 1;
}
std::uint32_t gates_amount() const override {
std::cout << "Verifier gates_amount " << num_gates << std::endl;
Expand Down Expand Up @@ -371,35 +372,6 @@ namespace nil {
component.all_witnesses(), std::array<std::uint32_t, 1>({component.C(0)}), std::array<std::uint32_t, 0>(),
component.fri_initial_merkle_proof_size, component.fri_omega
);
std::cout << "Check table values" << std::endl;
// colinear_checks_component_type colinear_checks_instance(component.fri_params_r); // Fix after 1st round will be ready
// colinear_checks_input.ys[0] = zero_var;
// colinear_checks_input.ys[1] = zero_var;
for( std::size_t i = 0; i < component.fri_params_lambda; i++){
// typename colinear_checks_component_type::input_type colinear_checks_input;
// colinear_checks_input.x = xs[i];
// for( std::size j = 0; j < component.fri_params_r; j++){
// colinear_checks_input.ys[2*j + 2] = instance_input.round_proof_values[i][2*j];
// colinear_checks_input.ys[2*j + 3] = instance_input.round_proof_values[i][2*j + 1];
// colinear_checks_input.alphas[j-1] = challenges.fri_alphas[j];
// }
// Just check x_index and merkle proof correspondense
std::size_t x_index = 0;
std::size_t factor = 1;
for( std::size_t j = 0; j < instance_input.merkle_tree_positions[i].size(); j++){
std::cout << var_value(assignment, instance_input.merkle_tree_positions[i][j]) << " ";
if( var_value(assignment, instance_input.merkle_tree_positions[i][j]) == 0 ) x_index += factor;
factor *= 2;
}
std::cout << " => " << x_index << std::endl;
auto fri_omega = component.fri_omega;
auto fri_domain_size = component.fri_domain_size;
std::cout << fri_omega << std::endl;
std::cout << x_index << " => " << fri_omega.pow(x_index) << std::endl;
std::cout << x_index + fri_domain_size/2 << " => " << -fri_omega.pow(x_index) << std::endl;
std::cout << var_value(assignment, challenges.fri_xs[i]).pow((BlueprintFieldType::modulus-1)/fri_domain_size) << std::endl;
}

for( std::size_t i = 0; i < component.fri_params_lambda; i++){
typename x_index_component_type::input_type x_index_input;
x_index_input.x = xs[i];
Expand All @@ -412,6 +384,28 @@ namespace nil {
row += x_index_instance.rows_amount;
}

colinear_checks_component_type colinear_checks_instance(
component.all_witnesses(), std::array<std::uint32_t, 1>({component.C(0)}),
std::array<std::uint32_t, 0>(), component.fri_params_r
);
for( std::size_t i = 0; i < component.fri_params_lambda; i++){
typename colinear_checks_component_type::input_type colinear_checks_input(component.fri_params_r);
colinear_checks_input.x = xs[i];
colinear_checks_input.ys.push_back(zero_var); // Fix after 1st round will be ready
colinear_checks_input.ys.push_back(zero_var); // Fix after 1st round will be ready
colinear_checks_input.bs.push_back(zero_var); // Set it to x_index component output
for( std::size_t j = 0; j < component.fri_params_r; j++){
colinear_checks_input.ys.push_back(instance_input.round_proof_values[i][2*j]);
colinear_checks_input.ys.push_back(instance_input.round_proof_values[i][2*j + 1]);
colinear_checks_input.alphas.push_back(challenges.fri_alphas[j]);
colinear_checks_input.bs.push_back(instance_input.merkle_tree_positions[i][instance_input.merkle_tree_positions[i].size() - j - 1]);
}
typename colinear_checks_component_type::result_type colinear_checks_output = generate_assignments(
colinear_checks_instance, assignment, colinear_checks_input, row
);
row += colinear_checks_instance.rows_amount;
}


// Query proof check
// Construct Merkle leaves
Expand Down Expand Up @@ -514,6 +508,7 @@ namespace nil {
using swap_input_type = typename swap_component_type::input_type;
using constant_pow_component_type = typename component_type::constant_pow_component_type;
using x_index_component_type = typename component_type::x_index_component_type;
using colinear_checks_component_type = typename component_type::colinear_checks_component_type;
typename component_type::challenges challenges;

std::size_t row = start_row_index;
Expand Down Expand Up @@ -624,6 +619,28 @@ namespace nil {
row += x_index_instance.rows_amount;
}

colinear_checks_component_type colinear_checks_instance(
component.all_witnesses(), std::array<std::uint32_t, 1>({component.C(0)}),
std::array<std::uint32_t, 0>(), component.fri_params_r
);
for( std::size_t i = 0; i < component.fri_params_lambda; i++){
typename colinear_checks_component_type::input_type colinear_checks_input(component.fri_params_r);
colinear_checks_input.x = xs[i];
colinear_checks_input.ys.push_back(zero_var); // Fix after 1st round will be ready
colinear_checks_input.ys.push_back(zero_var); // Fix after 1st round will be ready
colinear_checks_input.bs.push_back(zero_var); // Set it to x_index component output
for( std::size_t j = 0; j < component.fri_params_r; j++){
colinear_checks_input.ys.push_back(instance_input.round_proof_values[i][2*j]);
colinear_checks_input.ys.push_back(instance_input.round_proof_values[i][2*j + 1]);
colinear_checks_input.alphas.push_back(challenges.fri_alphas[j]);
colinear_checks_input.bs.push_back(instance_input.merkle_tree_positions[i][instance_input.merkle_tree_positions[i].size() - j - 1]);
}
typename colinear_checks_component_type::result_type colinear_checks_output = generate_circuit(
colinear_checks_instance, bp, assignment, colinear_checks_input, row
);
row += colinear_checks_instance.rows_amount;
}

// Query proof check
for( std::size_t i = 0; i < component.fri_params_lambda; i++){
std::cout << "Query proof " << i << std::endl;
Expand Down

0 comments on commit 41abe68

Please sign in to comment.