diff --git a/include/nil/blueprint/transpiler/recursive_verifier_generator.hpp b/include/nil/blueprint/transpiler/recursive_verifier_generator.hpp index 1511aa6..b44dc4b 100644 --- a/include/nil/blueprint/transpiler/recursive_verifier_generator.hpp +++ b/include/nil/blueprint/transpiler/recursive_verifier_generator.hpp @@ -254,74 +254,90 @@ namespace nil { out << "\t\t{\"array\": [" << std::endl; std::size_t cur = 0; for( std::size_t i = 0; i < eval_proof.fri_proof.query_proofs.size(); i++){ + if(i != 0) out << "," << std::endl; + out << "\t\t\t{\"array\": [" << std::endl; + cur = 0; for( std::size_t j = 0; j < eval_proof.fri_proof.query_proofs[i].round_proofs.size(); j++){ const auto &round_proof = eval_proof.fri_proof.query_proofs[i].round_proofs[j]; if(cur != 0) out << "," << std::endl; BOOST_ASSERT_MSG(round_proof.y.size() == 1, "Unsupported step_lis value"); - out << "\t\t\t{\"field\":\"" << round_proof.y[0][0] << "\"}," << std::endl; - out << "\t\t\t{\"field\":\"" << round_proof.y[0][1] << "\"}"; + out << "\t\t\t\t{\"field\":\"" << round_proof.y[0][0] << "\"}," << std::endl; + out << "\t\t\t\t{\"field\":\"" << round_proof.y[0][1] << "\"}"; cur++; cur++; } + out << std::endl << "\t\t\t]}"; } out << std::endl << "\t\t]}," << std::endl; out << "\t\t{\"array\": [" << std::endl; - cur = 0; for( std::size_t i = 0; i < eval_proof.fri_proof.query_proofs.size(); i++){ + if( i!= 0 ) out << "," << std::endl; + out << "\t\t\t{\"array\":[" << std::endl; + std::size_t cur = 0; for( const auto &[j, initial_proof]: eval_proof.fri_proof.query_proofs[i].initial_proof){ for( std::size_t k = 0; k < initial_proof.p.path().size(); k++){ if(cur != 0) out << "," << std::endl; - out << "\t\t\t{\"int\":" << initial_proof.p.path()[k][0].position() << "}"; + out << "\t\t\t\t{\"int\":" << initial_proof.p.path()[k][0].position() << "}"; cur ++; } break; } + out << std::endl << "\t\t\t]}"; } out << std::endl << "\t\t]}," << std::endl; out << "\t\t{\"array\": [" << std::endl; - cur = 0; for( std::size_t i = 0; i < eval_proof.fri_proof.query_proofs.size(); i++){ + if( i!= 0 ) out << "," << std::endl; + out << "\t\t\t{\"array\":[" << std::endl; + std::size_t cur = 0; for( const auto &[j, initial_proof]: eval_proof.fri_proof.query_proofs[i].initial_proof){ for( std::size_t k = 0; k < initial_proof.p.path().size(); k++){ if(cur != 0) out << "," << std::endl; - out << "\t\t\t" << generate_hash( + out << "\t\t\t\t" << generate_hash( initial_proof.p.path()[k][0].hash() ); cur ++; } } + out << std::endl << "\t\t\t]}"; } out << std::endl << "\t\t]}," << std::endl; out << "\t\t{\"array\": [" << std::endl; - cur = 0; for( std::size_t i = 0; i < eval_proof.fri_proof.query_proofs.size(); i++){ + if(i != 0) out << "," << std::endl; + out << "\t\t\t{\"array\": [" << std::endl; + cur = 0; for( std::size_t j = 0; j < eval_proof.fri_proof.query_proofs[i].round_proofs.size(); j++){ const auto& p = eval_proof.fri_proof.query_proofs[i].round_proofs[j].p; for( std::size_t k = 0; k < p.path().size(); k++){ if(cur != 0) out << "," << std::endl; - out << "\t\t\t{\"int\": " << p.path()[k][0].position() << "}"; + out << "\t\t\t\t{\"int\": " << p.path()[k][0].position() << "}"; cur++; } } + out << std::endl << "\t\t\t]}"; } out << std::endl << "\t\t]}," << std::endl; out << "\t\t{\"array\": [" << std::endl; - cur = 0; for( std::size_t i = 0; i < eval_proof.fri_proof.query_proofs.size(); i++){ + if(i != 0) out << "," << std::endl; + out << "\t\t\t{\"array\": [" << std::endl; + cur = 0; for( std::size_t j = 0; j < eval_proof.fri_proof.query_proofs[i].round_proofs.size(); j++){ const auto& p = eval_proof.fri_proof.query_proofs[i].round_proofs[j].p; for( std::size_t k = 0; k < p.path().size(); k++){ if(cur != 0) out << "," << std::endl; - out << "\t\t\t" << generate_hash( + out << "\t\t\t\t" << generate_hash( p.path()[k][0].hash() ); cur++; } } + out << std::endl << "\t\t\t]}"; } out << std::endl << "\t\t]}," << std::endl; @@ -498,8 +514,8 @@ namespace nil { if(j == 0) return "xi"; else if(j == 1 ) return "xi*omega"; else if(j == -1) return "xi/omega"; else - if(j > 0) return "xi*pow(omega, " + to_string(j) + ")"; else - if(j < 0) return "xi/pow(omega, " + to_string(-j) + ")"; + if(j > 0) return "xi*pow<" + to_string(j) + ">(omega)"; else + if(j < 0) return "xi/pow<" + to_string(-j) + ">(omega)"; return ""; } @@ -820,15 +836,119 @@ namespace nil { lpc_y_computation << "\t\ty[1] += Q1;" << std::endl; } + // We need remove loop there because we can't use for loops in for loops + cur = 0; + std::string full_public_input_check_str = ""; + full_public_input_check_str += "\tstd::array Omegas = {1};\n"; + full_public_input_check_str += "\tpallas::base_field_type::value_type result(0);\n"; + for (std::size_t i = 0; i < arithmetization_params::public_input_columns; i++){ + full_public_input_check_str += "\t{\n"; + for( std::size_t j = 0; j < public_input_sizes[i]; j++){ + full_public_input_check_str += "\tresult = pallas::base_field_type::value_type(0);\n"; + full_public_input_check_str += "\t\tresult += public_input[" + to_string(cur) + "] * Omegas["+to_string(j)+"] / (challenges.xi - Omegas["+to_string(j)+"]);"; + if( j != public_input_sizes[i] - 1) + full_public_input_check_str += " Omegas["+to_string(j+1)+"] = Omegas["+to_string(j)+"] * omega;\n"; + cur++; + } + full_public_input_check_str += "\n\t\t__builtin_assigner_exit_check(rows_amount * proof.z[zero_indices[witness_amount + " + to_string(i) + " ]] == precomputed_values.Z_at_xi * result);\n"; + full_public_input_check_str += "\t}\n"; + } + std::size_t fixed_values_size = permutation_size * 2 + 2 + arithmetization_params::constant_columns + arithmetization_params::selector_columns; std::size_t variable_values_size = arithmetization_params::witness_columns + arithmetization_params::public_input_columns; - std::string batches_size_list = to_string(fixed_values_size) + ", " + to_string(variable_values_size) + ", " + - to_string(use_lookups?2:1) + ", " + to_string(quotient_polys); - if(use_lookups) batches_size_list += ", " + to_string(constraint_system.sorted_lookup_columns_number()); + + std::string initial_proof_check_str = ""; + std::vector batches_sizes; + batches_sizes.push_back(fixed_values_size); + batches_sizes.push_back(variable_values_size); + batches_sizes.push_back(use_lookups?2:1); + batches_sizes.push_back(quotient_polys); + if(use_lookups) batches_sizes.push_back(constraint_system.sorted_lookup_columns_number()); + + std::size_t start_position = 0; + std::size_t initial_merkle_proofs_position_num = (log2(fri_params.D[0]->m) - 1); + cur = 0; + for(std::size_t i = 0; i < batches_num; i++){ + initial_proof_check_str += "\t\thash_state = calculate_leaf_hash<"+to_string(start_position*2)+"," + to_string(batches_sizes[i]) + ">(proof.initial_proof_values[i], res[0][2] == pallas::base_field_type::value_type(0));\n"; + for(std::size_t j = 0; j < initial_merkle_proofs_position_num; j++){ + initial_proof_check_str += "\t\tpos = pallas::base_field_type::value_type(proof.initial_proof_positions[i][" + to_string(j) + "]);"; + initial_proof_check_str += " npos = pallas::base_field_type::value_type(1) - pos;\n"; + initial_proof_check_str += + "\t\thash_state = __builtin_assigner_poseidon_pallas_base({0, pos * hash_state + npos * proof.initial_proof_hashes[i][" + +to_string(cur)+ + "], npos * hash_state + pos * proof.initial_proof_hashes[i][" + +to_string(cur)+ + "]})[2];\n"; + cur++; + } + start_position += batches_sizes[i]; + if( i == 0 ) + initial_proof_check_str += "\t\t__builtin_assigner_exit_check(hash_state == vk[1]);\n\n"; + else + initial_proof_check_str += "\t\t__builtin_assigner_exit_check(hash_state == proof.commitments[" + to_string(i-1) + "]);\n\n"; + } + + std::string batches_size_list = to_string(batches_sizes[0]) + ", " + to_string(batches_sizes[1]) + ", " + + to_string(batches_sizes[2]) + ", " + to_string(batches_sizes[3]); + if(use_lookups) batches_size_list += ", " + to_string(batches_sizes[4]); + + std::string round_proof_check_str = ""; + cur = 0; + for( std::size_t i = 0; i < fri_params.r; i++){ + round_proof_check_str += "\t\tpos = res[" + to_string(i) + "][2]; npos = pallas::base_field_type::value_type(1) - pos;\n"; + if(i == 0) + round_proof_check_str += "\t\trhash = __builtin_assigner_poseidon_pallas_base({0, npos * y[0] + pos * y[1], pos * y[0] + npos * y[1]})[2];\n"; + else + round_proof_check_str += "\t\trhash = __builtin_assigner_poseidon_pallas_base({0, npos * proof.round_proof_values[i]["+to_string(i*2-2)+"] + pos * proof.round_proof_values[i]["+to_string(i*2-1)+"], npos * proof.round_proof_values[i]["+to_string(i*2-1)+"] + pos * proof.round_proof_values[i]["+to_string(i*2-2)+"]})[2];\n"; + for ( std::size_t j = 0; j < log2(fri_params.D[0]->m) - i - 1; j++){ + round_proof_check_str += "\t\tpos = pallas::base_field_type::value_type(proof.round_merkle_proof_positions[i][" + to_string(cur) + "]); npos = pallas::base_field_type::value_type(1) - pos;\n"; + round_proof_check_str += "\t\trhash = __builtin_assigner_poseidon_pallas_base({0, pos * rhash + npos * proof.round_proof_hashes[i]["+to_string(cur)+"], npos * rhash + pos * proof.round_proof_hashes[i]["+to_string(cur)+"]})[2];\n"; + cur++; + } + round_proof_check_str += "\t\t__builtin_assigner_exit_check(rhash == proof.fri_roots["+to_string(i)+"]);\n\n"; + } + + std::string lookup_input_loop = ""; + cur = 0; + std::size_t cur_e = 0; + for(std::size_t i=0; i < constraint_system.lookup_gates().size(); i++){ + for(std::size_t j = 0; j < constraint_system.lookup_gates()[i].constraints.size(); j++){ + lookup_input_loop += "\t\tlookup_input["+to_string(cur) + "] = lookup_gate_constraints_table_ids["+to_string(cur)+"];\n"; + lookup_input_loop += "\t\ttheta_acc = theta;\n"; + for(std::size_t k = 0; k < constraint_system.lookup_gates()[i].constraints[j].lookup_input.size(); k++){ + lookup_input_loop += "\t\tlookup_input["+to_string(cur)+"] += lookup_gate_constraints_lookup_inputs["+to_string(cur_e)+"] * theta_acc; theta_acc *= theta;\n"; + cur_e++; + } + lookup_input_loop += "\t\tlookup_input["+to_string(cur) + "] *= lookup_gate_selectors["+to_string(i)+"];\n"; + cur++; + } + } + + std::string lookup_table_loop = ""; + cur = 0; + std::size_t cur_o = 0; + for(std::size_t i = 0; i < constraint_system.lookup_tables().size(); i++){ + for(std::size_t j = 0; j < constraint_system.lookup_tables()[i].lookup_options.size(); j++){ + lookup_table_loop += "\t\ttheta_acc = theta;\n"; + lookup_table_loop += "\t\tlookup_value["+to_string(cur)+"] = lookup_table_selectors["+to_string(i)+"] * pallas::base_field_type::value_type("+to_string(i+1)+");\n"; + lookup_table_loop += "\t\tlookup_shifted_value["+to_string(cur)+"] = shifted_lookup_table_selectors["+to_string(i)+"] * pallas::base_field_type::value_type("+to_string(i+1)+");\n"; + for(std::size_t k = 0; k < constraint_system.lookup_tables()[i].lookup_options[j].size(); k++){ + lookup_table_loop += "\t\tlookup_value["+to_string(cur)+"] += lookup_table_selectors["+to_string(i)+"] * lookup_table_lookup_options["+to_string(cur_o)+"] * theta_acc;\n"; + lookup_table_loop += "\t\tlookup_shifted_value["+to_string(cur)+"] += shifted_lookup_table_selectors["+to_string(i)+"] * shifted_lookup_table_lookup_options["+to_string(cur_o)+"] * theta_acc;\n"; + lookup_table_loop += "\t\ttheta_acc = theta_acc * theta;\n"; + cur_o++; + } + lookup_table_loop += "\t\tlookup_value["+to_string(cur)+"] *= (pallas::base_field_type::value_type(1) - q_last[0] - q_blind[0]);\n"; + lookup_table_loop += "\t\tlookup_shifted_value["+to_string(cur)+"] *= (pallas::base_field_type::value_type(1) - q_last[1] - q_blind[1]);\n"; + cur++; + } + } lookup_reps["$LOOKUP_VARS$"] = use_lookups?lookup_vars:""; lookup_reps["$LOOKUP_EXPRESSIONS$"] = use_lookups?lookup_expressions:""; lookup_reps["$LOOKUP_CODE$"] = use_lookups?lookup_code:""; + lookup_reps["$LOOKUP_INPUT_LOOP$"] = use_lookups?lookup_input_loop:""; + lookup_reps["$LOOKUP_TABLE_LOOP$"] = use_lookups?lookup_table_loop:""; result = replace_all(result, lookup_reps); reps["$USE_LOOKUPS_DEFINE$"] = use_lookups?"#define __USE_LOOKUPS__ 1\n":""; @@ -838,13 +958,15 @@ namespace nil { reps["$POINTS_NUM$"] = to_string(points_num); reps["$POLY_NUM$"] = to_string(poly_num); reps["$INITIAL_PROOF_POINTS_NUM$"] = to_string(poly_num * 2); - reps["$ROUND_PROOF_POINTS_NUM$"] = to_string(fri_params.r * 2 * lambda); + reps["$ROUND_PROOF_POINTS_NUM$"] = to_string(fri_params.r * 2); reps["$FRI_ROOTS_NUM$"] = to_string(fri_params.r); reps["$INITIAL_MERKLE_PROOFS_NUM$"] = to_string(batches_num * lambda); - reps["$INITIAL_MERKLE_PROOFS_POSITION_NUM$"] = to_string(lambda * (log2(fri_params.D[0]->m) - 1)); - reps["$INITIAL_MERKLE_PROOFS_HASH_NUM$"] = to_string(lambda * (log2(fri_params.D[0]->m) - 1) * batches_num); - reps["$ROUND_MERKLE_PROOFS_POSITION_NUM$"] = to_string(lambda * round_proof_layers_num); - reps["$ROUND_MERKLE_PROOFS_HASH_NUM$"] = to_string(lambda * round_proof_layers_num); + reps["$INITIAL_MERKLE_PROOFS_POSITION_NUM$"] = to_string(initial_merkle_proofs_position_num); + reps["$INITIAL_MERKLE_PROOFS_HASH_NUM$"] = to_string((log2(fri_params.D[0]->m) - 1) * batches_num); + reps["$INITIAL_PROOF_CHECK$"] = to_string(initial_proof_check_str); + reps["$ROUND_MERKLE_PROOFS_POSITION_NUM$"] = to_string(round_proof_layers_num); + reps["$ROUND_MERKLE_PROOFS_HASH_NUM$"] = to_string(round_proof_layers_num); + reps["$ROUND_PROOF_CHECK$"] = to_string(round_proof_check_str); reps["$FINAL_POLYNOMIAL_SIZE$"] = to_string(std::pow(2, std::log2(fri_params.max_degree + 1) - fri_params.r + 1) - 2); reps["$LAMBDA$"] = to_string(lambda); reps["$PERMUTATION_SIZE$"] = to_string(permutation_size); @@ -898,7 +1020,7 @@ namespace nil { reps["$FULL_PUBLIC_INPUT_SIZE$"] = to_string(full_public_input_size); reps["$LPC_POLY_IDS_CONSTANT_ARRAYS$"] = lpc_poly_ids_const_arrays; reps["$LPC_Y_COMPUTATION$"] = lpc_y_computation.str(); - reps["$PUBLIC_INPUT_CHECK$"] = arithmetization_params::public_input_columns == 0 ? "" :public_input_check_str; + reps["$PUBLIC_INPUT_CHECK$"] = arithmetization_params::public_input_columns == 0 ? "" :full_public_input_check_str; reps["$PUBLIC_INPUT_INPUT$"] = arithmetization_params::public_input_columns == 0 ? "" : public_input_input_str; result = replace_all(result, reps); diff --git a/include/nil/blueprint/transpiler/templates/recursive_verifier.hpp b/include/nil/blueprint/transpiler/templates/recursive_verifier.hpp index 28c2be3..dd10f7c 100644 --- a/include/nil/blueprint/transpiler/templates/recursive_verifier.hpp +++ b/include/nil/blueprint/transpiler/templates/recursive_verifier.hpp @@ -80,43 +80,12 @@ std::array calcu lookup_output_type lookup_argument; std::array lookup_input; - std::size_t cur = 0; - std::size_t cur_e = 0; - for(std::size_t g = 0; g < lookup_gate_amount; g++){ - for( std::size_t i = 0; i < lookup_constraints_amount_list[g]; i++ ){ - lookup_input[cur] = lookup_gate_selectors[g] * lookup_gate_constraints_table_ids[cur]; - pallas::base_field_type::value_type theta_acc = theta; - for(std::size_t e = 0; e < lookup_expressions_amount_list[cur]; e++){ - lookup_input[cur] = lookup_input[cur] + lookup_gate_selectors[g] * lookup_gate_constraints_lookup_inputs[cur_e] * theta_acc; - theta_acc = theta_acc * theta; - cur_e++; - } - cur++; - } - } - + pallas::base_field_type::value_type theta_acc; +$LOOKUP_INPUT_LOOP$ std::array lookup_value; std::array lookup_shifted_value; - cur = 0; - std::size_t cur_o = 0; pallas::base_field_type::value_type tab_id = 1; - for( std::size_t t = 0; t < lookup_table_amount; t++ ){ - for( std::size_t o = 0; o < lookup_options_amount_list[t]; o++ ){ - pallas::base_field_type::value_type theta_acc = theta; - lookup_value[cur] = lookup_table_selectors[t] * tab_id; - lookup_shifted_value[cur] = shifted_lookup_table_selectors[t] * tab_id; - for( std::size_t c = 0; c < lookup_tables_columns_amount_list[t]; c++){ - lookup_value[cur] = lookup_value[cur] + lookup_table_selectors[t] * lookup_table_lookup_options[cur_o] * theta_acc; - lookup_shifted_value[cur] = lookup_shifted_value[cur] + shifted_lookup_table_selectors[t] * shifted_lookup_table_lookup_options[cur_o] * theta_acc; - theta_acc = theta_acc * theta; - cur_o++; - } - lookup_value[cur] = lookup_value[cur] * (pallas::base_field_type::value_type(1) - q_last[0] - q_blind[0]); - lookup_shifted_value[cur] = lookup_shifted_value[cur] * (pallas::base_field_type::value_type(1) - q_last[1] - q_blind[1]); - cur++; - } - tab_id = tab_id + 1; - } +$LOOKUP_TABLE_LOOP$ pallas::base_field_type::value_type g = pallas::base_field_type::value_type(1); pallas::base_field_type::value_type h = pallas::base_field_type::value_type(1); @@ -148,17 +117,14 @@ std::array calcu std::string public_input_check_str = R"( //Check public input - std::size_t cur = 0; - for( std::size_t i = 0; i < public_input_amount; i++){ - pallas::base_field_type::value_type Omega(1); - pallas::base_field_type::value_type result(0); - for( std::size_t j = 0; j < public_input_sizes[i]; j++){ - result += public_input[cur] * Omega / (challenges.xi - Omega); - Omega *= omega; - cur++; - } - __builtin_assigner_exit_check(rows_amount * proof.z[zero_indices[witness_amount + i]] == precomputed_values.Z_at_xi * result); + pallas::base_field_type::value_type Omega(1); + pallas::base_field_type::value_type result(0); + for( std::size_t j = 0; j < public_input_sizes[i]; j++){ + result += public_input[cur] * Omega / (challenges.xi - Omega); + Omega *= omega; + cur++; } + __builtin_assigner_exit_check(rows_amount * proof.z[zero_indices[witness_amount + i]] == precomputed_values.Z_at_xi * result); )"; std::string public_input_input_str = "\tstd::array public_input,\n"; @@ -224,12 +190,12 @@ struct placeholder_proof_type{ pallas::base_field_type::value_type challenge; std::array z; std::array fri_roots; - std::array, lambda> initial_proof_values; // lambda times - std::array round_proof_values; // lambda times - std::array initial_proof_positions; // lambda times - std::array initial_proof_hashes; // lambda times - std::array round_merkle_proof_positions; // lambda times - std::array round_proof_hashes; // lambda times + std::array, lambda> initial_proof_values; + std::array, lambda> round_proof_values; // lambda times + std::array, lambda> initial_proof_positions; + std::array, lambda> initial_proof_hashes; + std::array, lambda> round_merkle_proof_positions; // lambda times + std::array, lambda> round_proof_hashes; // lambda times std::array final_polynomial; }; @@ -283,10 +249,9 @@ pallas::base_field_type::value_type transcript_challenge(transcript_state_type & return tr_state.state[0]; } -pallas::base_field_type::value_type pow2_p(pallas::base_field_type::value_type x, size_t plog){ - if(plog == 0) return pallas::base_field_type::value_type(1); +pallas::base_field_type::value_type pow_rows_amount(pallas::base_field_type::value_type x){ pallas::base_field_type::value_type result = x; - for(std::size_t i = 0; i < plog; i++){ + for(std::size_t i = 0; i < rows_log; i++){ result = result * result; } return result; @@ -339,12 +304,13 @@ pallas::base_field_type::value_type pow9(pallas::base_field_type::value_type x){ return result; } -pallas::base_field_type::value_type pow(pallas::base_field_type::value_type x, size_t p){ - if( p == 0 ) return pallas::base_field_type::value_type(1); - if( p == 1 ) return x; - pallas::base_field_type::value_type result = pow(x, p/2); +template +pallas::base_field_type::value_type pow(pallas::base_field_type::value_type x){ + if constexpr( p == 0 ) return pallas::base_field_type::value_type(1); + if constexpr( p == 1 ) return x; + pallas::base_field_type::value_type result = pow

(x); result = result * result; - if( p%2 == 1 ) result = result * x; + if constexpr( p%2 == 1 ) result = result * x; return result; } @@ -403,7 +369,7 @@ placeholder_challenges_type generate_challenges( challenges.xi = transcript_challenge(tr_state); transcript(tr_state, vk[1]); - for(std::size_t i = 0; i < proof.commitments.size(); i++){ + for(std::size_t i = 0; i < commitments_num; i++){ transcript(tr_state, proof.commitments[i]); } @@ -424,7 +390,7 @@ placeholder_challenges_type generate_challenges( std::pair xi_polys( pallas::base_field_type::value_type xi ){ - pallas::base_field_type::value_type xi_n = pow2_p(xi, rows_log) - pallas::base_field_type::value_type(1); + pallas::base_field_type::value_type xi_n = pow_rows_amount(xi) - pallas::base_field_type::value_type(1); pallas::base_field_type::value_type l0 = (xi - pallas::base_field_type::value_type(1))*pallas::base_field_type::value_type(rows_amount); l0 = xi_n / l0; return std::make_pair(l0, xi_n); @@ -456,140 +422,20 @@ typename pallas::base_field_type::value_type ); } -std::array getV3( - pallas::base_field_type::value_type xi0,pallas::base_field_type::value_type xi1,pallas::base_field_type::value_type xi2 -){ - std::array result; - result[0] = - xi0 * xi1 * xi2; - result[1] = xi0 * xi1 + xi1 * xi2 + xi0 * xi2; - result[2] = - xi0 - xi1 - xi2; - result[3] = pallas::base_field_type::value_type(1); -// __builtin_assigner_exit_check(result[0] + xi0 * result[1] + xi0 * xi0 * result[2] + xi0*xi0*xi0*result[3] == pallas::base_field_type::value_type(0)); - return result; -} - -std::array getV2( - pallas::base_field_type::value_type xi0,pallas::base_field_type::value_type xi1 -){ - std::array result; - result[0] = xi0 * xi1; - result[1] = - xi0 - xi1; - result[2] = pallas::base_field_type::value_type(1); - result[3] = pallas::base_field_type::value_type(0); -// __builtin_assigner_exit_check(result[0] + xi0 * result[1] + xi0 * xi0 * result[2] + xi0*xi0*xi0*result[3] == pallas::base_field_type::value_type(0)); - return result; -} - -std::array getV1( - pallas::base_field_type::value_type xi0 -){ - std::array result; - result[0] = - xi0; - result[1] = pallas::base_field_type::value_type(1); - result[2] = pallas::base_field_type::value_type(0); - result[3] = pallas::base_field_type::value_type(0); -// __builtin_assigner_exit_check(result[0] + xi0 * result[1] + xi0 * xi0 * result[2] + xi0*xi0*xi0*result[3] == pallas::base_field_type::value_type(0)); - return result; -} - -std::array getU3( - pallas::base_field_type::value_type x0,pallas::base_field_type::value_type x1,pallas::base_field_type::value_type x2, - pallas::base_field_type::value_type z0,pallas::base_field_type::value_type z1,pallas::base_field_type::value_type z2 -){ - std::array result; - pallas::base_field_type::value_type denom = (x0-x1)*(x1-x2)*(x2-x0); - - z0 = z0 * (x2-x1); - z1 = z1 * (x0-x2); - z2 = z2 * (x1-x0); - - result[0] = (z0*x1*x2 + z1*x0*x2 + z2*x0*x1)/denom; - result[1] = (-z0*(x1 + x2) - z1*(x0 + x2) - z2 * (x0 + x1))/denom; - result[2] = (z0 + z1 + z2)/denom; - -// __builtin_assigner_exit_check(result[0] + x0 * result[1] + x0 * x0 * result[2] == z0/(x2-x1)); -// __builtin_assigner_exit_check(result[0] + x1 * result[1] + x1 * x1 * result[2] == z1/(x0-x2)); -// __builtin_assigner_exit_check(result[0] + x2 * result[1] + x2 * x2 * result[2] == z2/(x1-x0)); - - return result; -} - -std::array getU2( - pallas::base_field_type::value_type x0,pallas::base_field_type::value_type x1, - pallas::base_field_type::value_type z0,pallas::base_field_type::value_type z1 -){ - std::array result; - pallas::base_field_type::value_type denom = (x0-x1); - result[0] = (-z0*x1 + z1*x0)/denom; - result[1] = (z0 - z1)/denom; - result[2] = pallas::base_field_type::value_type(0); - -// __builtin_assigner_exit_check(result[0] + x0 * result[1] + x0 * x0 * result[2] == z0); -// __builtin_assigner_exit_check(result[0] + x1 * result[1] + x1 * x1 * result[2] == z1); - - return result; -} - -std::array getU1( - pallas::base_field_type::value_type x0, - pallas::base_field_type::value_type z0 -){ - std::array result; - result[0] = z0; - result[1] = pallas::base_field_type::value_type(0); - result[2] = pallas::base_field_type::value_type(0); - -// __builtin_assigner_exit_check(result[0] + x0 * result[1] + x0 * x0 * result[2] == z0); - - return result; -} - -pallas::base_field_type::value_type eval4(std::array poly, pallas::base_field_type::value_type x){ - pallas::base_field_type::value_type result; - result = poly[3]; - result = result *x + poly[2]; - result = result *x + poly[1]; - result = result *x + poly[0]; -// __builtin_assigner_exit_check(poly[0] + x * poly[1] + x * x * poly[2] + x*x*x*poly[3] == result); - return result; -} - -pallas::base_field_type::value_type eval3(std::array poly, pallas::base_field_type::value_type x){ - pallas::base_field_type::value_type result; - result = poly[2]; - result = result *x + poly[1]; - result = result *x + poly[0]; -// __builtin_assigner_exit_check(poly[0] + x * poly[1] + x * x * poly[2] == result); - return result; -} - +template pallas::base_field_type::value_type calculate_leaf_hash( std::array val, - std::size_t start_index, - std::size_t leaf_size + bool reversed ){ pallas::base_field_type::value_type hash_state = pallas::base_field_type::value_type(0); - for(std::size_t pos = 0; pos < leaf_size; pos+=2){ + for(std::size_t pos = 0; pos < leaf_size*2; pos+=2){ hash_state = __builtin_assigner_poseidon_pallas_base( - {hash_state, val[start_index + pos], val[start_index + pos+1]} + {hash_state, reversed?val[start_index + pos]:val[start_index + pos+1], reversed?val[start_index + pos+1]:val[start_index + pos]} )[2]; } return hash_state; } -pallas::base_field_type::value_type calculate_reversed_leaf_hash( - std::array &val, - std::size_t start_index, - std::size_t leaf_size -){ - pallas::base_field_type::value_type hash_state = pallas::base_field_type::value_type(0); - for(std::size_t pos = 0; pos < leaf_size; pos+=2){ - hash_state = __builtin_assigner_poseidon_pallas_base( - {hash_state, val[start_index + pos + 1], val[start_index + pos]} - )[2]; - } - return hash_state; -} struct precomputed_values_type{ pallas::base_field_type::value_type l0; pallas::base_field_type::value_type Z_at_xi; @@ -623,7 +469,8 @@ typedef __attribute__((ext_vector_type(2))) precomputed_values_type precomputed_values; std::tie(precomputed_values.l0, precomputed_values.Z_at_xi) = xi_polys(challenges.xi); - $PUBLIC_INPUT_CHECK$ + // For loop in for loop removed +$PUBLIC_INPUT_CHECK$ std::array F;// = {0,0,0,0,0,0,0,0}; @@ -707,28 +554,9 @@ typedef __attribute__((ext_vector_type(2))) cur_val = 0; pallas::base_field_type::value_type hash_state; - for(std::size_t b = 0; b < batches_num; b++){ - pallas::base_field_type::value_type hash_state(0); - if(res[0][2] == pallas::base_field_type::value_type(0)){ - hash_state = calculate_leaf_hash(proof.initial_proof_values[i], cur_val, batches_amount_list[b] *2); - } else if(res[0][2] == pallas::base_field_type::value_type(1)){ - hash_state = calculate_reversed_leaf_hash(proof.initial_proof_values[i], cur_val, batches_amount_list[b] *2); - } - cur_val += batches_amount_list[b] *2; - for(std::size_t r = i * initial_merkle_proofs_position_num/lambda; r < (i + 1)* initial_merkle_proofs_position_num/lambda ; r++){ - if(proof.initial_proof_positions[r] == 1){ - hash_state = __builtin_assigner_poseidon_pallas_base({0, hash_state, proof.initial_proof_hashes[initial_proof_hash_ind]})[2]; - } else{ - hash_state = __builtin_assigner_poseidon_pallas_base({0, proof.initial_proof_hashes[initial_proof_hash_ind], hash_state})[2]; - } - initial_proof_hash_ind ++; - } - if(b == 0) - __builtin_assigner_exit_check(hash_state == vk[1]); - else - __builtin_assigner_exit_check(hash_state == proof.commitments[b-1]); - } - + pallas::base_field_type::value_type pos; + pallas::base_field_type::value_type npos; +$INITIAL_PROOF_CHECK$ std::array y = {0,0}; theta_acc = pallas::base_field_type::value_type(1); pallas::base_field_type::value_type Q0; @@ -736,35 +564,19 @@ typedef __attribute__((ext_vector_type(2))) $LPC_Y_COMPUTATION$ std::size_t D = D0_log - 1; pallas::base_field_type::value_type rhash; +$ROUND_PROOF_CHECK$ for(std::size_t j = 0; j < fri_rounds; j++){ - if(res[j][2] == pallas::base_field_type::value_type(0)){ - rhash = __builtin_assigner_poseidon_pallas_base({0, y[0], y[1]})[2]; - } else { - rhash = __builtin_assigner_poseidon_pallas_base({0, y[1], y[0]})[2]; - } - for( std::size_t d = 0; d < D; d++){ - if(proof.round_merkle_proof_positions[round_proof_hash_ind] == 1){ - rhash = __builtin_assigner_poseidon_pallas_base({0, rhash, proof.round_proof_hashes[round_proof_hash_ind]})[2]; - } else { - rhash = __builtin_assigner_poseidon_pallas_base({0, proof.round_proof_hashes[round_proof_hash_ind], rhash})[2]; - } - round_proof_hash_ind++; - } - __builtin_assigner_exit_check(rhash == proof.fri_roots[j]); - D--; - interpolant = __builtin_assigner_fri_lin_inter( res[j][0], y[0], y[1], challenges.fri_alphas[j] ); - __builtin_assigner_exit_check(interpolant == proof.round_proof_values[round_proof_ind]); - y[0] = proof.round_proof_values[round_proof_ind]; - y[1] = proof.round_proof_values[round_proof_ind + 1]; + __builtin_assigner_exit_check(interpolant == proof.round_proof_values[i][2*j]); + y[0] = proof.round_proof_values[i][2*j]; + y[1] = proof.round_proof_values[i][2*j + 1]; pallas::base_field_type::value_type rhash; - round_proof_ind += 2; } interpolant = pallas::base_field_type::value_type(0); diff --git a/include/nil/blueprint/transpiler/util.hpp b/include/nil/blueprint/transpiler/util.hpp index 504d819..dcfdbff 100644 --- a/include/nil/blueprint/transpiler/util.hpp +++ b/include/nil/blueprint/transpiler/util.hpp @@ -60,8 +60,8 @@ namespace nil { if(j == 0) return "xi"; else if(j == 1 ) return "xi*omega"; else if(j == -1) return "xi/omega"; else - if(j > 0) return "xi*pow(omega, " + to_string(j) + ")"; else - if(j < 0) return "xi/pow(omega, " + to_string(-j) + ")"; + if(j > 0) return "xi*pow< " + to_string(j) + ">(omega)"; else + if(j < 0) return "xi/pow< " + to_string(-j) + ">(omega)"; } else if(mode == "evm") { if(j == 0) return "xi"; else if(j == 1 ) return "mulmod(xi, omega, modulus)"; else