Skip to content

Commit

Permalink
wip #355
Browse files Browse the repository at this point in the history
  • Loading branch information
vo-nil committed Apr 19, 2024
1 parent 8b77315 commit 35f82e9
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#ifndef CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_MNT4_MILLER_LOOP_HPP
#define CRYPTO3_BLUEPRINT_COMPONENTS_PLONK_MNT4_MILLER_LOOP_HPP

#include <cstdint>
#include <nil/crypto3/algebra/fields/detail/element/fp2.hpp>
#include <nil/crypto3/algebra/fields/fp2.hpp>

Expand All @@ -43,18 +44,19 @@
#include <nil/blueprint/manifest.hpp>

#include <nil/blueprint/components/algebra/fields/plonk/non_native/detail/mnt4_fp4.hpp>
#include <nil/blueprint/components/algebra/fields/plonk/non_native/detail/abstract_fp2.hpp>

namespace nil {
namespace blueprint {
namespace components {
namespace detail {
template<unsigned short int B, typename T>
std::vector<unsigned short int> base(T x) {
std::vector<unsigned short int> res = {(unsigned short int)(x % B)};
template<std::uint8_t B, typename T>
std::vector<std::uint8_t> base(T x) {
std::vector<std::uint8_t> res = {(std::uint8_t)(x % B)};
if (x > 0) {
x /= B;
while (x > 0) {
res.insert(res.begin(), x % B);
res.insert(res.begin(), std::uint8_t(x % B));
x /= B;
}
}
Expand Down Expand Up @@ -111,8 +113,6 @@ namespace nil {

using var = typename component_type::var;
using manifest_type = plonk_component_manifest;
using point_addition_type = mnt4_g2_point_addition<
crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType>>;

class gate_manifest_type : public component_gate_manifest {
public:
Expand All @@ -130,8 +130,7 @@ namespace nil {
std::size_t lookup_column_amount)
{
gate_manifest manifest =
gate_manifest(gate_manifest_type(witness_amount))
.merge_with(point_addition_type::get_gate_manifest(witness_amount,lookup_column_amount));
gate_manifest(gate_manifest_type(witness_amount));
return manifest;
}

Expand All @@ -140,15 +139,15 @@ namespace nil {
static manifest_type manifest = manifest_type(
std::shared_ptr<manifest_param>(new manifest_single_value_param(14)),
true // constant column required
).merge_with(point_addition_type::get_manifest());
);
return manifest;
}

static std::size_t get_rows_amount(
std::size_t witness_amount,
std::size_t lookup_column_amount)
{
std::vector<unsigned short int> C_bin = base<2>(C_val);
std::vector<std::uint8_t> C_bin = base<2>(C_val);

std::size_t result = 0;

Expand All @@ -162,7 +161,7 @@ namespace nil {
}

constexpr static integral_type C_val = mnt4_pairing_params::ate_loop_count;
std::vector<unsigned short int> C_bin = base<2>(C_val);
std::vector<std::uint8_t> C_bin = base<2>(C_val);

constexpr static const std::size_t gates_amount = 2;
const std::size_t rows_amount = get_rows_amount(this->witness_amount(), 0);
Expand Down Expand Up @@ -232,13 +231,11 @@ namespace nil {
using policy_type_fp2 = crypto3::algebra::fields::fp2<BlueprintFieldType>;
using fp2_element = typename policy_type_fp2::value_type;
using curve_point = std::array<fp2_element,2>;
using point_addition_type = typename component_type::point_addition_type;

using curve_type = nil::crypto3::algebra::curves::mnt4<298>;

std::vector<unsigned short int> C_bin = component.C_bin;
std::vector<std::uint8_t> C_bin = component.C_bin;

point_addition_type point_addition_instance( component._W, component._C, component._PI);

value_type
xP = var_value(assignment, instance_input.P[0]),
Expand Down Expand Up @@ -275,10 +272,10 @@ namespace nil {
auto insert_row_doubling = [&double_point, &assignment, &component, &start_row_index, &xP, &yP]
(fp4_element const& f, curve_point& T, std::size_t row)
{
fp4_element x, y, x1, y1, g;
fp4_element x, y, x1, y1, g, three({{3,0},{0,0}});

x = fp4_element::one() * xP;
y = fp4_element::one() * yP;
x = fp4_element({ {xP, 0}, {0, 0} });
y = fp4_element({ {yP, 0}, {0, 0} });

// Untwisting: E'/Fp2 -> E/Fp4
// x * u^-1, y * (uv)^-1
Expand All @@ -296,13 +293,13 @@ namespace nil {
// Y: ((x0,x1),(0,0)) * ((0,0),(1/nr,0)) = ( (0, 0), (x0/nr, x1/nr) )
//
//
value_type nri = fp2_element::params_type::non_residue.inversed();
value_type nri = policy_type_fp2::extension_policy::non_residue.inversed();

x1 = fp4_element({ {T[0].data[1], T[0].data[0]*nri }, {0,0} });
y1 = fp4_element({ {0,0}, {T[1].data[0]*nri, T[1].data[1]*nri}});

fp4_element a(curve_type::g1_type<>::params_type::a,0,0,0);
g = f.pow(2) * ((3*x1.pow(2) + a)*(x-x1)*((2*y1).inversed()) + y1 - y);
fp4_element a({{curve_type::g1_type<>::params_type::a,0},{0,0}});
g = f.pow(2) * ((three*x1.pow(2) + a)*(x-x1)*((y1+y1).inversed()) + y1 - y);

// f
assignment.witness(component.W(0),start_row_index + row) = f.data[0].data[0];
Expand Down Expand Up @@ -335,17 +332,17 @@ namespace nil {
{
fp4_element x, y, x1, y1, x2, y2, l, g;

x = fp4_element::one() * xP;
y = fp4_element::one() * yP;
x = fp4_element({ {xP, 0}, {0, 0} });
y = fp4_element({ {yP, 0}, {0, 0} });

value_type nri = fp2_element::params_type::non_residue.inversed();
value_type nri = policy_type_fp2::extension_policy::non_residue.inversed();

// Untwist T and Q: E'/Fp2 -> E/Fp4
x1 = fp4_element({ {T[0].data[1], T[0].data[0]*nri }, {0,0} });
y1 = fp4_element({ {0, 0}, {T[1].data[0]*nri, T[1].data[1]*nri}});

x2 = fp4_element({ {xQ[1], xQ[0]*nri }, {0,0} });
y2 = fp4_element({ {0,0}, {yQ[0]*nri, yQ[1]*nri}});
x2 = fp4_element({ {Q[0].data[1], Q[0].data[0]*nri }, {0,0} });
y2 = fp4_element({ {0,0}, {Q[1].data[0]*nri, Q[1].data[1]*nri}});

l = (y2-y1)*(x2-x1).inversed();
g = f * (l*(x-x1) + y1 - y);
Expand Down Expand Up @@ -386,7 +383,7 @@ namespace nil {
for(std::size_t i = 1; i < C_bin.size(); ++i) {
f = insert_row_doubling(f, T, rel_row++);
if (C_bin[i]) {
f = insert_row_doubling(f, T, rel_row++);
f = insert_row_addition(f, T, rel_row++);
}
}

Expand Down Expand Up @@ -430,26 +427,55 @@ namespace nil {
{
using var = typename plonk_miller_loop<BlueprintFieldType>::var;
using constraint_type = crypto3::zk::snark::plonk_constraint<BlueprintFieldType>;
using curve_type = nil::crypto3::algebra::curves::mnt4<298>;

/*
using fp2_constraint = detail::abstract_fp2_element<
constraint_type,
typename mnt4_g2_params::field_type::value_type >;
*/

using fp4_constraint = detail::mnt4_fp4_element<BlueprintFieldType>;

fp2_constraint C;

std::vector<std::size_t> gate_list = {};
constraint_type c_zero = constraint_type(), c_one = c_zero + 1;
constraint_type c_a = c_zero + curve_type::g1_type<>::params_type::a;

/* Constraints for the doubling row */

/* 1. f = f_prev^2 * line_doubling(T,T,P)
* 2. T = T_prev + T_prev
* 2. T_next = T + T
*/
std::vector<constraint_type> doubling_constrs = {};
//
// TODO:
// TODO: f
//

// constraint for doubling: Tnext = T + T:
// Tnext.x = (3*T.x^2+a)^2/(2T.y)^2 - 2T.x
// Tnext.y = (3*T.x^2+a)/2T.y *(T.x-Tnext.x)-T.y
//
// Rewrite:
// (Tnext.x +2 * Tx)*(2*T.y)^2 - (3*T.x^2+a)^2 = 0
// (Tnext.y + T.y) * (2*T.y) - (3*T.x^2+a)*(T.x-Tnext.x) =0
//
fp2_constraint one = {c_one, c_zero},
a = {c_a, c_zero},
Tx = {var(component.W(6), 0, true), var(component.W(7), 0, true)},
Ty = {var(component.W(8), 0, true), var(component.W(9), 0, true)},
Tnx = {var(component.W(6), 1, true), var(component.W(7), 1, true)},
Tny = {var(component.W(8), 1, true), var(component.W(9), 1, true)};

C = (Tnx + 2*Tx)*(2*Ty)*(2*Ty) - (3*Tx*Tx + a)*(3*Tx*Tx + a);
doubling_constrs.push_back(C[0]);
doubling_constrs.push_back(C[1]);

C = (Tny + Ty)*(2*Ty) - (3*Tx*Tx + a)*(Tx - Tnx);
doubling_constrs.push_back(C[0]);
doubling_constrs.push_back(C[1]);

// Should we check for zero ?

gate_list.push_back(bp.add_gate(doubling_constrs));

/* Constraints for the addition row */
Expand All @@ -459,8 +485,31 @@ namespace nil {
*/
std::vector<constraint_type> adding_constrs = {};
//
// TODO:
// TODO: f
//

// constraint for addition: Tnext = T + Q:
// Tnext.x = (Q.y - T.y)^2/(Q.x - T.x)^2- T.x - Q.x
// Tnext.y = (Q.y - T.y)/(Q.x - T.x)*(T.x - Tnext.x) - Q.y
//
// Rewrite:
// (Tnext.x + T.x + Q.x)*(Q.x - T.x)^2 - (Q.y - T.y)^2 = 0
// (Tnext.y + Q.y)*(Q.x - T.x) - (Q.y - T.y) * (T.x - Tnext.x) = 0
//
fp2_constraint
Qx = {var(component.W(10), 0, true), var(component.W(11), 0, true)},
Qy = {var(component.W(12), 0, true), var(component.W(13), 0, true)};

C = (Tnx + Tx + Qx)*(Qx - Tx)*(Qx - Tx) - (Qy - Ty)*(Qy - Ty);
adding_constrs.push_back(C[0]);
adding_constrs.push_back(C[1]);

C = (Tny + Qy)*(Qx - Tx) - (Qy - Ty)*(Tx - Tnx);
adding_constrs.push_back(C[0]);
adding_constrs.push_back(C[1]);

// Should we check for zero?

gate_list.push_back(bp.add_gate(adding_constrs));

return gate_list;
Expand Down Expand Up @@ -492,6 +541,12 @@ namespace nil {
var(0, start_row_index, false, var::column_type::constant),
var(component.W(3), start_row_index, false)});

/* T on the first row is Q */
bp.add_copy_constraint({var(component.W(6), start_row_index), instance_input.Q[0]});
bp.add_copy_constraint({var(component.W(7), start_row_index), instance_input.Q[1]});
bp.add_copy_constraint({var(component.W(8), start_row_index), instance_input.Q[2]});
bp.add_copy_constraint({var(component.W(9), start_row_index), instance_input.Q[3]});

std::size_t row = 0;

/* Copy P and Q along the circuit */
Expand Down Expand Up @@ -523,9 +578,6 @@ namespace nil {
{
using component_type = plonk_miller_loop<BlueprintFieldType>;
using var = typename component_type::var;
using point_addition_type = typename component_type::point_addition_type;

point_addition_type point_addition_instance( component._W, component._C, component._PI);

std::vector<std::size_t> selector_index = generate_gates(component, bp, assignment, instance_input);

Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ set(HASHES_TESTS_FILES
"hashes/r1cs/pedersen")

set(PAIRING_TESTS_FILES
"algebra/pairing/weierstrass/plonk/mnt4_pairing"
"algebra/pairing/weierstrass/r1cs/miller_loop"
"algebra/pairing/weierstrass/r1cs/precomputation")

Expand Down

0 comments on commit 35f82e9

Please sign in to comment.