Skip to content

Commit

Permalink
non-native field ops #308
Browse files Browse the repository at this point in the history
  • Loading branch information
tshchelovek authored and Iluvmagick committed Dec 23, 2023
1 parent e42f2e7 commit 1438726
Show file tree
Hide file tree
Showing 8 changed files with 398 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,14 @@ namespace nil {
std::size_t lookup_column_amount) {
return rows_amount_internal(witness_amount, lookup_column_amount);
}
constexpr static std::size_t get_empty_rows_amount() {
return 1;
}

constexpr static const std::size_t T = 257;

const std::size_t rows_amount = rows_amount_internal(this->witness_amount(), 0);
const std::size_t empty_rows_amount = get_empty_rows_amount();
constexpr static const std::size_t gates_amount = 1;

struct input_type {
Expand All @@ -133,6 +137,12 @@ namespace nil {
var(component.W(2), start_row_index + 2, false),
var(component.W(3), start_row_index + 2, false)};
}
result_type(const addition &component, std::uint32_t start_row_index, bool skip) {
output = {var(component.W(0), start_row_index, false),
var(component.W(1), start_row_index, false),
var(component.W(2), start_row_index, false),
var(component.W(3), start_row_index, false)};
}

std::vector<var> all_vars() const {
return {output[0], output[1], output[2], output[3]};
Expand All @@ -154,6 +164,64 @@ namespace nil {
std::initializer_list<typename component_type::public_input_container_type::value_type>
public_inputs) :
component_type(witnesses, constants, public_inputs, get_manifest()) {};

static std::array<typename BlueprintFieldType::value_type, 4>
calculate(std::array<typename BlueprintFieldType::value_type, 4> a,
std::array<typename BlueprintFieldType::value_type, 4> b) {
using ed25519_field_type = crypto3::algebra::fields::curve25519_base_field;

typename ed25519_field_type::integral_type base = 1;
typename BlueprintFieldType::integral_type pasta_base = 1;
typename ed25519_field_type::extended_integral_type extended_base = 1;
typename ed25519_field_type::value_type eddsa_a =
typename ed25519_field_type::integral_type(a[0].data) +
typename ed25519_field_type::integral_type(a[1].data) * (base << 66) +
typename ed25519_field_type::integral_type(a[2].data) * (base << 132) +
typename ed25519_field_type::integral_type(a[3].data) * (base << 198);

typename ed25519_field_type::value_type eddsa_b =
typename ed25519_field_type::integral_type(b[0].data) +
typename ed25519_field_type::integral_type(b[1].data) * (base << 66) +
typename ed25519_field_type::integral_type(b[2].data) * (base << 132) +
typename ed25519_field_type::integral_type(b[3].data) * (base << 198);

typename ed25519_field_type::value_type eddsa_r = eddsa_a + eddsa_b;
typename ed25519_field_type::integral_type integral_eddsa_r =
typename ed25519_field_type::integral_type(eddsa_r.data);
typename ed25519_field_type::extended_integral_type eddsa_p = ed25519_field_type::modulus;
typename ed25519_field_type::extended_integral_type integral_eddsa_q =
(typename ed25519_field_type::extended_integral_type(eddsa_a.data) +
typename ed25519_field_type::extended_integral_type(eddsa_b.data) -
typename ed25519_field_type::extended_integral_type(eddsa_r.data)) /
eddsa_p;
typename ed25519_field_type::extended_integral_type pow = extended_base << 257;
typename ed25519_field_type::extended_integral_type minus_eddsa_p = pow - eddsa_p;

std::array<typename BlueprintFieldType::value_type, 4> r;
std::array<typename BlueprintFieldType::value_type, 4> q;
std::array<typename BlueprintFieldType::value_type, 4> p;
typename BlueprintFieldType::integral_type mask = (pasta_base << 66) - 1;
r[0] = (integral_eddsa_r) & (mask);
q[0] = (integral_eddsa_q) & (mask);
p[0] = (minus_eddsa_p) & (mask);
for (std::size_t i = 1; i < 4; i++) {
r[i] = (integral_eddsa_r >> (66 * i)) & (mask);
}
typename BlueprintFieldType::value_type t = a[0] + b[0] + p[0] * q[0];

typename BlueprintFieldType::value_type u0 = t - r[0];

typename BlueprintFieldType::integral_type u0_integral =
typename BlueprintFieldType::integral_type(u0.data) >> 66;
std::array<typename BlueprintFieldType::value_type, 4> u0_chunks;

u0_chunks[0] = u0_integral & ((1 << 22) - 1);
u0_chunks[1] = (u0_integral >> 22) & ((1 << 22) - 1);
u0_chunks[2] = (u0_integral >> 44) & ((1 << 22) - 1);
u0_chunks[3] = (u0_integral >> 66) & (1);

return {r[0], r[1], r[2], r[3]};
}
};

template<typename BlueprintFieldType, typename ArithmetizationParams>
Expand Down Expand Up @@ -276,6 +344,43 @@ namespace nil {
component, start_row_index);
}

