Skip to content

Commit

Permalink
rewrite tests for non native field operations #107
Browse files Browse the repository at this point in the history
  • Loading branch information
CblPOK-git committed Jan 26, 2023
1 parent 2ff2d19 commit c63077b
Show file tree
Hide file tree
Showing 4 changed files with 337 additions and 48 deletions.
116 changes: 90 additions & 26 deletions test/algebra/fields/plonk/non_native/addition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,32 @@

#include <boost/test/unit_test.hpp>

#include <nil/crypto3/algebra/fields/bls12/scalar_field.hpp>
#include <nil/crypto3/algebra/curves/vesta.hpp>
#include <nil/crypto3/algebra/fields/arithmetic_params/vesta.hpp>
#include <nil/crypto3/algebra/curves/pallas.hpp>
#include <nil/crypto3/algebra/fields/arithmetic_params/pallas.hpp>

#include <nil/crypto3/algebra/curves/ed25519.hpp>
#include <nil/crypto3/algebra/fields/arithmetic_params/ed25519.hpp>
#include <nil/crypto3/algebra/random_element.hpp>
#include <nil/crypto3/random/algebraic_engine.hpp>

#include <nil/crypto3/hash/keccak.hpp>

#include <nil/blueprint/blueprint/plonk/circuit.hpp>
#include <nil/blueprint/blueprint/plonk/assignment.hpp>
#include <nil/blueprint/components/algebra/fields/plonk/non_native/addition.hpp>

#include <../test/algebra/fields/plonk/non_native/chop_and_glue_non_native.hpp>

#include "../../../../test_plonk_component.hpp"

using namespace nil;

