diff --git a/include/nil/blueprint/bls_signature/bls12_381_pairing.hpp b/include/nil/blueprint/bls_signature/bls12_381_pairing.hpp new file mode 100644 index 00000000..3f30d7b5 --- /dev/null +++ b/include/nil/blueprint/bls_signature/bls12_381_pairing.hpp @@ -0,0 +1,87 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2022 Mikhail Komarov +// Copyright (c) 2022 Nikita Kaskov +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ASSIGNER_BLS12_381_PAIRING_HPP +#define CRYPTO3_ASSIGNER_BLS12_381_PAIRING_HPP + +#include "llvm/IR/Type.h" +#include "llvm/IR/TypeFinder.h" +#include "llvm/IR/TypedPointerType.h" + +#include +#include +#include +#include +#include + +#include + +namespace nil { + namespace blueprint { + + template + void handle_bls12381_pairing( + const llvm::Instruction *inst, + stack_frame> &frame, + circuit_proxy> &bp, + assignment_proxy> + &assignment, + std::uint32_t start_row, std::uint32_t target_prover_idx) { + + using var = crypto3::zk::snark::plonk_variable; + + using component_type = components::bls12_381_pairing< + crypto3::zk::snark::plonk_constraint_system, + BlueprintFieldType>; + + ASSERT(frame.vectors[inst->getOperand(0)].size() == 2); + ASSERT(frame.vectors[inst->getOperand(1)].size() == 4); + std::vector operand0_vars = frame.vectors[inst->getOperand(0)]; + std::vector operand1_vars = frame.vectors[inst->getOperand(1)]; + + std::array P = { + operand0_vars[0], + operand0_vars[1]}; + std::array Q = { + operand1_vars[0], + operand1_vars[1], + operand1_vars[2], + operand1_vars[3]}; + + typename component_type::input_type instance_input; + instance_input.P = P; + instance_input.Q = Q; + + const auto& component_result = get_component_result + (bp, assignment, start_row, target_prover_idx, instance_input); + + handle_component_result + (assignment, inst, frame, component_result); + } + + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_ASSIGNER_BLS12_381_PAIRING_HPP diff --git a/include/nil/blueprint/bls_signature/fp12_multiplication.hpp b/include/nil/blueprint/bls_signature/fp12_multiplication.hpp new file mode 100644 index 00000000..3aa773ad --- /dev/null +++ b/include/nil/blueprint/bls_signature/fp12_multiplication.hpp @@ -0,0 +1,90 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2022 Mikhail Komarov +// Copyright (c) 2022 Nikita Kaskov +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ASSIGNER_FP12_MULTIPLICATION_HPP +#define CRYPTO3_ASSIGNER_FP12_MULTIPLICATION_HPP + +#include "llvm/IR/Type.h" +#include "llvm/IR/TypeFinder.h" +#include "llvm/IR/TypedPointerType.h" + +#include +#include +#include +#include +#include + +#include + +namespace nil { + namespace blueprint { + + template + void handle_fp12_mul( + const llvm::Instruction *inst, + stack_frame> &frame, + circuit_proxy> &bp, + assignment_proxy> + &assignment, + std::uint32_t start_row, std::uint32_t target_prover_idx) { + + using var = crypto3::zk::snark::plonk_variable; + + using component_type = components::fp12_multiplication< + crypto3::zk::snark::plonk_constraint_system, + BlueprintFieldType>; + + std::vector x = frame.vectors[inst->getOperand(0)]; + ASSERT(x.size() == 12); + + std::vector y = frame.vectors[inst->getOperand(1)]; + ASSERT(y.size() == 12); + + std::array x_arr = { + x[0], x[1], x[2], x[3], + x[4], x[5], x[6], x[7], + x[8], x[9], x[10], x[11] + }; + std::array y_arr = { + y[0], y[1], y[2], y[3], + y[4], y[5], y[6], y[7], + y[8], y[9], y[10], y[11] + }; + + typename component_type::input_type instance_input; + instance_input.a = x_arr; + instance_input.b = y_arr; + + const auto& component_result = get_component_result + (bp, assignment, start_row, target_prover_idx, instance_input); + + handle_component_result + (assignment, inst, frame, component_result); + } + + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_ASSIGNER_FP12_MULTIPLICATION_HPP diff --git a/include/nil/blueprint/bls_signature/h2c.hpp b/include/nil/blueprint/bls_signature/h2c.hpp new file mode 100644 index 00000000..4bb93805 --- /dev/null +++ b/include/nil/blueprint/bls_signature/h2c.hpp @@ -0,0 +1,74 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2022 Mikhail Komarov +// Copyright (c) 2022 Nikita Kaskov +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ASSIGNER_H2C_HPP +#define CRYPTO3_ASSIGNER_H2C_HPP + +#include "llvm/IR/Type.h" +#include "llvm/IR/TypeFinder.h" +#include "llvm/IR/TypedPointerType.h" + +#include +#include +#include +#include +#include + +#include + +namespace nil { + namespace blueprint { + + template + void handle_h2c( + const llvm::Instruction *inst, + stack_frame> &frame, + circuit_proxy> &bp, + assignment_proxy> + &assignment, + std::uint32_t start_row, std::uint32_t target_prover_idx) { + + using var = crypto3::zk::snark::plonk_variable; + + using component_type = components::h2c< + crypto3::zk::snark::plonk_constraint_system, + BlueprintFieldType>; + + var input = frame.scalars[inst->getOperand(0)]; + + typename component_type::input_type instance_input; + instance_input.input = input; + + const auto& component_result = get_component_result + (bp, assignment, start_row, target_prover_idx, instance_input); + + handle_component_result + (assignment, inst, frame, component_result); + } + + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_ASSIGNER_H2C_HPP diff --git a/include/nil/blueprint/bls_signature/is_in_g1.hpp b/include/nil/blueprint/bls_signature/is_in_g1.hpp new file mode 100644 index 00000000..1ada852b --- /dev/null +++ b/include/nil/blueprint/bls_signature/is_in_g1.hpp @@ -0,0 +1,79 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2022 Mikhail Komarov +// Copyright (c) 2022 Nikita Kaskov +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ASSIGNER_IS_IN_G1_HPP +#define CRYPTO3_ASSIGNER_IS_IN_G1_HPP + +#include "llvm/IR/Type.h" +#include "llvm/IR/TypeFinder.h" +#include "llvm/IR/TypedPointerType.h" + +#include +#include +#include +#include +#include + +#include + +namespace nil { + namespace blueprint { + + template + void handle_is_in_g1( + const llvm::Instruction *inst, + stack_frame> &frame, + circuit_proxy> &bp, + assignment_proxy> + &assignment, + std::uint32_t start_row, std::uint32_t target_prover_idx) { + + using var = crypto3::zk::snark::plonk_variable; + + using component_type = components::is_in_g1< + crypto3::zk::snark::plonk_constraint_system, + BlueprintFieldType>; + + ASSERT(frame.vectors[inst->getOperand(0)].size() == 2); + std::vector operand0_vars = frame.vectors[inst->getOperand(0)]; + + std::array input = { + operand0_vars[0], + operand0_vars[1]}; + + typename component_type::input_type instance_input; + instance_input.input = input; + + const auto& component_result = get_component_result + (bp, assignment, start_row, target_prover_idx, instance_input); + + handle_component_result + (assignment, inst, frame, component_result); + } + + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_ASSIGNER_IS_IN_G1_HPP diff --git a/include/nil/blueprint/bls_signature/is_in_g2.hpp b/include/nil/blueprint/bls_signature/is_in_g2.hpp new file mode 100644 index 00000000..39344fb7 --- /dev/null +++ b/include/nil/blueprint/bls_signature/is_in_g2.hpp @@ -0,0 +1,83 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2022 Mikhail Komarov +// Copyright (c) 2022 Nikita Kaskov +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ASSIGNER_IS_IN_G2_HPP +#define CRYPTO3_ASSIGNER_IS_IN_G2_HPP + +#include "llvm/IR/Type.h" +#include "llvm/IR/TypeFinder.h" +#include "llvm/IR/TypedPointerType.h" + +#include +#include +#include +#include +#include + +#include + +namespace nil { + namespace blueprint { + + template + void handle_is_in_g2( + const llvm::Instruction *inst, + stack_frame> &frame, + circuit_proxy> &bp, + assignment_proxy> + &assignment, + std::uint32_t start_row, std::uint32_t target_prover_idx) { + + using var = crypto3::zk::snark::plonk_variable; + + using component_type = components::is_in_g2< + crypto3::zk::snark::plonk_constraint_system, + BlueprintFieldType>; + + ASSERT(frame.vectors[inst->getOperand(0)].size() == 4); + std::vector operand0_vars = frame.vectors[inst->getOperand(0)]; + + std::array X = { + operand0_vars[0], + operand0_vars[1]}; + std::array Y = { + operand0_vars[2], + operand0_vars[3]}; + + typename component_type::input_type instance_input; + instance_input.X = X; + instance_input.Y = Y; + + const auto& component_result = get_component_result + (bp, assignment, start_row, target_prover_idx, instance_input); + + handle_component_result + (assignment, inst, frame, component_result); + } + + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_ASSIGNER_IS_IN_G2_HPP diff --git a/include/nil/blueprint/comparison/comparison.hpp b/include/nil/blueprint/comparison/comparison.hpp index c076a5e0..97ce50d8 100644 --- a/include/nil/blueprint/comparison/comparison.hpp +++ b/include/nil/blueprint/comparison/comparison.hpp @@ -29,6 +29,8 @@ #include "llvm/IR/TypeFinder.h" #include "llvm/IR/TypedPointerType.h" +#include + #include namespace nil { @@ -36,7 +38,7 @@ namespace nil { template typename ComponentType::result_type - handle_comparison_component( + handle_comparison_component_eq_neq( llvm::CmpInst::Predicate p, const typename crypto3::zk::snark::plonk_variable &x, const typename crypto3::zk::snark::plonk_variable &y, @@ -68,6 +70,52 @@ namespace nil { } } + template + typename ComponentType::result_type + handle_comparison_component_others( + llvm::CmpInst::Predicate p, + const typename crypto3::zk::snark::plonk_variable &x, + const typename crypto3::zk::snark::plonk_variable &y, + std::size_t Bitness, + circuit_proxy> &bp, + assignment_proxy> + &assignment, + std::uint32_t start_row, std::uint32_t target_prover_idx) { + + + using comp_component_type = components::comparison< + crypto3::zk::snark::plonk_constraint_system, BlueprintFieldType>; + typename comp_component_type::input_type instance_input({x, y}); + + nil::blueprint::components::comparison_mode Mode; + + switch (p) { + case llvm::CmpInst::ICMP_SGE: + case llvm::CmpInst::ICMP_UGE: + Mode = nil::blueprint::components::comparison_mode::GREATER_EQUAL; + break; + case llvm::CmpInst::ICMP_SGT: + case llvm::CmpInst::ICMP_UGT: + Mode = nil::blueprint::components::comparison_mode::GREATER_THAN; + break; + case llvm::CmpInst::ICMP_SLE: + case llvm::CmpInst::ICMP_ULE: + Mode = nil::blueprint::components::comparison_mode::LESS_EQUAL; + break; + case llvm::CmpInst::ICMP_SLT: + case llvm::CmpInst::ICMP_ULT: + Mode = nil::blueprint::components::comparison_mode::LESS_THAN; + break; + default: + UNREACHABLE("Unsupported icmp predicate"); + break; + } + + return get_component_result + (bp, assignment, start_row, target_prover_idx, instance_input, Mode); + + } + } // namespace blueprint } // namespace nil diff --git a/include/nil/blueprint/component_mockups/bls12_381_pairing.hpp b/include/nil/blueprint/component_mockups/bls12_381_pairing.hpp new file mode 100644 index 00000000..e00f4703 --- /dev/null +++ b/include/nil/blueprint/component_mockups/bls12_381_pairing.hpp @@ -0,0 +1,326 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2023 Alexey Yashunsky +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// +// @file Declaration of the BLS12-381 pairing component +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_BLS12_381_PAIRING_HPP +#define CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_BLS12_381_PAIRING_HPP + +#include + +#include +#include +#include +#include + +#include + +namespace nil { + namespace blueprint { + namespace components { + namespace detail { + template + std::vector base(T x) { + std::vector res = {(unsigned short int)(x % B)}; + if (x > 0) { + x /= B; + while (x > 0) { + res.insert(res.begin(), x % B); + x /= B; + } + } + return res; + } + } + // + // Component for computing the pairing of + // two points: P from E(F_p) and Q from E'(F_p^2) + // for BLS12-381. + // Input: P[2], Q[4] ( we assume P and Q are NOT (0,0), i.e. not the points at infinity, NOT CHECKED ) + // Output: f[12]: an element of F_p^12 + // + // It is just the Miller loop followed by exponentiation. + // We realize the circuit in two versions - 12-column and 24-column. + // + + using namespace detail; + + template + class bls12_381_pairing; + + template + class bls12_381_pairing, + BlueprintFieldType> + : public plonk_component { + + static std::size_t gates_amount_internal(std::size_t witness_amount) { + return + 3 + // miller_loop + ((witness_amount == 12) ? 8 : 9); // bls12_exponentiation + } + + public: + using component_type = plonk_component; + + using var = typename component_type::var; + using manifest_type = plonk_component_manifest; + + class gate_manifest_type : public component_gate_manifest { + public: + std::size_t witness_amount; + + gate_manifest_type(std::size_t witness_amount_) : witness_amount(witness_amount_) {} + + std::uint32_t gates_amount() const override { + return + 3 + // miller_loop + ((witness_amount == 12) ? 8 : 9); // bls12_exponentiation + } + + bool operator<(const component_gate_manifest *other) const override { + return (witness_amount < dynamic_cast(other)->witness_amount); + } + }; + + static gate_manifest get_gate_manifest(std::size_t witness_amount, + std::size_t lookup_column_amount) { + static gate_manifest manifest = + gate_manifest(gate_manifest_type(witness_amount)); + return manifest; + } + + static manifest_type get_manifest() { + static manifest_type manifest = manifest_type( + std::shared_ptr(new manifest_range_param(12,24,12)), // 12 or 24 + false + ); + + return manifest; + } +//////// + constexpr static std::size_t rows_amount_bls12_g2_point_addition(std::size_t witness_amount, + std::size_t lookup_column_amount) { + return 1 + (witness_amount < 24); + } + + + static std::size_t rows_amount_miller_loop(std::size_t witness_amount, + std::size_t lookup_column_amount, unsigned long long C_val) { + std::vector C_bin = base<2>(C_val); + + return (C_bin.size()-1)*2 + // doubling LineFunctions + (std::count(C_bin.begin(),C_bin.end(),1)-1)* // number of Adding blocks + // LineFunction and point adder + (4 + rows_amount_bls12_g2_point_addition(witness_amount, lookup_column_amount)) + + 2; // final result and extra point (for gate uniformity) + } +//////////// + constexpr static std::size_t rows_amount_power_t(std::size_t witness_amount, + std::size_t lookup_column_amount) { + return (witness_amount == 12)? 42 : 22; // 12 -> 42, 24 -> 22 + } + + + constexpr static std::size_t rows_amount_power_tm1sq3_type(std::size_t witness_amount, + std::size_t lookup_column_amount) { + return ((witness_amount == 12)? (59+3) : (32+2)) + // 12 -> 59+3, 24 -> 32+2 + rows_amount_power_t(witness_amount, lookup_column_amount); + } + + constexpr static std::size_t rows_amount_bls12_exponentiation(std::size_t witness_amount, + std::size_t lookup_column_amount) { + return ((witness_amount == 12)? (8 + 3 + 3 + 4 + 10) : (5 + 2 + 2 + 2 + 6)) + + rows_amount_power_tm1sq3_type(witness_amount,lookup_column_amount) + + 3 * rows_amount_power_t(witness_amount, lookup_column_amount); + } +/////// + + + constexpr static std::size_t get_rows_amount(std::size_t witness_amount, + std::size_t lookup_column_amount) { + return rows_amount_miller_loop(witness_amount, lookup_column_amount,0xD201000000010000) + + rows_amount_bls12_exponentiation(witness_amount, lookup_column_amount); + } + + const std::size_t gates_amount = gates_amount_internal(this->witness_amount()); + const std::size_t rows_amount = get_rows_amount(this->witness_amount(), 0); + const std::string component_name = "native_bls12_381_pairing"; + + struct input_type { + std::array P; + std::array Q; + + std::vector> all_vars() { + std::vector> result = {}; + result.push_back(std::ref(P[0])); + result.push_back(std::ref(P[1])); + result.push_back(std::ref(Q[0])); + result.push_back(std::ref(Q[1])); + result.push_back(std::ref(Q[2])); + result.push_back(std::ref(Q[3])); + return result; + } + }; + + struct result_type { + std::array output; + + std::vector all_vars() const { + std::vector res = {}; + + for(auto & e : output) { res.push_back(e); } + return res; + } + }; + + template + explicit bls12_381_pairing(ContainerType witness) : component_type(witness, {}, {}, get_manifest()) { }; + + template + bls12_381_pairing(WitnessContainerType witness, ConstantContainerType constant, + PublicInputContainerType public_input) : + component_type(witness, constant, public_input, get_manifest()) { }; + bls12_381_pairing( + std::initializer_list + witnesses, + std::initializer_list + constants, + std::initializer_list + public_inputs) : + component_type(witnesses, constants, public_inputs, get_manifest()) { }; + }; + + template + using plonk_bls12_381_pairing = + bls12_381_pairing< + crypto3::zk::snark::plonk_constraint_system, + BlueprintFieldType>; + + template + typename plonk_bls12_381_pairing::result_type generate_assignments( + const plonk_bls12_381_pairing &component, + assignment> + &assignment, + const typename plonk_bls12_381_pairing::input_type + &instance_input, + const std::uint32_t start_row_index) { + + using component_type = plonk_bls12_381_pairing; + using var = typename component_type::var; + + std::uint32_t row = start_row_index; + + + typename crypto3::algebra::curves::bls12<381>::template g1_type<>::value_type g1 = { + var_value(assignment, instance_input.P[0]), + var_value(assignment, instance_input.P[1]), + // var_value(assignments[currProverIdx], frame.vectors[inst->getOperand(0)][0]), + // var_value(assignments[currProverIdx], frame.vectors[inst->getOperand(0)][1]), + crypto3::algebra::curves::bls12<381>::template g1_type<>::field_type::value_type::one() + }; + + typename crypto3::algebra::curves::bls12<381>::template g2_type<>::value_type g2 = { + typename crypto3::algebra::curves::bls12<381>::template g2_type<>::field_type::value_type( + var_value(assignment, instance_input.Q[0]), + var_value(assignment, instance_input.Q[1]) + ), + typename crypto3::algebra::curves::bls12<381>::template g2_type<>::field_type::value_type( + var_value(assignment, instance_input.Q[2]), + var_value(assignment, instance_input.Q[3]) + ), + crypto3::algebra::curves::bls12<381>::template g2_type<>::field_type::value_type::one() + }; + + typename crypto3::algebra::curves::bls12<381>::gt_type::value_type gt = + crypto3::algebra::pair>(g1, g2); + + typename plonk_bls12_381_pairing::result_type res; + + assignment.witness(component.W(0), row) = gt.data[0].data[0].data[0]; + res.output[0] = var(component.W(0), row++, false); + assignment.witness(component.W(0), row) = gt.data[0].data[0].data[1]; + res.output[1] = var(component.W(0), row++, false); + assignment.witness(component.W(0), row) = gt.data[0].data[1].data[0]; + res.output[2] = var(component.W(0), row++, false); + assignment.witness(component.W(0), row) = gt.data[0].data[1].data[1]; + res.output[3] = var(component.W(0), row++, false); + assignment.witness(component.W(0), row) = gt.data[0].data[2].data[0]; + res.output[4] = var(component.W(0), row++, false); + assignment.witness(component.W(0), row) = gt.data[0].data[2].data[1]; + res.output[5] = var(component.W(0), row++, false); + assignment.witness(component.W(0), row) = gt.data[1].data[0].data[0]; + res.output[6] = var(component.W(0), row++, false); + assignment.witness(component.W(0), row) = gt.data[1].data[0].data[1]; + res.output[7] = var(component.W(0), row++, false); + assignment.witness(component.W(0), row) = gt.data[1].data[1].data[0]; + res.output[8] = var(component.W(0), row++, false); + assignment.witness(component.W(0), row) = gt.data[1].data[1].data[1]; + res.output[9] = var(component.W(0), row++, false); + assignment.witness(component.W(0), row) = gt.data[1].data[2].data[0]; + res.output[10] = var(component.W(0), row++, false); + assignment.witness(component.W(0), row) = gt.data[1].data[2].data[1]; + res.output[11] = var(component.W(0), row++, false); + + return res; + } + + template + std::vector generate_gates( + const plonk_bls12_381_pairing &component, + circuit> &bp, + assignment> + &assignment, + const typename plonk_bls12_381_pairing::input_type + &instance_input) { + return {}; + } + + template + void generate_copy_constraints( + const plonk_bls12_381_pairing &component, + circuit> &bp, + assignment> + &assignment, + const typename plonk_bls12_381_pairing::input_type &instance_input, + const std::size_t start_row_index) { + } + + template + typename plonk_bls12_381_pairing::result_type generate_circuit( + const plonk_bls12_381_pairing &component, + circuit> &bp, + assignment> + &assignment, + const typename plonk_bls12_381_pairing::input_type &instance_input, + const std::size_t start_row_index) { + + typename plonk_bls12_381_pairing::result_type res; + return res; + } + } // namespace components + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_BLS12_381_PAIRING_HPP diff --git a/include/nil/blueprint/component_mockups/comparison.hpp b/include/nil/blueprint/component_mockups/comparison.hpp new file mode 100644 index 00000000..8840d5da --- /dev/null +++ b/include/nil/blueprint/component_mockups/comparison.hpp @@ -0,0 +1,527 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2021-2022 Mikhail Komarov +// Copyright (c) 2021-2022 Nikita Kaskov +// Copyright (c) 2022 Alisa Cherniaeva +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +// #ifndef CRYPTO3_BLUEPRINT_PLONK_COMPARISON_HPP +// #define CRYPTO3_BLUEPRINT_PLONK_COMPARISON_HPP + +// #include +// #include +// #include +// #include + +// #include +// #include +// #include +// #include + + +/////// +//---------------------------------------------------------------------------// +// Copyright (c) 2023 Dmitrii Tabalin +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_BLUEPRINT_COMPONENTS_NON_NATIVE_comparison_HPP +#define CRYPTO3_BLUEPRINT_COMPONENTS_NON_NATIVE_comparison_HPP + +#include + +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +namespace nil { + namespace blueprint { + namespace components { + + template + class comparison; + + template + class comparison< + crypto3::zk::snark::plonk_constraint_system, + BlueprintFieldType>: + public plonk_component { + + static std::size_t comparisons_per_gate_instance_internal(std::size_t witness_amount) { + return 1 + (witness_amount - 3) / 2; + } + + static std::size_t bits_per_gate_instance_internal(std::size_t witness_amount) { + return comparisons_per_gate_instance_internal(witness_amount) * chunk_size; + } + + static std::size_t rows_amount_internal(std::size_t witness_amount) { + return (256 + bits_per_gate_instance_internal(witness_amount) - 1) / + bits_per_gate_instance_internal(witness_amount) * 2 + + 1 + needs_bonus_row_internal(witness_amount); + } + + static std::size_t gate_instances_internal(std::size_t witness_amount) { + return (rows_amount_internal(witness_amount) - 1) / 2; + } + + static std::size_t padded_chunks_internal(std::size_t witness_amount) { + return gate_instances_internal(witness_amount) * + comparisons_per_gate_instance_internal(witness_amount); + } + + static std::size_t padding_bits_internal(std::size_t witness_amount) { + return padded_chunks_internal(witness_amount) * chunk_size - 256; + } + + static std::size_t padding_size_internal(std::size_t witness_amount) { + return padding_bits_internal(witness_amount) / chunk_size; + } + + static std::size_t gates_amount_internal() { + return 2 + (256 % chunk_size > 0); + } + + static std::size_t needs_bonus_row_internal(std::size_t witness_amount) { + return witness_amount <= 3; + } + + public: + using component_type = plonk_component; + + using var = typename component_type::var; + using manifest_type = nil::blueprint::plonk_component_manifest; + + class gate_manifest_type : public component_gate_manifest { + public: + std::size_t witness_amount; + comparison_mode mode; + + gate_manifest_type(std::size_t witness_amount_, comparison_mode mode_) + : witness_amount(witness_amount_), mode(mode_) {} + + std::uint32_t gates_amount() const override { + return comparison::gates_amount_internal(); + } + + // bool operator<(const component_gate_manifest* other) const override{ + // const gate_manifest_type* other_casted = dynamic_cast(other); + // return witness_amount < other_casted->witness_amount || + // (witness_amount == other_casted->witness_amount && + // bits_amount < other_casted->bits_amount) || + // (witness_amount == other_casted->witness_amount && + // bits_amount == other_casted->bits_amount && + // mode < other_casted->mode); + // } + }; + + static gate_manifest get_gate_manifest(std::size_t witness_amount, + std::size_t lookup_column_amount, + comparison_mode mode) { + gate_manifest manifest = + gate_manifest(gate_manifest_type(witness_amount, mode)); + return manifest; + } + + static manifest_type get_manifest() { + static manifest_type manifest = manifest_type( + std::shared_ptr( + new manifest_range_param(3, (BlueprintFieldType::modulus_bits + 28 - 1) / 28 )), + false + ); + return manifest; + } + + constexpr static std::size_t get_rows_amount(std::size_t witness_amount, + std::size_t lookup_column_amount, + comparison_mode mode) { + return rows_amount_internal(witness_amount); + } + constexpr static std::size_t get_empty_rows_amount() { + return 1; + } + + /* + It's CRITICAL that these three variables remain on top + Otherwise initialization goes in wrong order, leading to arbitrary values. + */ + const comparison_mode mode; + constexpr static const std::size_t chunk_size = 2; + /* Do NOT move the above variables! */ + + const std::size_t comparisons_per_gate_instance = + comparisons_per_gate_instance_internal(this->witness_amount()); + const std::size_t bits_per_gate_instance = + bits_per_gate_instance_internal(this->witness_amount()); + const bool needs_bonus_row = needs_bonus_row_internal(this->witness_amount()); + + const std::size_t rows_amount = rows_amount_internal(this->witness_amount()); + const std::size_t empty_rows_amount = get_empty_rows_amount(); + const std::string component_name = "comparison"; + + + const std::size_t gate_instances = gate_instances_internal(this->witness_amount()); + const std::size_t padded_chunks = padded_chunks_internal(this->witness_amount()); + const std::size_t padding_bits = padding_bits_internal(this->witness_amount()); + const std::size_t padding_size = padding_size_internal(this->witness_amount()); + + const std::size_t gates_amount = gates_amount_internal(); + + struct input_type { + var x, y; + + std::vector> all_vars() { + return {x, y}; + } + }; + + struct result_type { + var flag; + + result_type(const comparison &component, std::size_t start_row_index) { + flag = var(component.W(0), start_row_index, false); + } + + std::vector all_vars() const { + return {flag}; + } + }; + + template + explicit comparison(ContainerType witness, comparison_mode mode_): + component_type(witness, {}, {}, get_manifest()), + mode(mode_) {}; + + template + comparison(WitnessContainerType witness, ConstantContainerType constant, + PublicInputContainerType public_input, + comparison_mode mode_): + component_type(witness, constant, public_input, get_manifest()), + mode(mode_) { + }; + + comparison( + std::initializer_list witnesses, + std::initializer_list constants, + std::initializer_list + public_inputs, + comparison_mode mode_) : + component_type(witnesses, constants, public_inputs, get_manifest()), + mode(mode_) { + }; + + }; + + template + using plonk_comparison = + comparison, BlueprintFieldType>; + + template + typename plonk_comparison::result_type + generate_circuit( + const plonk_comparison + &component, + circuit> + &bp, + assignment> + &assignment, + const typename plonk_comparison::input_type + &instance_input, + const std::uint32_t start_row_index) { + + return typename plonk_comparison::result_type( + component, start_row_index); + } + + template + typename plonk_comparison::result_type + generate_assignments( + const plonk_comparison + &component, + assignment> + &assignment, + const typename plonk_comparison::input_type + &instance_input, + const std::uint32_t start_row_index) { + + std::size_t row = start_row_index; + + using component_type = plonk_comparison; + using value_type = typename BlueprintFieldType::value_type; + using integral_type = typename BlueprintFieldType::integral_type; + + integral_type x = integral_type(var_value(assignment, instance_input.x).data); + integral_type y = integral_type(var_value(assignment, instance_input.y).data); + + assignment.witness(component.W(1), row) = x; + assignment.witness(component.W(2), row) = y; + + bool output; + switch (component.mode) { + case comparison_mode::LESS_THAN: + output = (x < y); + break; + case comparison_mode::LESS_EQUAL: + output = (x <= y); + break; + case comparison_mode::GREATER_THAN: + output = (x > y); + break; + case comparison_mode::GREATER_EQUAL: + output = (x >= y); + break; + } + + assignment.witness(component.W(0), row) = output; + + return typename component_type::result_type(component, start_row_index); + } + + template + typename plonk_comparison::result_type + generate_empty_assignments( + const plonk_comparison + &component, + assignment> + &assignment, + const typename plonk_comparison::input_type + &instance_input, + const std::uint32_t start_row_index) { + std::size_t row = start_row_index; + + using component_type = plonk_comparison; + using value_type = typename BlueprintFieldType::value_type; + using integral_type = typename BlueprintFieldType::integral_type; + + integral_type x = integral_type(var_value(assignment, instance_input.x).data); + integral_type y = integral_type(var_value(assignment, instance_input.y).data); + + assignment.witness(component.W(1), row) = x; + assignment.witness(component.W(2), row) = y; + + bool output; + switch (component.mode) { + case comparison_mode::LESS_THAN: + output = (x < y); + break; + case comparison_mode::LESS_EQUAL: + output = (x <= y); + break; + case comparison_mode::GREATER_THAN: + output = (x > y); + break; + case comparison_mode::GREATER_EQUAL: + output = (x >= y); + break; + } + + assignment.witness(component.W(0), row) = output; + + return typename component_type::result_type(component, start_row_index); + } + + } // namespace components + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_BLUEPRINT_COMPONENTS_NON_NATIVE_comparison_HPP + +//////////// +// namespace nil { +// namespace blueprint { +// namespace components { + +// template +// class comparison; + +// template +// class comparison, +// FieldType> +// : public plonk_component { + +// public: +// using component_type = plonk_component; + + +// constexpr static const std::size_t gates_amount = 0; +// const std::size_t rows_amount = get_rows_amount(this->witness_amount(), 0); +// const std::string component_name = "comparison"; + +// using var = typename component_type::var; +// using manifest_type = nil::blueprint::plonk_component_manifest; + +// class gate_manifest_type : public component_gate_manifest { +// public: +// std::uint32_t gates_amount() const override { +// return comparison::gates_amount; +// } +// }; + +// static gate_manifest get_gate_manifest(std::size_t witness_amount, +// std::size_t lookup_column_amount) { +// static gate_manifest manifest = gate_manifest(gate_manifest_type()); +// return manifest; +// } + + +// static manifest_type get_manifest() { +// using manifest_param = nil::blueprint::manifest_param; +// using manifest_single_value_param = nil::blueprint::manifest_single_value_param; +// static manifest_type manifest = manifest_type( +// std::shared_ptr(new manifest_single_value_param(15)), +// false +// ); +// return manifest; +// } + +// constexpr static std::size_t get_rows_amount(std::size_t witness_amount, +// std::size_t lookup_column_amount) { +// return 0; +// } + +// struct input_type { +// std::array X; +// std::array Y; + +// std::vector> all_vars() { +// std::vector> result; +// result.insert(result.end(), X.begin(), X.end()); +// result.insert(result.end(), Y.begin(), Y.end()); +// return result; +// } +// }; + +// struct result_type { +// var output; + +// result_type(const comparison, +// FieldType> &component, +// std::uint32_t start_row_index) { +// output = var(component.W(0), start_row_index, false); +// } + +// std::vector all_vars() const { +// std::vector result; +// result.push_back(output); +// return result; +// } +// }; + + +// template +// explicit comparison(ContainerType witness) : component_type(witness, {}, {}, get_manifest()) {}; + +// template +// comparison(WitnessContainerType witness, ConstantContainerType constant, +// PublicInputContainerType public_input) : +// component_type(witness, constant, public_input, get_manifest()) {}; + +// comparison(std::initializer_list witnesses, +// std::initializer_list +// constants, +// std::initializer_list +// public_inputs) : +// component_type(witnesses, constants, public_inputs, get_manifest()) {}; +// }; + +// template +// using plonk_comparison = +// comparison, +// FieldType>; + +// template +// typename plonk_comparison::result_type +// generate_assignments( +// const plonk_comparison &component, +// assignment> +// &assignment, +// const typename plonk_comparison::input_type +// instance_input, +// const std::uint32_t start_row_index) { + +// using component_type = plonk_comparison; + +// assignment.witness(component.W(0), start_row_index) = 1; + +// return typename plonk_comparison::result_type( +// component, start_row_index); +// } + + +// template +// typename plonk_comparison::result_type +// generate_circuit( +// const plonk_comparison &component, +// circuit> &bp, +// assignment> +// &assignment, +// const typename plonk_comparison::input_type +// &instance_input, +// const std::size_t start_row_index) { + +// return typename plonk_comparison::result_type( +// component, start_row_index); +// } +// } // namespace components +// } // namespace blueprint +// } // namespace nil + +// #endif // CRYPTO3_BLUEPRINT_PLONK_COMPARISON_HPP diff --git a/include/nil/blueprint/component_mockups/fp12_multiplication.hpp b/include/nil/blueprint/component_mockups/fp12_multiplication.hpp new file mode 100644 index 00000000..0b7562b2 --- /dev/null +++ b/include/nil/blueprint/component_mockups/fp12_multiplication.hpp @@ -0,0 +1,229 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2023 Alexey Yashunsky +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// +// @file Declaration of interfaces for F_p^{12} field multiplication. +// We use towered field extension +// F_p^12 = F_p^6[w]/(w^2 - v), +// F_p^6 = F_p^2[v]/(v^3-(u+1)), +// F_p^2 = F_p[u]/(u^2 - (-1)). +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_FP12_MULTIPLICATION_HPP +#define CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_FP12_MULTIPLICATION_HPP + +#include + +#include +#include +#include +#include + + + +namespace nil { + namespace blueprint { + namespace components { + // F_p^12 multiplication gate + // Input: a[12], b[12] + // Output: c[12] = a*b as elements of F_p^12 + + template + class fp12_multiplication; + + template + class fp12_multiplication, + BlueprintFieldType> + : public plonk_component { + + public: + using component_type = plonk_component; + + using var = typename component_type::var; + using manifest_type = plonk_component_manifest; + + class gate_manifest_type : public component_gate_manifest { + public: + std::uint32_t gates_amount() const override { + return fp12_multiplication::gates_amount; + } + }; + + static gate_manifest get_gate_manifest(std::size_t witness_amount, + std::size_t lookup_column_amount) { + static gate_manifest manifest = gate_manifest(gate_manifest_type()); + return manifest; + } + + static manifest_type get_manifest() { + static manifest_type manifest = manifest_type( + std::shared_ptr(new manifest_range_param(12,36)), // from 12 to 36 + false + ); + return manifest; + } + + constexpr static std::size_t get_rows_amount(std::size_t witness_amount, + std::size_t lookup_column_amount) { + return 36/witness_amount + (36 % witness_amount > 0); + } + + constexpr static const std::size_t gates_amount = 1; + const std::size_t rows_amount = get_rows_amount(this->witness_amount(), 0); + const std::string component_name = "non_native fp12 multiplication"; + + struct input_type { + std::array a; + std::array b; + + std::vector> all_vars() { + std::vector> result = {}; + for (int i = 0; i < a.size(); i++) { + result.push_back(std::ref(a[i])); + result.push_back(std::ref(b[i])); + } + return result; + } + }; + + struct result_type { + std::array output; + + result_type(const fp12_multiplication &component, std::uint32_t start_row_index) { + const std::size_t WA = component.witness_amount(); + + for(std::size_t i = 0; i < 12; i++) { + output[i] = var(component.W((i+24) % WA), start_row_index + (i+24)/WA, false, var::column_type::witness); + } + } + + std::vector all_vars() const { + std::vector res = {}; + + for(auto & e : output) { res.push_back(e); } + return res; + } + }; + + template + explicit fp12_multiplication(ContainerType witness) : component_type(witness, {}, {}, get_manifest()) {}; + + template + fp12_multiplication(WitnessContainerType witness, ConstantContainerType constant, + PublicInputContainerType public_input) : + component_type(witness, constant, public_input, get_manifest()) {}; + + fp12_multiplication( + std::initializer_list + witnesses, + std::initializer_list + constants, + std::initializer_list + public_inputs) : + component_type(witnesses, constants, public_inputs, get_manifest()) {}; + }; + + template + using plonk_fp12_multiplication = + fp12_multiplication< + crypto3::zk::snark::plonk_constraint_system, + BlueprintFieldType>; + + template + typename plonk_fp12_multiplication::result_type generate_assignments( + const plonk_fp12_multiplication &component, + assignment> + &assignment, + const typename plonk_fp12_multiplication::input_type + &instance_input, + const std::uint32_t start_row_index) { + + using value_type = typename BlueprintFieldType::value_type; + + const std::size_t WA = component.witness_amount(); + + std::array a; + std::array b; + + for(std::size_t i = 0; i < 12; i++) { + a[i] = var_value(assignment, instance_input.a[i]); + b[i] = var_value(assignment, instance_input.b[i]); + assignment.witness(component.W(i),start_row_index) = a[i]; + assignment.witness(component.W((12 + i) % WA),start_row_index + (12 + i)/WA) = b[i]; + } + + using policy_type_fp12 = crypto3::algebra::fields::fp12_2over3over2; + using fp12_element = typename policy_type_fp12::value_type; + + fp12_element A = fp12_element({ {a[0],a[1]}, {a[2],a[3]}, {a[4],a[5]} }, { {a[6],a[7]}, {a[8],a[9]}, {a[10],a[11]} }), + B = fp12_element({ {b[0],b[1]}, {b[2],b[3]}, {b[4],b[5]} }, { {b[6],b[7]}, {b[8],b[9]}, {b[10],b[11]} }), + C = A*B; + + for(std::size_t i = 0; i < 12; i++) { + assignment.witness(component.W((24 + i) % WA),start_row_index + (24 + i)/WA) = C.data[i/6].data[(i % 6)/2].data[i % 2]; + } + + return typename plonk_fp12_multiplication::result_type( + component, start_row_index); + } + + template + std::size_t generate_gates( + const plonk_fp12_multiplication &component, + circuit> &bp, + assignment> + &assignment, + const typename plonk_fp12_multiplication::input_type + &instance_input) { + + } + + template + void generate_copy_constraints( + const plonk_fp12_multiplication &component, + circuit> &bp, + assignment> + &assignment, + const typename plonk_fp12_multiplication::input_type &instance_input, + const std::size_t start_row_index) { + + } + + template + typename plonk_fp12_multiplication::result_type generate_circuit( + const plonk_fp12_multiplication &component, + circuit> &bp, + assignment> + &assignment, + const typename plonk_fp12_multiplication::input_type &instance_input, + const std::size_t start_row_index) { + + return typename plonk_fp12_multiplication::result_type( + component, start_row_index); + } + + } // namespace components + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_FP12_MULTIPLICATION_HPP diff --git a/include/nil/blueprint/component_mockups/h2c.hpp b/include/nil/blueprint/component_mockups/h2c.hpp new file mode 100644 index 00000000..4bcd1515 --- /dev/null +++ b/include/nil/blueprint/component_mockups/h2c.hpp @@ -0,0 +1,184 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2021-2022 Mikhail Komarov +// Copyright (c) 2021-2022 Nikita Kaskov +// Copyright (c) 2022 Alisa Cherniaeva +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_BLUEPRINT_PLONK_H2C_HPP +#define CRYPTO3_BLUEPRINT_PLONK_H2C_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include + + +namespace nil { + namespace blueprint { + namespace components { + + template + class h2c; + + template + class h2c, + FieldType> + : public plonk_component { + + public: + using component_type = plonk_component; + + + constexpr static const std::size_t gates_amount = 0; + const std::size_t rows_amount = get_rows_amount(this->witness_amount(), 0); + const std::string component_name = "hash to curve"; + + using var = typename component_type::var; + using manifest_type = nil::blueprint::plonk_component_manifest; + + class gate_manifest_type : public component_gate_manifest { + public: + std::uint32_t gates_amount() const override { + return h2c::gates_amount; + } + }; + + static gate_manifest get_gate_manifest(std::size_t witness_amount, + std::size_t lookup_column_amount) { + static gate_manifest manifest = gate_manifest(gate_manifest_type()); + return manifest; + } + + + static manifest_type get_manifest() { + using manifest_param = nil::blueprint::manifest_param; + using manifest_single_value_param = nil::blueprint::manifest_single_value_param; + static manifest_type manifest = manifest_type( + std::shared_ptr(new manifest_single_value_param(15)), + false + ); + return manifest; + } + + constexpr static std::size_t get_rows_amount(std::size_t witness_amount, + std::size_t lookup_column_amount) { + return 0; + } + + struct input_type { + var input; + + std::vector> all_vars() { + std::vector> result; + result.push_back(input); + return result; + } + }; + + struct result_type { + std::array output; + + result_type(const h2c, + FieldType> &component, + std::uint32_t start_row_index) { + output[0] = var(component.W(0), start_row_index, false); + output[1] = var(component.W(1), start_row_index, false); + } + + std::vector all_vars() const { + std::vector result; + result.push_back(output[0]); + result.push_back(output[1]); + return result; + } + }; + + + template + explicit h2c(ContainerType witness) : component_type(witness, {}, {}, get_manifest()) {}; + + template + h2c(WitnessContainerType witness, ConstantContainerType constant, + PublicInputContainerType public_input) : + component_type(witness, constant, public_input, get_manifest()) {}; + + h2c(std::initializer_list witnesses, + std::initializer_list + constants, + std::initializer_list + public_inputs) : + component_type(witnesses, constants, public_inputs, get_manifest()) {}; + }; + + template + using plonk_h2c = + h2c, + FieldType>; + + template + typename plonk_h2c::result_type + generate_assignments( + const plonk_h2c &component, + assignment> + &assignment, + const typename plonk_h2c::input_type + instance_input, + const std::uint32_t start_row_index) { + + using component_type = plonk_h2c; + + assignment.witness(component.W(0), start_row_index) = 1; + assignment.witness(component.W(1), start_row_index) = 1; + assignment.witness(component.W(2), start_row_index) = var_value(assignment, instance_input.input); + + return typename plonk_h2c::result_type( + component, start_row_index); + } + + + template + typename plonk_h2c::result_type + generate_circuit( + const plonk_h2c &component, + circuit> &bp, + assignment> + &assignment, + const typename plonk_h2c::input_type + &instance_input, + const std::size_t start_row_index) { + + return typename plonk_h2c::result_type( + component, start_row_index); + } + } // namespace components + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_BLUEPRINT_PLONK_H2C_HPP diff --git a/include/nil/blueprint/component_mockups/is_in_g1.hpp b/include/nil/blueprint/component_mockups/is_in_g1.hpp new file mode 100644 index 00000000..ea1f74f3 --- /dev/null +++ b/include/nil/blueprint/component_mockups/is_in_g1.hpp @@ -0,0 +1,180 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2021-2022 Mikhail Komarov +// Copyright (c) 2021-2022 Nikita Kaskov +// Copyright (c) 2022 Alisa Cherniaeva +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_BLUEPRINT_PLONK_IS_IN_G1_HPP +#define CRYPTO3_BLUEPRINT_PLONK_IS_IN_G1_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include + + +namespace nil { + namespace blueprint { + namespace components { + + template + class is_in_g1; + + template + class is_in_g1, + FieldType> + : public plonk_component { + + public: + using component_type = plonk_component; + + + constexpr static const std::size_t gates_amount = 0; + const std::size_t rows_amount = get_rows_amount(this->witness_amount(), 0); + const std::string component_name = "is_in_g1"; + + using var = typename component_type::var; + using manifest_type = nil::blueprint::plonk_component_manifest; + + class gate_manifest_type : public component_gate_manifest { + public: + std::uint32_t gates_amount() const override { + return is_in_g1::gates_amount; + } + }; + + static gate_manifest get_gate_manifest(std::size_t witness_amount, + std::size_t lookup_column_amount) { + static gate_manifest manifest = gate_manifest(gate_manifest_type()); + return manifest; + } + + + static manifest_type get_manifest() { + using manifest_param = nil::blueprint::manifest_param; + using manifest_single_value_param = nil::blueprint::manifest_single_value_param; + static manifest_type manifest = manifest_type( + std::shared_ptr(new manifest_single_value_param(15)), + false + ); + return manifest; + } + + constexpr static std::size_t get_rows_amount(std::size_t witness_amount, + std::size_t lookup_column_amount) { + return 0; + } + + struct input_type { + std::array input; + + std::vector> all_vars() { + std::vector> result; + result.insert(result.end(), input.begin(), input.end()); + return result; + } + }; + + struct result_type { + var output; + + result_type(const is_in_g1, + FieldType> &component, + std::uint32_t start_row_index) { + output = var(component.W(0), start_row_index, false); + } + + std::vector all_vars() const { + std::vector result; + result.push_back(output); + return result; + } + }; + + + template + explicit is_in_g1(ContainerType witness) : component_type(witness, {}, {}, get_manifest()) {}; + + template + is_in_g1(WitnessContainerType witness, ConstantContainerType constant, + PublicInputContainerType public_input) : + component_type(witness, constant, public_input, get_manifest()) {}; + + is_in_g1(std::initializer_list witnesses, + std::initializer_list + constants, + std::initializer_list + public_inputs) : + component_type(witnesses, constants, public_inputs, get_manifest()) {}; + }; + + template + using plonk_is_in_g1 = + is_in_g1, + FieldType>; + + template + typename plonk_is_in_g1::result_type + generate_assignments( + const plonk_is_in_g1 &component, + assignment> + &assignment, + const typename plonk_is_in_g1::input_type + instance_input, + const std::uint32_t start_row_index) { + + using component_type = plonk_is_in_g1; + + assignment.witness(component.W(0), start_row_index) = 1; + + return typename plonk_is_in_g1::result_type( + component, start_row_index); + } + + + template + typename plonk_is_in_g1::result_type + generate_circuit( + const plonk_is_in_g1 &component, + circuit> &bp, + assignment> + &assignment, + const typename plonk_is_in_g1::input_type + &instance_input, + const std::size_t start_row_index) { + + return typename plonk_is_in_g1::result_type( + component, start_row_index); + } + } // namespace components + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_BLUEPRINT_PLONK_IS_IN_G1_HPP diff --git a/include/nil/blueprint/component_mockups/is_in_g2.hpp b/include/nil/blueprint/component_mockups/is_in_g2.hpp new file mode 100644 index 00000000..9b1568c3 --- /dev/null +++ b/include/nil/blueprint/component_mockups/is_in_g2.hpp @@ -0,0 +1,182 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2021-2022 Mikhail Komarov +// Copyright (c) 2021-2022 Nikita Kaskov +// Copyright (c) 2022 Alisa Cherniaeva +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_BLUEPRINT_PLONK_IS_IN_G2_HPP +#define CRYPTO3_BLUEPRINT_PLONK_IS_IN_G2_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include + + +namespace nil { + namespace blueprint { + namespace components { + + template + class is_in_g2; + + template + class is_in_g2, + FieldType> + : public plonk_component { + + public: + using component_type = plonk_component; + + + constexpr static const std::size_t gates_amount = 0; + const std::size_t rows_amount = get_rows_amount(this->witness_amount(), 0); + const std::string component_name = "is_in_g2"; + + using var = typename component_type::var; + using manifest_type = nil::blueprint::plonk_component_manifest; + + class gate_manifest_type : public component_gate_manifest { + public: + std::uint32_t gates_amount() const override { + return is_in_g2::gates_amount; + } + }; + + static gate_manifest get_gate_manifest(std::size_t witness_amount, + std::size_t lookup_column_amount) { + static gate_manifest manifest = gate_manifest(gate_manifest_type()); + return manifest; + } + + + static manifest_type get_manifest() { + using manifest_param = nil::blueprint::manifest_param; + using manifest_single_value_param = nil::blueprint::manifest_single_value_param; + static manifest_type manifest = manifest_type( + std::shared_ptr(new manifest_single_value_param(15)), + false + ); + return manifest; + } + + constexpr static std::size_t get_rows_amount(std::size_t witness_amount, + std::size_t lookup_column_amount) { + return 0; + } + + struct input_type { + std::array X; + std::array Y; + + std::vector> all_vars() { + std::vector> result; + result.insert(result.end(), X.begin(), X.end()); + result.insert(result.end(), Y.begin(), Y.end()); + return result; + } + }; + + struct result_type { + var output; + + result_type(const is_in_g2, + FieldType> &component, + std::uint32_t start_row_index) { + output = var(component.W(0), start_row_index, false); + } + + std::vector all_vars() const { + std::vector result; + result.push_back(output); + return result; + } + }; + + + template + explicit is_in_g2(ContainerType witness) : component_type(witness, {}, {}, get_manifest()) {}; + + template + is_in_g2(WitnessContainerType witness, ConstantContainerType constant, + PublicInputContainerType public_input) : + component_type(witness, constant, public_input, get_manifest()) {}; + + is_in_g2(std::initializer_list witnesses, + std::initializer_list + constants, + std::initializer_list + public_inputs) : + component_type(witnesses, constants, public_inputs, get_manifest()) {}; + }; + + template + using plonk_is_in_g2 = + is_in_g2, + FieldType>; + + template + typename plonk_is_in_g2::result_type + generate_assignments( + const plonk_is_in_g2 &component, + assignment> + &assignment, + const typename plonk_is_in_g2::input_type + instance_input, + const std::uint32_t start_row_index) { + + using component_type = plonk_is_in_g2; + + assignment.witness(component.W(0), start_row_index) = 1; + + return typename plonk_is_in_g2::result_type( + component, start_row_index); + } + + + template + typename plonk_is_in_g2::result_type + generate_circuit( + const plonk_is_in_g2 &component, + circuit> &bp, + assignment> + &assignment, + const typename plonk_is_in_g2::input_type + &instance_input, + const std::size_t start_row_index) { + + return typename plonk_is_in_g2::result_type( + component, start_row_index); + } + } // namespace components + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_BLUEPRINT_PLONK_IS_IN_G2_HPP diff --git a/include/nil/blueprint/handle_component.hpp b/include/nil/blueprint/handle_component.hpp index 363bf7ca..fb3809a0 100644 --- a/include/nil/blueprint/handle_component.hpp +++ b/include/nil/blueprint/handle_component.hpp @@ -58,6 +58,13 @@ #include #include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -106,7 +113,6 @@ namespace nil { } } - template struct has_get_empty_rows_amount{ private: static int detect(...); @@ -154,9 +160,7 @@ namespace nil { ++component_counter[component_instance.component_name]; - rows_per_component[typeid(ComponentType).name()] = component_instance.rows_amount; component_rows[component_instance.component_name] = component_instance.rows_amount; - gates_used[typeid(ComponentType).name()] = component_instance.gates_amount; component_gates[component_instance.component_name] = component_instance.gates_amount; component_witness[component_instance.component_name] = component_instance.witness_amount(); if (unfinished_components.find(component_instance.component_name) != unfinished_components.end()) { @@ -190,6 +194,7 @@ namespace nil { std::cerr << component_instance.component_name; std::cerr << " component\n"; } + if (target_prover_idx == assignment.get_id() || target_prover_idx == std::numeric_limits::max()) { return components::generate_assignments(component_instance, assignment, instance_input, start_row); diff --git a/include/nil/blueprint/parser.hpp b/include/nil/blueprint/parser.hpp index af3b6a30..8a8f4e4c 100644 --- a/include/nil/blueprint/parser.hpp +++ b/include/nil/blueprint/parser.hpp @@ -94,6 +94,13 @@ #include #include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -181,44 +188,25 @@ namespace nil { using eq_component_type = components::equality_flag< crypto3::zk::snark::plonk_constraint_system, BlueprintFieldType>; + using comp_component_type = components::comparison< + crypto3::zk::snark::plonk_constraint_system, BlueprintFieldType>; if (p == llvm::CmpInst::ICMP_EQ || p ==llvm::CmpInst::ICMP_NE) { std::size_t bitness = inst->getOperand(0)->getType()->getPrimitiveSizeInBits(); const auto start_row = assignments[currProverIdx].allocated_rows(); - const auto v = handle_comparison_component( + const auto v = handle_comparison_component_eq_neq( p, lhs, rhs, bitness, circuits[currProverIdx], assignments[currProverIdx], start_row, targetProverIdx); handle_component_result (assignments[currProverIdx], inst, frame, v); } else { - bool res; - - switch (p) { - case llvm::CmpInst::ICMP_SGE: - case llvm::CmpInst::ICMP_UGE:{ - res = (var_value(assignments[currProverIdx], lhs) >= var_value(assignments[currProverIdx], rhs)); - break; - } - case llvm::CmpInst::ICMP_SGT: - case llvm::CmpInst::ICMP_UGT:{ - res = (var_value(assignments[currProverIdx], lhs) > var_value(assignments[currProverIdx], rhs)); - break; - } - case llvm::CmpInst::ICMP_SLE: - case llvm::CmpInst::ICMP_ULE:{ - res = (var_value(assignments[currProverIdx], lhs) <= var_value(assignments[currProverIdx], rhs)); - break; - } - case llvm::CmpInst::ICMP_SLT: - case llvm::CmpInst::ICMP_ULT:{ - res = (var_value(assignments[currProverIdx], lhs) < var_value(assignments[currProverIdx], rhs)); - break; - } - default: - UNREACHABLE("Unsupported icmp predicate"); - break; - } - variables[inst] = put_into_assignment(res); + std::size_t bitness = inst->getOperand(0)->getType()->getPrimitiveSizeInBits(); + const auto start_row = assignments[currProverIdx].allocated_rows(); + const auto v = handle_comparison_component_others( + p, lhs, rhs, bitness, + circuits[currProverIdx], assignments[currProverIdx], start_row, targetProverIdx); + handle_component_result + (assignments[currProverIdx], inst, frame, v); } } @@ -241,7 +229,7 @@ namespace nil { for (size_t i = 0; i < lhs.size(); ++i) { const auto start_row = assignments[currProverIdx].allocated_rows(); - auto v = handle_comparison_component( + auto v = handle_comparison_component_eq_neq( inst->getPredicate(), lhs[i], rhs[i], bitness, circuits[currProverIdx], assignments[currProverIdx], start_row, targetProverIdx); @@ -267,7 +255,7 @@ namespace nil { crypto3::zk::snark::plonk_constraint_system, BlueprintFieldType>; for (size_t i = 0; i < lhs.size(); ++i) { - auto v = handle_comparison_component( + auto v = handle_comparison_component_eq_neq( inst->getPredicate(), lhs[i], rhs[i], 0, circuits[currProverIdx], assignments[currProverIdx], assignments[currProverIdx].allocated_rows(), targetProverIdx); res.emplace_back(v.output); @@ -480,49 +468,7 @@ namespace nil { case llvm::Intrinsic::assigner_optimal_ate_pairing: { if constexpr (std::is_same>::value) { - std::cerr << "warning: __builtin_assigner_bls12_optimal_ate_pairing is an experimental feature, may be not stable\n"; - - ASSERT(frame.vectors[inst->getOperand(0)].size() == 2); - ASSERT(frame.vectors[inst->getOperand(1)].size() == 4); - - typename crypto3::algebra::curves::bls12<381>::template g1_type<>::value_type g1 = { - var_value(assignments[currProverIdx], frame.vectors[inst->getOperand(0)][0]), - var_value(assignments[currProverIdx], frame.vectors[inst->getOperand(0)][1]), - crypto3::algebra::curves::bls12<381>::template g1_type<>::field_type::value_type::one() - }; - - typename crypto3::algebra::curves::bls12<381>::template g2_type<>::value_type g2 = { - typename crypto3::algebra::curves::bls12<381>::template g2_type<>::field_type::value_type( - var_value(assignments[currProverIdx], frame.vectors[inst->getOperand(1)][0]), - var_value(assignments[currProverIdx], frame.vectors[inst->getOperand(1)][1]) - ), - typename crypto3::algebra::curves::bls12<381>::template g2_type<>::field_type::value_type( - var_value(assignments[currProverIdx], frame.vectors[inst->getOperand(1)][2]), - var_value(assignments[currProverIdx], frame.vectors[inst->getOperand(1)][3]) - ), - crypto3::algebra::curves::bls12<381>::template g2_type<>::field_type::value_type::one() - }; - - typename crypto3::algebra::curves::bls12<381>::gt_type::value_type gt = - crypto3::algebra::pair>(g1, g2); - - std::vector res = { - put_into_assignment(gt.data[0].data[0].data[0]), - put_into_assignment(gt.data[0].data[0].data[1]), - put_into_assignment(gt.data[0].data[1].data[0]), - put_into_assignment(gt.data[0].data[1].data[1]), - put_into_assignment(gt.data[0].data[2].data[0]), - put_into_assignment(gt.data[0].data[2].data[1]), - put_into_assignment(gt.data[1].data[0].data[0]), - put_into_assignment(gt.data[1].data[0].data[1]), - put_into_assignment(gt.data[1].data[1].data[0]), - put_into_assignment(gt.data[1].data[1].data[1]), - put_into_assignment(gt.data[1].data[2].data[0]), - put_into_assignment(gt.data[1].data[2].data[1]) - }; - - handle_result - (assignments[currProverIdx], inst, frame, res); + handle_bls12381_pairing(inst, frame, circuits[currProverIdx], assignments[currProverIdx], start_row, targetProverIdx); return true; } else { @@ -532,12 +478,7 @@ namespace nil { case llvm::Intrinsic::assigner_hash_to_curve: { if constexpr (std::is_same>::value) { - std::cerr << "warning: __builtin_assigner_hash_to_curve is an experimental feature, may be not stable\n"; - - std::vector res = {frame.scalars[inst->getOperand(0)], frame.scalars[inst->getOperand(0)]}; - - handle_result - (assignments[currProverIdx], inst, frame, res); + handle_h2c(inst, frame, circuits[currProverIdx], assignments[currProverIdx], start_row, targetProverIdx); return true; } else { @@ -547,10 +488,7 @@ namespace nil { case llvm::Intrinsic::assigner_is_in_g1_check: { if constexpr (std::is_same>::value) { - std::cerr << "warning: __builtin_assigner_is_in_g1_check is an experimental feature, may be not stable\n"; - - handle_result - (assignments[currProverIdx], inst, frame, {zero_var}); + handle_is_in_g1(inst, frame, circuits[currProverIdx], assignments[currProverIdx], start_row, targetProverIdx); return true; } else { @@ -560,10 +498,7 @@ namespace nil { case llvm::Intrinsic::assigner_is_in_g2_check: { if constexpr (std::is_same>::value) { - std::cerr << "warning: __builtin_assigner_is_in_g2_check is an experimental feature, may be not stable\n"; - - handle_result - (assignments[currProverIdx], inst, frame, {zero_var}); + handle_is_in_g2(inst, frame, circuits[currProverIdx], assignments[currProverIdx], start_row, targetProverIdx); return true; } else { @@ -573,45 +508,7 @@ namespace nil { case llvm::Intrinsic::assigner_gt_multiplication: { if constexpr (std::is_same>::value) { - std::cerr << "warning: __builtin_assigner_gt_multiplication is an experimental feature, may be not stable\n"; - - std::vector vars_1 = frame.vectors[inst->getOperand(0)]; - ASSERT(vars_1.size() == 12); - std::vector A = {}; - for(std::size_t i = 0; i < 12; i++) { - A.push_back(var_value(assignments[currProverIdx], vars_1[i])); - } - - std::vector vars_2 = frame.vectors[inst->getOperand(0)]; - ASSERT(vars_2.size() == 12); - std::vector B = {}; - for(std::size_t i = 0; i < 12; i++) { - B.push_back(var_value(assignments[currProverIdx], vars_2[i])); - } - - using fp12_element = typename crypto3::algebra::fields::fp12_2over3over2::value_type; - - - fp12_element e1 = fp12_element({ {A[0],A[1]}, {A[2],A[3]}, {A[4],A[5]} }, { {A[6],A[7]}, {A[8],A[9]}, {A[10],A[11]} }), - e2 = fp12_element({ {B[0],B[1]}, {B[2],B[3]}, {B[4],B[5]} }, { {B[6],B[7]}, {B[8],B[9]}, {B[10],B[11]} }), - e = e1 * e2; - - std::vector res= { - put_into_assignment(e.data[0].data[0].data[0]), - put_into_assignment(e.data[0].data[0].data[1]), - put_into_assignment(e.data[0].data[1].data[0]), - put_into_assignment(e.data[0].data[1].data[1]), - put_into_assignment(e.data[0].data[2].data[0]), - put_into_assignment(e.data[0].data[2].data[1]), - put_into_assignment(e.data[1].data[0].data[0]), - put_into_assignment(e.data[1].data[0].data[1]), - put_into_assignment(e.data[1].data[1].data[0]), - put_into_assignment(e.data[1].data[1].data[1]), - put_into_assignment(e.data[1].data[2].data[0]), - put_into_assignment(e.data[1].data[2].data[1]) }; - - handle_result - (assignments[currProverIdx], inst, frame, res); + handle_fp12_mul(inst, frame, circuits[currProverIdx], assignments[currProverIdx], start_row, targetProverIdx); return true; } else { @@ -689,7 +586,7 @@ namespace nil { using eq_component_type = components::equality_flag< crypto3::zk::snark::plonk_constraint_system, BlueprintFieldType>; - var comparison_result = handle_comparison_component( + var comparison_result = handle_comparison_component_eq_neq( llvm::CmpInst::ICMP_EQ, logical_statement, zero_var, bitness, circuits[currProverIdx], assignments[currProverIdx], assignments[currProverIdx].allocated_rows(), targetProverIdx).output;