template<typename BlueprintFieldType, typename ArithmetizationParams>
typename plonk_ed25519_addition<BlueprintFieldType, ArithmetizationParams>::result_type
generate_empty_assignments(
const plonk_ed25519_addition<BlueprintFieldType, ArithmetizationParams> &component,
assignment<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>>
&assignment,
const typename plonk_ed25519_addition<BlueprintFieldType, ArithmetizationParams>::input_type
instance_input,
const std::uint32_t start_row_index) {

using component_type = plonk_ed25519_addition<BlueprintFieldType, ArithmetizationParams>;

using var = typename plonk_ed25519_addition<BlueprintFieldType, ArithmetizationParams>::var;

std::array<typename BlueprintFieldType::value_type, 4> a = {
typename BlueprintFieldType::integral_type(var_value(assignment, instance_input.A[0]).data),
typename BlueprintFieldType::integral_type(var_value(assignment, instance_input.A[1]).data),
typename BlueprintFieldType::integral_type(var_value(assignment, instance_input.A[2]).data),
typename BlueprintFieldType::integral_type(var_value(assignment, instance_input.A[3]).data)};

std::array<typename BlueprintFieldType::value_type, 4> b = {
typename BlueprintFieldType::integral_type(var_value(assignment, instance_input.B[0]).data),
typename BlueprintFieldType::integral_type(var_value(assignment, instance_input.B[1]).data),
typename BlueprintFieldType::integral_type(var_value(assignment, instance_input.B[2]).data),
typename BlueprintFieldType::integral_type(var_value(assignment, instance_input.B[3]).data)};

auto r = component_type::calculate(a, b);

assignment.witness(component.W(0), start_row_index) = r[0];
assignment.witness(component.W(1), start_row_index) = r[1];
assignment.witness(component.W(2), start_row_index) = r[2];
assignment.witness(component.W(3), start_row_index) = r[3];

return typename plonk_ed25519_addition<BlueprintFieldType, ArithmetizationParams>::result_type(
component, start_row_index, true);
}

template<typename BlueprintFieldType, typename ArithmetizationParams>
std::size_t generate_gates(
const plonk_ed25519_addition<BlueprintFieldType, ArithmetizationParams> &component,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ namespace nil {
bool check_inputs) {
return rows_amount_internal(witness_amount, bits_amount, check_inputs);
}
constexpr static std::size_t get_empty_rows_amount() {
return 1;
}

/*
It's CRITICAL that these two variables remain on top
Expand All @@ -148,6 +151,7 @@ namespace nil {

const bool needs_bonus_row = needs_bonus_row_internal(this->witness_amount());
const std::size_t rows_amount = rows_amount_internal(this->witness_amount(), bits_amount, check_inputs);
const std::size_t empty_rows_amount = get_empty_rows_amount();
constexpr static const std::size_t gates_amount = 1;

enum var_address {
Expand Down Expand Up @@ -185,6 +189,14 @@ namespace nil {
quotient = var(component.W(q_address.second), q_address.first);
remainder = var(component.W(r_address.second), r_address.first);
}
result_type(const division_remainder &component, std::size_t start_row_index, bool skip) {
std::pair<std::size_t, std::size_t>
r_address = component.get_var_address(var_address::R_, start_row_index),
q_address = component.get_var_address(var_address::Q, start_row_index);

quotient = var(component.W(0), start_row_index);
remainder = var(component.W(1), start_row_index);
}

std::vector<var> all_vars() const {
return {quotient, remainder};
Expand Down Expand Up @@ -215,6 +227,18 @@ namespace nil {
range_checks(range_check_amount, range_check_component_type(witnesses, constants,
public_inputs, bits_amount_))
{};

static std::array<typename BlueprintFieldType::value_type, 2> calculate(
std::array<typename BlueprintFieldType::value_type, 2> input) {
using value_type = typename BlueprintFieldType::value_type;
using integral_type = typename BlueprintFieldType::integral_type;

integral_type x_integral = integral_type(input[0].data),
y_integral = integral_type(input[1].data);
integral_type q_integral = y_integral != 0 ? x_integral / y_integral : 0,
r_integral = y_integral != 0 ? x_integral % y_integral : 0;
return {value_type(q_integral), value_type(r_integral)};
}
};

template<typename BlueprintFieldType, typename ArithmetizationParams>
Expand Down Expand Up @@ -407,6 +431,32 @@ namespace nil {

return typename component_type::result_type(component, start_row_index);
}

template<typename BlueprintFieldType, typename ArithmetizationParams>
typename plonk_division_remainder<BlueprintFieldType, ArithmetizationParams>::result_type
generate_empty_assignments(
const plonk_division_remainder<BlueprintFieldType, ArithmetizationParams>
&component,
assignment<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType,
ArithmetizationParams>>
&assignment,
const typename plonk_division_remainder<BlueprintFieldType, ArithmetizationParams>::input_type
&instance_input,
const std::uint32_t start_row_index) {

using component_type = plonk_division_remainder<BlueprintFieldType, ArithmetizationParams>;
using value_type = typename BlueprintFieldType::value_type;
using integral_type = typename BlueprintFieldType::integral_type;

value_type x = var_value(assignment, instance_input.x),
y = var_value(assignment, instance_input.y);
auto res = component_type::calculate({x, y});

assignment.witness(component.W(0), start_row_index) = res[0];
assignment.witness(component.W(1), start_row_index) = res[1];

return typename component_type::result_type(component, start_row_index, true);
}
} // namespace components
} // namespace blueprint
} // namespace nil
Expand Down
Loading

0 comments on commit 1438726

Please sign in to comment.