Skip to content

Commit

Permalink
rewrite tests, add new cases for decomposed and usual variable base s…
Browse files Browse the repository at this point in the history
…calar mul, bool scalar mul, decomposition #107
  • Loading branch information
CblPOK-git committed Feb 2, 2023
1 parent ee0ed71 commit 8542227
Show file tree
Hide file tree
Showing 6 changed files with 363 additions and 268 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,26 @@
#include <nil/blueprint/blueprint/plonk/circuit.hpp>
#include <nil/blueprint/blueprint/plonk/assignment.hpp>
#include <nil/blueprint/component.hpp>
#include <nil/blueprint/basic_non_native_policy.hpp>

namespace nil {
namespace blueprint {
namespace components {

template<typename ArithmetizationType, typename Ed25519Type, std::uint32_t WitnessesAmount>
template<typename ArithmetizationType, typename Ed25519Type, std::uint32_t WitnessesAmount,
typename NonNativePolicyType>
class bool_scalar_multiplication;

template<typename BlueprintFieldType, typename ArithmetizationParams>
class bool_scalar_multiplication<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>,
typename crypto3::algebra::curves::ed25519, 9>:
typename crypto3::algebra::curves::ed25519, 9, basic_non_native_policy<BlueprintFieldType>>:
public plonk_component<BlueprintFieldType, ArithmetizationParams, 9, 0, 0> {

constexpr static const std::uint32_t WitnessesAmount = 9;

using component_type = plonk_component<BlueprintFieldType, ArithmetizationParams, WitnessesAmount, 0, 0>;
using operating_field_type = typename crypto3::algebra::fields::curve25519_base_field;
using non_native_policy_type = basic_non_native_policy<BlueprintFieldType>;

public:

Expand All @@ -61,8 +65,8 @@ namespace nil {

struct input_type {
struct var_ec_point {
std::array<var, 4> x;
std::array<var, 4> y;
typename non_native_policy_type::template field<operating_field_type>::value_type x;
typename non_native_policy_type::template field<operating_field_type>::value_type y;
};

var_ec_point T;
Expand All @@ -71,8 +75,8 @@ namespace nil {

struct result_type {
struct var_ec_point {
std::array<var, 4> x;
std::array<var, 4> y;
typename non_native_policy_type::template field<operating_field_type>::value_type x;
typename non_native_policy_type::template field<operating_field_type>::value_type y;
};
var_ec_point output;

Expand Down Expand Up @@ -116,7 +120,8 @@ namespace nil {
using plonk_bool_scalar_multiplication =
bool_scalar_multiplication<crypto3::zk::snark::plonk_constraint_system<BlueprintFieldType, ArithmetizationParams>,
typename crypto3::algebra::curves::ed25519,
WitnessesAmount>;
WitnessesAmount,
basic_non_native_policy<BlueprintFieldType>>;

template<typename BlueprintFieldType, typename ArithmetizationParams>
typename plonk_bool_scalar_multiplication<BlueprintFieldType, ArithmetizationParams, 9>::result_type
Expand Down
136 changes: 111 additions & 25 deletions test/algebra/curves/plonk/decomposed_variable_base_scalar_mul.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,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 @@ -49,6 +49,17 @@

using namespace nil::crypto3;

template<typename CurveType>
constexpr static bool scalar_larger() {
using ScalarField = typename CurveType::scalar_field_type;
using BaseField = typename CurveType::base_field_type;

auto n1 = ScalarField::modulus;
auto n2 = BaseField::modulus;

return n1 > n2;
}

template <typename CurveType>
void test_decomposed_variable_base_scalar_mul (std::vector<typename CurveType::base_field_type::value_type> public_input,
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type expected){
Expand Down Expand Up @@ -77,45 +88,120 @@ typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates:

component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14},{0},{});

auto result_check = [&expected](AssignmentType &assignment,
auto result_check = [&expected, public_input](AssignmentType &assignment,
typename component_type::result_type &real_res) {
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type R;
R.X = var_value(assignment, real_res.X);
R.Y = var_value(assignment, real_res.Y);
assert(expected.X == var_value(assignment, real_res.X));
assert(expected.Y == var_value(assignment, real_res.Y));

#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED
std::cout << std::hex;
std::cout << "_________________________________________________________________________________________________________________________________________________\n";
std::cout << "decomposed var base scal mul: (" << public_input[0].data << " " << public_input[1].data << ") * " << public_input[2].data << "\n";
std::cout << "expected:" << expected.X.data << " " << expected.Y.data << "\n";
std::cout << "real :" << R.X.data << " " << R.Y.data << "\n";
#endif

assert(expected.X == R.X);
assert(expected.Y - R.Y == 0); // not (expected.Y == R.Y) because of issue https://github.com/NilFoundation/crypto3-multiprecision/issues/38
};
nil::crypto3::test_component<component_type, BlueprintFieldType, ArithmetizationParams, hash_type, Lambda> (component_instance, public_input, result_check, instance_input);
}

BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite)
template <typename CurveType>
struct shift_params;

BOOST_AUTO_TEST_CASE(blueprint_plonk_decomposed_variable_base_scalar_mul_random_scalar_pallas) {
using curve_type = nil::crypto3::algebra::curves::pallas;
using BlueprintFieldType = typename curve_type::base_field_type;
using BlueprintScalarType = typename curve_type::scalar_field_type;
template<>
struct shift_params<nil::crypto3::algebra::curves::pallas> {
constexpr static const typename nil::crypto3::algebra::curves::pallas::scalar_field_type::value_type shift_base = 2;
constexpr static const typename nil::crypto3::algebra::curves::pallas::scalar_field_type::value_type shift_for_1_0_neg1 = shift_base.pow(255) + 1;
constexpr static const typename nil::crypto3::algebra::curves::pallas::scalar_field_type::value_type denominator_for_1_0_neg1 = 2;
};

typename BlueprintScalarType::value_type b_scalar = nil::crypto3::algebra::random_element<BlueprintScalarType>();
template<typename CurveType>
typename CurveType::base_field_type::integral_type shift_scalar(typename CurveType::scalar_field_type::value_type unshifted) {
typename CurveType::scalar_field_type::value_type shift_base = 2;
typename CurveType::scalar_field_type::value_type shift = shift_base.pow(255) + 1;
typename CurveType::scalar_field_type::value_type denominator = 2;

typename curve_type::scalar_field_type::value_type shift_base = 2;
typename curve_type::scalar_field_type::integral_type base = 1;
auto shift = shift_base.pow(255) + 1;
typename BlueprintScalarType::value_type x = (b_scalar - shift)/2;
typename BlueprintScalarType::integral_type integral_x = typename BlueprintScalarType::integral_type(x.data);
typename BlueprintFieldType::value_type x_scalar = integral_x;
// typename BlueprintScalarType::integral_type integral_x = typename BlueprintScalarType::integral_type(x.data);
typename CurveType::scalar_field_type::value_type shift_for_1_0_neg1 = shift_params<CurveType>::shift_for_1_0_neg1;
typename CurveType::scalar_field_type::value_type denominator_for_1_0_neg1 = shift_params<CurveType>::denominator_for_1_0_neg1;

typename CurveType::scalar_field_type::value_type shifted;

curve_type::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type T = nil::crypto3::algebra::random_element<curve_type::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>>();
std::vector<typename BlueprintFieldType::value_type> public_input = {T.X, T.Y, integral_x & ((base << 254) - 1), (integral_x >> 254)};
curve_type::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type expected;
if (b_scalar != 0) {
expected = b_scalar * T;
} else {
expected = {0, 0};
if ((unshifted == 1) || (unshifted == 0) || (unshifted == -1)){
shifted = (unshifted - shift_for_1_0_neg1) / denominator_for_1_0_neg1;
}
else {
shifted = (unshifted - shift) / denominator;
}

typename CurveType::scalar_field_type::integral_type shifted_integral_type = typename CurveType::scalar_field_type::integral_type(shifted.data);
return shifted_integral_type;
}

template<typename CurveType>
void test_decomposed_vbsm(
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type point,
typename CurveType::scalar_field_type::value_type scalar) {
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type zero_point = {0, 0};
typename CurveType::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type expected;
if (scalar != 0) {
expected = point * scalar;
} else {
expected = {0, 0};
}

typename CurveType::scalar_field_type::integral_type shifted_scalar = shift_scalar<CurveType>(scalar);
typename CurveType::scalar_field_type::integral_type one = 1;
typename CurveType::scalar_field_type::integral_type mask = (one << 254) - 1;

typename CurveType::scalar_field_type::integral_type least254bytes = shifted_scalar & mask;
typename CurveType::scalar_field_type::integral_type other_bytes = shifted_scalar >> 254;


test_decomposed_variable_base_scalar_mul<CurveType>({point.X, point.Y, least254bytes, other_bytes}, expected);
}


BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite)

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

test_decomposed_variable_base_scalar_mul<curve_type>(public_input, expected);
static_assert(scalar_larger<curve_type>(), "Decomposed vbsm is only for scalar_field > base_field! Use usual vbsm");

nil::crypto3::random::algebraic_engine<typename curve_type::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>> random_point;
boost::random::mt19937 seed_seq;
random_point.seed(seed_seq);

nil::crypto3::random::algebraic_engine<BlueprintScalarType> random_scalar;
boost::random::mt19937 seed_seq2;
random_scalar.seed(seed_seq2);

typename BlueprintScalarType::value_type two = 2;
typename BlueprintScalarType::value_type threefff = 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff_cppui255;
typename BlueprintScalarType::value_type unshifted_threefff = 2*threefff + two.pow(255) + 1;

test_decomposed_vbsm<curve_type>(random_point(), two + two.pow(255) + 1);
test_decomposed_vbsm<curve_type>(random_point(), two - two + two.pow(255) + 1);
test_decomposed_vbsm<curve_type>(random_point(), two - two - two + two.pow(255) + 1);
test_decomposed_vbsm<curve_type>(random_point(), random_scalar());
test_decomposed_vbsm<curve_type>(random_point(), unshifted_threefff);
test_decomposed_vbsm<curve_type>(random_point(), 1);
test_decomposed_vbsm<curve_type>(random_point(), 0);
test_decomposed_vbsm<curve_type>(random_point(), -1);

test_decomposed_vbsm<curve_type>({0, 0}, two + two.pow(255) + 1);
test_decomposed_vbsm<curve_type>({0, 0}, two - two + two.pow(255) + 1);
test_decomposed_vbsm<curve_type>({0, 0}, two - two - two + two.pow(255) + 1);
test_decomposed_vbsm<curve_type>({0, 0}, random_scalar());
test_decomposed_vbsm<curve_type>({0, 0}, unshifted_threefff);
test_decomposed_vbsm<curve_type>({0, 0}, 1);
test_decomposed_vbsm<curve_type>({0, 0}, 0);
test_decomposed_vbsm<curve_type>({0, 0}, -1);
}

BOOST_AUTO_TEST_SUITE_END()
Loading

0 comments on commit 8542227

Please sign in to comment.