template <typename BlueprintFieldType>
void test_field_add(std::vector<typename BlueprintFieldType::value_type> public_input){
template <typename BlueprintFieldType, typename NonNativeFieldType>
void test_field_add(std::vector<typename BlueprintFieldType::value_type> public_input,
std::array<typename BlueprintFieldType::value_type, 4> expected_res){

using ed25519_type = crypto3::algebra::curves::ed25519;
constexpr std::size_t WitnessColumns = 9;
constexpr std::size_t PublicInputColumns = 1;
constexpr std::size_t ConstantColumns = 0;
Expand All @@ -63,7 +68,7 @@ void test_field_add(std::vector<typename BlueprintFieldType::value_type> public_
using var = crypto3::zk::snark::plonk_variable<BlueprintFieldType>;

using component_type = blueprint::components::addition<ArithmetizationType,
typename ed25519_type::base_field_type, 9, blueprint::basic_non_native_policy<BlueprintFieldType>>;
NonNativeFieldType, 9, blueprint::basic_non_native_policy<BlueprintFieldType>>;

std::array<var, 4> input_var_a = {
var(0, 0, false, var::column_type::public_input), var(0, 1, false, var::column_type::public_input),
Expand All @@ -74,8 +79,40 @@ void test_field_add(std::vector<typename BlueprintFieldType::value_type> public_

typename component_type::input_type instance_input = {input_var_a, input_var_b};

auto result_check = [](AssignmentType &assignment,
auto result_check = [&expected_res, public_input](AssignmentType &assignment,
typename component_type::result_type &real_res) {
#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED
std::array<typename BlueprintFieldType::value_type, 4> x, y, expected_chunks, real_chunks;
for (std::size_t i = 0; i < 4; i++) {
x[i] = public_input[i];
y[i] = public_input[i+4];
expected_chunks[i] = expected_res[i];
real_chunks[i] = var_value(assignment, real_res.output[i]);
}

std::cout << std::hex;

std::cout << "_________________________________________________________________________________________________________________________________________________\n";
std::cout << "input : ";
for (std::size_t i = 0; i < 4; i++) {std::cout << x[3-i].data << " ";}
std::cout << "(" << glue_non_native<BlueprintFieldType, NonNativeFieldType>(x).data << ")\n";

std::cout << " ";
for (std::size_t i = 0; i < 4; i++) {std::cout << y[3-i].data << " ";}
std::cout << "(" << glue_non_native<BlueprintFieldType, NonNativeFieldType>(y).data << ")\n";

std::cout << "expected: ";
for (std::size_t i = 0; i < 4; i++) {std::cout << expected_chunks[3-i].data << " ";}
std::cout << "(" << glue_non_native<BlueprintFieldType, NonNativeFieldType>(expected_chunks).data << ")\n";

std::cout << "real : ";
for (std::size_t i = 0; i < 4; i++) {std::cout << real_chunks[3-i].data << " ";}
std::cout << "(" << glue_non_native<BlueprintFieldType, NonNativeFieldType>(real_chunks).data << ")\n";
#endif

for (std::size_t i = 0; i < 4; i++) {
assert(expected_res[i] == var_value(assignment, real_res.output[i]));
}
};

component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8},{},{});
Expand All @@ -84,30 +121,57 @@ void test_field_add(std::vector<typename BlueprintFieldType::value_type> public_
component_instance, public_input, result_check, instance_input);
}

BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite)

BOOST_AUTO_TEST_CASE(blueprint_non_native_addition_test0) {
test_field_add<typename crypto3::algebra::curves::pallas::base_field_type>(
{45524, 52353, 68769, 5431, 3724, 342453, 5425, 54222});
template <typename FieldType, typename NonNativeFieldType>
void test_field_add_useable(typename NonNativeFieldType::value_type a, typename NonNativeFieldType::value_type b){
using chunked_non_native_type = std::array<typename FieldType::value_type, 4>;
chunked_non_native_type first = chop_non_native<FieldType, NonNativeFieldType>(a);
chunked_non_native_type second = chop_non_native<FieldType, NonNativeFieldType>(b);
chunked_non_native_type expected_result = chop_non_native<FieldType, NonNativeFieldType>(a + b);
std::vector<typename FieldType::value_type> public_input = create_public_input<FieldType, NonNativeFieldType>(first, second);
test_field_add<FieldType, NonNativeFieldType>(public_input, expected_result);
}

BOOST_AUTO_TEST_CASE(blueprint_non_native_addition_test1) {

using ed25519_type = crypto3::algebra::curves::ed25519;
template <typename FieldType, typename NonNativeFieldType>
void test_field_add_all_cases(){
nil::crypto3::random::algebraic_engine<NonNativeFieldType> rand;
boost::random::mt19937 seed_seq;
rand.seed(seed_seq);

typename NonNativeFieldType::value_type f = 0xf;
typename NonNativeFieldType::integral_type f_integral;
for (std::size_t i = 0; i < 63; i++) {
f_integral = typename NonNativeFieldType::integral_type(f.data);
f_integral = (f_integral << 4) + 0xf;
f = typename NonNativeFieldType::value_type(f_integral);
test_field_add_useable<FieldType, NonNativeFieldType>(f, f);
}


test_field_add_useable<FieldType, NonNativeFieldType>(0, 0);
test_field_add_useable<FieldType, NonNativeFieldType>(1, 1);
test_field_add_useable<FieldType, NonNativeFieldType>(-1, -1);
test_field_add_useable<FieldType, NonNativeFieldType>(1, -1);
test_field_add_useable<FieldType, NonNativeFieldType>(-1, 0);
test_field_add_useable<FieldType, NonNativeFieldType>(1000, -1000);
test_field_add_useable<FieldType, NonNativeFieldType>(
glue_non_native<FieldType, NonNativeFieldType>({45524, 52353, 68769, 5431}),
glue_non_native<FieldType, NonNativeFieldType>({3724, 342453, 5425, 54222}));

test_field_add_useable<FieldType, NonNativeFieldType>(
glue_non_native<FieldType, NonNativeFieldType>({1,1,1,1}),
glue_non_native<FieldType, NonNativeFieldType>({1,1,1,1}));

for (std::size_t i = 0; i < 10; i++) {
test_field_add_useable<FieldType, NonNativeFieldType>(rand(), rand());
}

typename ed25519_type::base_field_type::integral_type a =
ed25519_type::base_field_type::integral_type(
crypto3::algebra::random_element<ed25519_type::base_field_type>().data);
typename ed25519_type::base_field_type::integral_type b =
ed25519_type::base_field_type::integral_type(
crypto3::algebra::random_element<ed25519_type::base_field_type>().data);

typename ed25519_type::base_field_type::integral_type base = 1;
typename ed25519_type::base_field_type::integral_type mask = (base << 66) - 1;
}
BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite)

test_field_add<typename crypto3::algebra::curves::pallas::base_field_type>(
{a & mask, (a >> 66) & mask, (a >> 132) & mask, (a >> 198) & mask,
b & mask, (b >> 66) & mask, (b >> 132) & mask, (b >> 198) & mask});
BOOST_AUTO_TEST_CASE(blueprint_non_native_addition_pallas) {
using non_native_field_type = typename crypto3::algebra::fields::curve25519_base_field;
using field_type = crypto3::algebra::curves::pallas::base_field_type;
test_field_add_all_cases<field_type, non_native_field_type>();
}

BOOST_AUTO_TEST_SUITE_END()
50 changes: 50 additions & 0 deletions test/algebra/fields/plonk/non_native/chop_and_glue_non_native.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
template<typename FieldType, typename NonNativeFieldType>
std::array<typename FieldType::value_type, 4> chop_non_native(typename NonNativeFieldType::value_type input) {
typename NonNativeFieldType::integral_type input_integral =
typename NonNativeFieldType::integral_type(
input.data);

std::array<typename FieldType::value_type, 4> output;

typename NonNativeFieldType::integral_type base = 1;
typename NonNativeFieldType::integral_type mask = (base << 66) - 1;

output[0] = input_integral & mask;
output[1] = (input_integral >> 66) & mask;
output[2] = (input_integral >> 132) & mask;
output[3] = (input_integral >> 198) & mask;

return output;
}

template<typename FieldType, typename NonNativeFieldType>
typename NonNativeFieldType::value_type glue_non_native(std::array<typename FieldType::value_type, 4> input) {
typename NonNativeFieldType::integral_type base = 1;
typename NonNativeFieldType::integral_type chunk_size = (base << 66);

std::array<typename FieldType::integral_type, 4> input_integral;

for (std::size_t i = 0; i < input.size(); i++) {
assert(input[i] < chunk_size);
input_integral[i] = typename FieldType::integral_type(input[i].data);
}

typename NonNativeFieldType::integral_type output_integral
= input_integral[0] + (input_integral[1] << 66) + (input_integral[2] << 132) + (input_integral[3] << 198);

typename NonNativeFieldType::value_type output = typename NonNativeFieldType::value_type (output_integral);

return output;
}

template <typename FieldType, typename NonNativeFieldType>
std::vector<typename FieldType::value_type> create_public_input(std::array<typename FieldType::value_type, 4> a, std::array<typename FieldType::value_type, 4> b) {
std::vector<typename FieldType::value_type> public_input;
for (std::size_t i = 0; i < a.size(); i++){
public_input.push_back(a[i]);
}
for (std::size_t i = 0; i < b.size(); i++){
public_input.push_back(b[i]);
}
return public_input;
}
111 changes: 101 additions & 10 deletions test/algebra/fields/plonk/non_native/multiplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,17 @@
#include <nil/blueprint/blueprint/plonk/assignment.hpp>
#include <nil/blueprint/components/algebra/fields/plonk/non_native/multiplication.hpp>

#include <nil/crypto3/random/algebraic_engine.hpp>
#include <../test/algebra/fields/plonk/non_native/chop_and_glue_non_native.hpp>

#include "../../../../test_plonk_component.hpp"

using namespace nil;

template <typename BlueprintFieldType>
void test_field_mul(std::vector<typename BlueprintFieldType::value_type> public_input){

using ed25519_type = crypto3::algebra::curves::ed25519;
template <typename BlueprintFieldType, typename NonNativeFieldType>
void test_field_mul(std::vector<typename BlueprintFieldType::value_type> public_input,
std::array<typename BlueprintFieldType::value_type, 4> expected_res){

constexpr std::size_t WitnessColumns = 9;
constexpr std::size_t PublicInputColumns = 1;
constexpr std::size_t ConstantColumns = 0;
Expand All @@ -64,7 +67,7 @@ void test_field_mul(std::vector<typename BlueprintFieldType::value_type> public_
using var = crypto3::zk::snark::plonk_variable<BlueprintFieldType>;

using component_type = blueprint::components::multiplication<ArithmetizationType,
typename ed25519_type::base_field_type, 9, blueprint::basic_non_native_policy<BlueprintFieldType>>;
NonNativeFieldType, 9, blueprint::basic_non_native_policy<BlueprintFieldType>>;

std::array<var, 4> input_var_a = {
var(0, 0, false, var::column_type::public_input), var(0, 1, false, var::column_type::public_input),
Expand All @@ -75,8 +78,41 @@ void test_field_mul(std::vector<typename BlueprintFieldType::value_type> public_

typename component_type::input_type instance_input = {input_var_a, input_var_b};

auto result_check = [](AssignmentType &assignment,
auto result_check = [&expected_res, public_input](AssignmentType &assignment,
typename component_type::result_type &real_res) {

#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED
std::array<typename BlueprintFieldType::value_type, 4> x, y, expected_chunks, real_chunks;
for (std::size_t i = 0; i < 4; i++) {
x[i] = public_input[i];
y[i] = public_input[i+4];
expected_chunks[i] = expected_res[i];
real_chunks[i] = var_value(assignment, real_res.output[i]);
}

std::cout << std::hex;

std::cout << "_________________________________________________________________________________________________________________________________________________\n";
std::cout << "input : ";
for (std::size_t i = 0; i < 4; i++) {std::cout << x[3-i].data << " ";}
std::cout << "(" << glue_non_native<BlueprintFieldType, NonNativeFieldType>(x).data << ")\n";

std::cout << " ";
for (std::size_t i = 0; i < 4; i++) {std::cout << y[3-i].data << " ";}
std::cout << "(" << glue_non_native<BlueprintFieldType, NonNativeFieldType>(y).data << ")\n";

std::cout << "expected: ";
for (std::size_t i = 0; i < 4; i++) {std::cout << expected_chunks[3-i].data << " ";}
std::cout << "(" << glue_non_native<BlueprintFieldType, NonNativeFieldType>(expected_chunks).data << ")\n";

std::cout << "real : ";
for (std::size_t i = 0; i < 4; i++) {std::cout << real_chunks[3-i].data << " ";}
std::cout << "(" << glue_non_native<BlueprintFieldType, NonNativeFieldType>(real_chunks).data << ")\n";
#endif

for (std::size_t i = 0; i < 4; i++) {
assert(expected_res[i] == var_value(assignment, real_res.output[i]));
}
};

component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8},{},{});
Expand All @@ -87,10 +123,65 @@ void test_field_mul(std::vector<typename BlueprintFieldType::value_type> public_

BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite)

BOOST_AUTO_TEST_CASE(blueprint_non_native_multiplication_test0) {
test_field_mul<typename crypto3::algebra::curves::pallas::base_field_type>(
{0xc801afd_cppui255, 0xc801afd_cppui255, 0xc801afd_cppui255, 0xc801afd_cppui255,
0xc801afd_cppui255, 0xc801afd_cppui255, 0xc801afd_cppui255, 0xc801afd_cppui255});
template <typename FieldType, typename NonNativeFieldType>
void test_field_mul_useable(typename NonNativeFieldType::value_type a, typename NonNativeFieldType::value_type b){
using chunked_non_native_type = std::array<typename FieldType::value_type, 4>;
chunked_non_native_type first = chop_non_native<FieldType, NonNativeFieldType>(a);
chunked_non_native_type second = chop_non_native<FieldType, NonNativeFieldType>(b);
chunked_non_native_type expected_result = chop_non_native<FieldType, NonNativeFieldType>(a * b);
std::vector<typename FieldType::value_type> public_input = create_public_input<FieldType, NonNativeFieldType>(first, second);
test_field_mul<FieldType, NonNativeFieldType>(public_input, expected_result);
}

template <typename FieldType, typename NonNativeFieldType>
void test_field_mul_all_cases(){
nil::crypto3::random::algebraic_engine<NonNativeFieldType> rand;
boost::random::mt19937 seed_seq;
rand.seed(seed_seq);

typename NonNativeFieldType::value_type f = 0xf;
typename NonNativeFieldType::integral_type f_integral;
for (std::size_t i = 0; i < 63; i++) {
f_integral = typename NonNativeFieldType::integral_type(f.data);
f_integral = (f_integral << 4) + 0xf;
f = typename NonNativeFieldType::value_type(f_integral);
test_field_mul_useable<FieldType, NonNativeFieldType>(f, f);
}

test_field_mul_useable<FieldType, NonNativeFieldType>(0, 0);
test_field_mul_useable<FieldType, NonNativeFieldType>(1, 1);
test_field_mul_useable<FieldType, NonNativeFieldType>(-1, -1);
test_field_mul_useable<FieldType, NonNativeFieldType>(1, -1);
test_field_mul_useable<FieldType, NonNativeFieldType>(-1, 0);
test_field_mul_useable<FieldType, NonNativeFieldType>(1000, -1000);
test_field_mul_useable<FieldType, NonNativeFieldType>(
glue_non_native<FieldType, NonNativeFieldType>({45524, 52353, 68769, 5431}),
glue_non_native<FieldType, NonNativeFieldType>({3724, 342453, 5425, 54222}));

test_field_mul_useable<FieldType, NonNativeFieldType>(
glue_non_native<FieldType, NonNativeFieldType>({1,1,1,1}),
glue_non_native<FieldType, NonNativeFieldType>({1,1,1,1}));

test_field_mul_useable<FieldType, NonNativeFieldType>(
glue_non_native<FieldType, NonNativeFieldType>({1,0,0,0}),
glue_non_native<FieldType, NonNativeFieldType>({1,0,0,0}));

test_field_mul_useable<FieldType, NonNativeFieldType>(
glue_non_native<FieldType, NonNativeFieldType>({0x2BCA8C5A0FDF3D53E_cppui253, 0x39840DDF4C421B2D5_cppui253, 0x24FCE5728D26931CA_cppui253, 0xFBD6153B4CE63_cppui253}),
glue_non_native<FieldType, NonNativeFieldType>({0x3CD7BA9506A76AA1C_cppui253, 0x15C58810F101DDB2F_cppui253, 0x1AA5750251F6DA658_cppui253, 0x1323F61B67242F_cppui253}));

test_field_mul_useable<FieldType, NonNativeFieldType>(
glue_non_native<FieldType, NonNativeFieldType>({0xc801afd_cppui255, 0xc801afd_cppui255, 0xc801afd_cppui255, 0xc801afd_cppui255}),
glue_non_native<FieldType, NonNativeFieldType>({0xc801afd_cppui255, 0xc801afd_cppui255, 0xc801afd_cppui255, 0xc801afd_cppui255}));
for (std::size_t i = 0; i < 10; i++) {
test_field_mul_useable<FieldType, NonNativeFieldType>(rand(), rand());
}
}

BOOST_AUTO_TEST_CASE(blueprint_non_native_multiplication_pallas) {
using non_native_field_type = typename crypto3::algebra::fields::curve25519_base_field;
using field_type = crypto3::algebra::curves::pallas::base_field_type;
test_field_mul_all_cases<field_type, non_native_field_type>();
}

BOOST_AUTO_TEST_SUITE_END()
Loading

0 comments on commit c63077b

Please sign in to comment.