Skip to content

Commit

Permalink
rewrite tests, add bls12 field, update random elements generation #107
Browse files Browse the repository at this point in the history
  • Loading branch information
CblPOK-git committed Jan 25, 2023
1 parent fc390d1 commit 2ff2d19
Show file tree
Hide file tree
Showing 8 changed files with 701 additions and 232 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ namespace nil {

};

template<typename BlueprintFieldType, typename ArithmetizationParams, std::size_t ExponentSize, std::int32_t WitnessesAmount>
template<typename BlueprintFieldType, typename ArithmetizationParams, std::size_t ExponentSize, std::uint32_t WitnessesAmount>
using plonk_exponentiation =
exponentiation<
crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>,
Expand Down
148 changes: 140 additions & 8 deletions test/algebra/curves/plonk/endo_scalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include <nil/crypto3/algebra/fields/arithmetic_params/pallas.hpp>
#include <nil/crypto3/algebra/curves/vesta.hpp>
#include <nil/crypto3/algebra/fields/arithmetic_params/vesta.hpp>
#include <nil/crypto3/algebra/random_element.hpp>
#include <nil/crypto3/random/algebraic_engine.hpp>

#include <nil/crypto3/hash/algorithm/hash.hpp>
#include <nil/crypto3/hash/sha2.hpp>
Expand All @@ -47,9 +47,94 @@

#include "test_plonk_component.hpp"

template<typename CurveType>
struct endo_scalar_params;

template<>
struct endo_scalar_params<nil::crypto3::algebra::curves::vesta> {
using curve_type = nil::crypto3::algebra::curves::vesta;
using scalar_field_type = typename curve_type::scalar_field_type;
using base_field_type = typename curve_type::base_field_type;
constexpr static const typename scalar_field_type::value_type endo_r =
0x12CCCA834ACDBA712CAAD5DC57AAB1B01D1F8BD237AD31491DAD5EBDFDFE4AB9_cppui255;
constexpr static const typename base_field_type::value_type endo_q =
0x2D33357CB532458ED3552A23A8554E5005270D29D19FC7D27B7FD22F0201B547_cppui255;
};

template<>
struct endo_scalar_params<nil::crypto3::algebra::curves::pallas> {
using curve_type = nil::crypto3::algebra::curves::pallas;
using scalar_field_type = typename curve_type::scalar_field_type;
using base_field_type = typename curve_type::base_field_type;
constexpr static const typename scalar_field_type::value_type endo_r =
0x397E65A7D7C1AD71AEE24B27E308F0A61259527EC1D4752E619D1840AF55F1B1_cppui255;
constexpr static const typename base_field_type::value_type endo_q =
0x2D33357CB532458ED3552A23A8554E5005270D29D19FC7D27B7FD22F0201B547_cppui255;
};

template<typename CurveType, std::size_t ScalarSize>
typename CurveType::scalar_field_type::value_type calculate_endo_scalar(typename CurveType::scalar_field_type::value_type scalar) {

using endo_params = endo_scalar_params<CurveType>;
using BlueprintFieldType = typename CurveType::scalar_field_type;

typename BlueprintFieldType::value_type endo_r = endo_params::endo_r;

const std::size_t crumbs_per_row = 8;
const std::size_t bits_per_crumb = 2;
const std::size_t bits_per_row =
bits_per_crumb * crumbs_per_row; // we suppose that ScalarSize % bits_per_row = 0

typename BlueprintFieldType::integral_type integral_scalar =
typename BlueprintFieldType::integral_type(scalar.data);
std::array<bool, ScalarSize> bits_msb;
{
nil::marshalling::status_type status;
assert(ScalarSize <= 255);
std::array<bool, 255> bits_msb_all =
nil::marshalling::pack<nil::marshalling::option::big_endian>(integral_scalar, status);
assert(status == nil::marshalling::status_type::success);
std::copy(bits_msb_all.end() - ScalarSize, bits_msb_all.end(), bits_msb.begin());

for(std::size_t i = 0; i < 255 - ScalarSize; ++i) {
assert(bits_msb_all[i] == false);
}
}
typename BlueprintFieldType::value_type a = 2;
typename BlueprintFieldType::value_type b = 2;
typename BlueprintFieldType::value_type n = 0;

assert (ScalarSize % bits_per_row == 0);
for (std::size_t chunk_start = 0; chunk_start < bits_msb.size(); chunk_start += bits_per_row) {
for (std::size_t j = 0; j < crumbs_per_row; j++) {
std::size_t crumb = chunk_start + j * bits_per_crumb;
typename BlueprintFieldType::value_type b0 = static_cast<int>(bits_msb[crumb + 1]);
typename BlueprintFieldType::value_type b1 = static_cast<int>(bits_msb[crumb + 0]);

typename BlueprintFieldType::value_type crumb_value = b0 + b1.doubled();

a = a.doubled();
b = b.doubled();

typename BlueprintFieldType::value_type s =
(b0 == BlueprintFieldType::value_type::one()) ? 1 : -1;
if (b1 == BlueprintFieldType::value_type::zero()) {
b += s;
} else {
a += s;
}

n = (n.doubled()).doubled();
n += crumb_value;
}
}
auto res = a * endo_r + b;
return res;
}

template <typename CurveType>
void test_endo_scalar(std::vector<typename CurveType::scalar_field_type::value_type> public_input,
typename CurveType::scalar_field_type::value_type expected_res){
typename CurveType::scalar_field_type::value_type expected_res){
using BlueprintFieldType = typename CurveType::scalar_field_type;
constexpr std::size_t WitnessColumns = 15;
constexpr std::size_t PublicInputColumns = 1;
Expand All @@ -70,8 +155,14 @@ void test_endo_scalar(std::vector<typename CurveType::scalar_field_type::value_t
var challenge_var(0, 0, false, var::column_type::public_input);
typename component_type::input_type instance_input = {challenge_var};

auto result_check = [&expected_res](AssignmentType &assignment,
auto result_check = [&expected_res, public_input](AssignmentType &assignment,
typename component_type::result_type &real_res) {
#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED
std::cout << "endo_scalar input: " << std::hex << public_input[0].data << "\n";
std::cout << "expected result : " << std::hex << expected_res.data << "\n";
std::cout << "real result : " << std::hex << var_value(assignment, real_res.output).data << "\n\n";
#endif

assert(expected_res == var_value(assignment, real_res.output));
};

Expand All @@ -80,18 +171,59 @@ void test_endo_scalar(std::vector<typename CurveType::scalar_field_type::value_t
nil::crypto3::test_component<component_type, BlueprintFieldType, ArithmetizationParams, hash_type, Lambda> (component_instance, public_input, result_check, instance_input);
}

constexpr static const std::size_t random_tests_amount = 10;

BOOST_AUTO_TEST_SUITE(blueprint_plonk_endo_scalar_test_suite)

BOOST_AUTO_TEST_CASE(blueprint_plonk_unified_addition_addition) {
BOOST_AUTO_TEST_CASE(blueprint_plonk_endo_scalar_vesta) {
using curve_type = nil::crypto3::algebra::curves::vesta;
using BlueprintFieldType = typename curve_type::scalar_field_type;

typename BlueprintFieldType::value_type challenge = 0x00000000000000000000000000000000FC93536CAE0C612C18FBE5F6D8E8EEF2_cppui255;
typename BlueprintFieldType::value_type result = 0x004638173549A4C55A118327904B54E5F6F6314225C8C862F5AFA2506C77AC65_cppui255;

std::vector<typename BlueprintFieldType::value_type> public_input = {challenge};

test_endo_scalar<curve_type>(public_input, result);
test_endo_scalar<curve_type>({challenge}, result);
test_endo_scalar<curve_type>({1}, calculate_endo_scalar<curve_type, 128>(1));
test_endo_scalar<curve_type>({0}, calculate_endo_scalar<curve_type, 128>(0));
test_endo_scalar<curve_type>({0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui255},
calculate_endo_scalar<curve_type, 128>(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui255));

nil::crypto3::random::algebraic_engine<curve_type::scalar_field_type> generate_random;
boost::random::mt19937 seed_seq;
generate_random.seed(seed_seq);

for (std::size_t i = 0; i < random_tests_amount; i++){
typename curve_type::scalar_field_type::value_type input = generate_random();
typename curve_type::scalar_field_type::integral_type input_integral = typename curve_type::scalar_field_type::integral_type(input.data);
input_integral = input_integral & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui255;
typename curve_type::scalar_field_type::value_type input_scalar = input_integral;
test_endo_scalar<curve_type>({input_scalar}, calculate_endo_scalar<curve_type, 128>(input_scalar));
}
}

BOOST_AUTO_TEST_CASE(blueprint_plonk_endo_scalar_pallas) {
using curve_type = nil::crypto3::algebra::curves::pallas;
using BlueprintFieldType = typename curve_type::scalar_field_type;

typename BlueprintFieldType::value_type challenge = 0x00000000000000000000000000000000FC93536CAE0C612C18FBE5F6D8E8EEF2_cppui255;

test_endo_scalar<curve_type>({challenge}, calculate_endo_scalar<curve_type, 128>(challenge));
test_endo_scalar<curve_type>({1}, calculate_endo_scalar<curve_type, 128>(1));
test_endo_scalar<curve_type>({0}, calculate_endo_scalar<curve_type, 128>(0));
test_endo_scalar<curve_type>({0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui255},
calculate_endo_scalar<curve_type, 128>(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui255));

nil::crypto3::random::algebraic_engine<curve_type::scalar_field_type> generate_random;
boost::random::mt19937 seed_seq;
generate_random.seed(seed_seq);

for (std::size_t i = 0; i < random_tests_amount; i++){
typename curve_type::scalar_field_type::value_type input = generate_random();
typename curve_type::scalar_field_type::integral_type input_integral = typename curve_type::scalar_field_type::integral_type(input.data);
input_integral = input_integral & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_cppui255;
typename curve_type::scalar_field_type::value_type input_scalar = input_integral;
test_endo_scalar<curve_type>({input_scalar}, calculate_endo_scalar<curve_type, 128>(input_scalar));
}
}

BOOST_AUTO_TEST_SUITE_END()
122 changes: 94 additions & 28 deletions test/algebra/curves/plonk/unified_addition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@

#include <boost/test/unit_test.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/random_element.hpp>
#include <nil/crypto3/random/algebraic_engine.hpp>

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

Expand Down Expand Up @@ -70,8 +72,15 @@ void test_unified_addition(std::vector<typename CurveType::base_field_type::valu
{var(0, 0, false, var::column_type::public_input), var(0, 1, false, var::column_type::public_input)},
{var(0, 2, false, var::column_type::public_input), var(0, 3, false, var::column_type::public_input)}};

auto result_check = [&expected_res](AssignmentType &assignment,
auto result_check = [&expected_res, public_input](AssignmentType &assignment,
typename component_type::result_type &real_res) {
#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED
std::cout << "unified_addition test: " << "\n";
std::cout << "input : " << public_input[0].data << " " << public_input[1].data << "\n";
std::cout << "input : " << public_input[2].data << " " << public_input[3].data << "\n";
std::cout << "expected: " << expected_res.X.data << " " << expected_res.Y.data << "\n";
std::cout << "real : " << var_value(assignment, real_res.X).data << " " << var_value(assignment, real_res.Y).data << "\n\n";
#endif
assert(expected_res.X == var_value(assignment, real_res.X));
assert(expected_res.Y == var_value(assignment, real_res.Y));
};
Expand All @@ -82,48 +91,105 @@ void test_unified_addition(std::vector<typename CurveType::base_field_type::valu
component_instance, public_input, result_check, instance_input);
}

BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite)
template<typename CurveType>
void test_unified_addition_with_zeroes() {
nil::crypto3::random::algebraic_engine<typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>> generate_random_point;
boost::random::mt19937 seed_seq;
generate_random_point.seed(seed_seq);

BOOST_AUTO_TEST_CASE(blueprint_plonk_unified_addition_double) {
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type zero_algebraic = {0, 1};
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type zero_circuits = {0, 0};
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type P = generate_random_point();
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type Q = -P;

using curve_type = crypto3::algebra::curves::pallas;
std::vector<typename CurveType::base_field_type::value_type> public_input;

public_input = {zero_circuits.X, zero_circuits.Y, zero_circuits.X, zero_circuits.Y};
test_unified_addition<CurveType>(public_input, zero_circuits);

public_input = {zero_circuits.X, zero_circuits.Y, P.X, P.Y};
test_unified_addition<CurveType>(public_input, P);

auto P = crypto3::algebra::random_element<curve_type::template g1_type<>>().to_affine();
auto Q(P);
public_input = {P.X, P.Y, zero_circuits.X, zero_circuits.Y};
test_unified_addition<CurveType>(public_input, P);

std::vector<typename curve_type::base_field_type::value_type> public_input = {P.X, P.Y, Q.X, Q.Y};
typename curve_type::template g1_type<crypto3::algebra::curves::coordinates::affine>::value_type expected_res = P + Q;
public_input = {P.X, P.Y, Q.X, Q.Y};
test_unified_addition<CurveType>(public_input, zero_circuits);

test_unified_addition<curve_type>(public_input, expected_res);
public_input = {Q.X, Q.Y, P.X, P.Y};
test_unified_addition<CurveType>(public_input, zero_circuits);
}

BOOST_AUTO_TEST_CASE(blueprint_plonk_unified_addition_addition) {
template<typename CurveType>
void test_unified_addition_doubling() {
nil::crypto3::random::algebraic_engine<typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>> generate_random_point;
boost::random::mt19937 seed_seq;
generate_random_point.seed(seed_seq);

using curve_type = crypto3::algebra::curves::pallas;
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type P = generate_random_point();
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type Q(P);

std::vector<typename CurveType::base_field_type::value_type> public_input;

public_input = {P.X, P.Y, Q.X, Q.Y};
test_unified_addition<CurveType>(public_input, P+Q);

public_input = {Q.X, Q.Y, P.X, P.Y};
test_unified_addition<CurveType>(public_input, P+Q);
}

auto P = crypto3::algebra::random_element<curve_type::template g1_type<>>().to_affine();
auto Q = crypto3::algebra::random_element<curve_type::template g1_type<>>().to_affine();
typename curve_type::template g1_type<crypto3::algebra::curves::coordinates::affine>::value_type zero = {0, 0};
typename curve_type::template g1_type<crypto3::algebra::curves::coordinates::affine>::value_type expected_res;
P.X = Q.X;
P.Y = -Q.Y;
if (Q.X == zero.X && Q.Y == zero.Y) {
expected_res = P;
} else {
if (P.X == zero.X && P.Y == zero.Y) {
expected_res = Q;
template<typename CurveType, std::size_t RandomTestsAmount>
void test_unified_addition_random_data() {
nil::crypto3::random::algebraic_engine<typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>> generate_random_point;
boost::random::mt19937 seed_seq;
generate_random_point.seed(seed_seq);

typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type P = generate_random_point();
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type Q = generate_random_point();
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type zero = {0, 0};
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type expected_res;

std::vector<typename CurveType::base_field_type::value_type> public_input;

for (std::size_t i = 0; i < RandomTestsAmount; i++){
P = generate_random_point();
Q = generate_random_point();

if (Q.X == zero.X && Q.Y == zero.Y) {
expected_res = P;
} else {
if (P.X == Q.X && P.Y == -Q.Y) {
expected_res = {0, 0};
if (P.X == zero.X && P.Y == zero.Y) {
expected_res = Q;
} else {
expected_res = P + Q;
if (P.X == Q.X && P.Y == -Q.Y) {
expected_res = {0, 0};
} else {
expected_res = P + Q;
}
}
}

public_input = {P.X, P.Y, Q.X, Q.Y};
test_unified_addition<CurveType>(public_input, expected_res);
}
}

constexpr static const std::size_t random_tests_amount = 10;

std::vector<typename curve_type::base_field_type::value_type> public_input = {P.X, P.Y, Q.X, Q.Y};
BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite)

BOOST_AUTO_TEST_CASE(blueprint_plonk_unified_addition_pallas) {
using curve_type = crypto3::algebra::curves::pallas;
test_unified_addition_with_zeroes<curve_type>();
test_unified_addition_doubling<curve_type>();
test_unified_addition_random_data<curve_type, random_tests_amount>();
}

test_unified_addition<curve_type>(public_input, expected_res);
BOOST_AUTO_TEST_CASE(blueprint_plonk_unified_addition_vesta) {
using curve_type = crypto3::algebra::curves::vesta;
test_unified_addition_with_zeroes<curve_type>();
test_unified_addition_doubling<curve_type>();
test_unified_addition_random_data<curve_type, random_tests_amount>();
}

BOOST_AUTO_TEST_SUITE_END()
Loading

0 comments on commit 2ff2d19

Please sign in to comment.