From 85422272e48010eac095a986d5bd9915c501a159 Mon Sep 17 00:00:00 2001 From: cblpok Date: Thu, 2 Feb 2023 23:01:45 +0300 Subject: [PATCH] rewrite tests, add new cases for decomposed and usual variable base scalar mul, bool scalar mul, decomposition #107 --- .../non_native/bool_scalar_multiplication.hpp | 19 +- .../decomposed_variable_base_scalar_mul.cpp | 136 +++++++-- .../curves/plonk/variable_base_scalar_mul.cpp | 262 ++++-------------- .../plonk/non_native/multiplication.cpp | 12 +- test/hashes/plonk/decomposition.cpp | 81 +++++- .../plonk/bool_scalar_multiplication.cpp | 121 ++++++-- 6 files changed, 363 insertions(+), 268 deletions(-) diff --git a/include/nil/blueprint/components/algebra/curves/edwards/plonk/non_native/bool_scalar_multiplication.hpp b/include/nil/blueprint/components/algebra/curves/edwards/plonk/non_native/bool_scalar_multiplication.hpp index 234332f334..7053d2302f 100644 --- a/include/nil/blueprint/components/algebra/curves/edwards/plonk/non_native/bool_scalar_multiplication.hpp +++ b/include/nil/blueprint/components/algebra/curves/edwards/plonk/non_native/bool_scalar_multiplication.hpp @@ -34,22 +34,26 @@ #include #include #include +#include namespace nil { namespace blueprint { namespace components { - template + template class bool_scalar_multiplication; template class bool_scalar_multiplication, - typename crypto3::algebra::curves::ed25519, 9>: + typename crypto3::algebra::curves::ed25519, 9, basic_non_native_policy>: public plonk_component { constexpr static const std::uint32_t WitnessesAmount = 9; using component_type = plonk_component; + using operating_field_type = typename crypto3::algebra::fields::curve25519_base_field; + using non_native_policy_type = basic_non_native_policy; public: @@ -61,8 +65,8 @@ namespace nil { struct input_type { struct var_ec_point { - std::array x; - std::array y; + typename non_native_policy_type::template field::value_type x; + typename non_native_policy_type::template field::value_type y; }; var_ec_point T; @@ -71,8 +75,8 @@ namespace nil { struct result_type { struct var_ec_point { - std::array x; - std::array y; + typename non_native_policy_type::template field::value_type x; + typename non_native_policy_type::template field::value_type y; }; var_ec_point output; @@ -116,7 +120,8 @@ namespace nil { using plonk_bool_scalar_multiplication = bool_scalar_multiplication, typename crypto3::algebra::curves::ed25519, - WitnessesAmount>; + WitnessesAmount, + basic_non_native_policy>; template typename plonk_bool_scalar_multiplication::result_type diff --git a/test/algebra/curves/plonk/decomposed_variable_base_scalar_mul.cpp b/test/algebra/curves/plonk/decomposed_variable_base_scalar_mul.cpp index ff01410570..657fab8674 100644 --- a/test/algebra/curves/plonk/decomposed_variable_base_scalar_mul.cpp +++ b/test/algebra/curves/plonk/decomposed_variable_base_scalar_mul.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include @@ -49,6 +49,17 @@ using namespace nil::crypto3; +template +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 void test_decomposed_variable_base_scalar_mul (std::vector public_input, typename CurveType::template g1_type::value_type expected){ @@ -77,45 +88,120 @@ typename CurveType::template g1_type::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_instance, public_input, result_check, instance_input); } -BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) +template +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 { + 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(); +template +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::shift_for_1_0_neg1; + typename CurveType::scalar_field_type::value_type denominator_for_1_0_neg1 = shift_params::denominator_for_1_0_neg1; + typename CurveType::scalar_field_type::value_type shifted; - curve_type::template g1_type::value_type T = nil::crypto3::algebra::random_element>(); - std::vector public_input = {T.X, T.Y, integral_x & ((base << 254) - 1), (integral_x >> 254)}; - curve_type::template g1_type::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 +void test_decomposed_vbsm( + typename CurveType::template g1_type::value_type point, + typename CurveType::scalar_field_type::value_type scalar) { + typename CurveType::template g1_type::value_type zero_point = {0, 0}; + typename CurveType::template g1_type::value_type expected; + if (scalar != 0) { + expected = point * scalar; + } else { + expected = {0, 0}; + } + + typename CurveType::scalar_field_type::integral_type shifted_scalar = shift_scalar(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({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(public_input, expected); + static_assert(scalar_larger(), "Decomposed vbsm is only for scalar_field > base_field! Use usual vbsm"); + + nil::crypto3::random::algebraic_engine> random_point; + boost::random::mt19937 seed_seq; + random_point.seed(seed_seq); + + nil::crypto3::random::algebraic_engine 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(random_point(), two + two.pow(255) + 1); + test_decomposed_vbsm(random_point(), two - two + two.pow(255) + 1); + test_decomposed_vbsm(random_point(), two - two - two + two.pow(255) + 1); + test_decomposed_vbsm(random_point(), random_scalar()); + test_decomposed_vbsm(random_point(), unshifted_threefff); + test_decomposed_vbsm(random_point(), 1); + test_decomposed_vbsm(random_point(), 0); + test_decomposed_vbsm(random_point(), -1); + + test_decomposed_vbsm({0, 0}, two + two.pow(255) + 1); + test_decomposed_vbsm({0, 0}, two - two + two.pow(255) + 1); + test_decomposed_vbsm({0, 0}, two - two - two + two.pow(255) + 1); + test_decomposed_vbsm({0, 0}, random_scalar()); + test_decomposed_vbsm({0, 0}, unshifted_threefff); + test_decomposed_vbsm({0, 0}, 1); + test_decomposed_vbsm({0, 0}, 0); + test_decomposed_vbsm({0, 0}, -1); } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/algebra/curves/plonk/variable_base_scalar_mul.cpp b/test/algebra/curves/plonk/variable_base_scalar_mul.cpp index e63da7402e..dd504630f1 100644 --- a/test/algebra/curves/plonk/variable_base_scalar_mul.cpp +++ b/test/algebra/curves/plonk/variable_base_scalar_mul.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include @@ -78,15 +78,17 @@ typename CurveType::template g1_type::value_type R; R.X = var_value(assignment, real_res.X); R.Y = var_value(assignment, real_res.Y); + + #ifdef BLUEPRINT_PLONK_PROFILING_ENABLED + std::cout << std::hex; + std::cout << "_________________________________________________________________________________________________________________________________________________\n"; std::cout << "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\n"; - auto ydata_expected = expected.Y.data; - auto ydata_real = R.Y.data; + std::cout << "real :" << R.X.data << " " << R.Y.data << "\n"; + #endif assert(expected.X == R.X); - std::cout << "assert(" << ydata_expected << " == " << ydata_real << ");" << std::endl; - assert(ydata_expected == ydata_real); + 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_instance, public_input, result_check, instance_input); } @@ -120,7 +122,7 @@ typename CurveType::base_field_type::value_type shift_scalar(typename CurveType: typename CurveType::scalar_field_type::value_type shifted; - if ((unshifted == 1) || (unshifted == 0) || (unshifted == 1)){ + if ((unshifted == 1) || (unshifted == 0) || (unshifted == -1)){ shifted = (unshifted - shift_for_1_0_neg1) / denominator_for_1_0_neg1; } else { @@ -132,215 +134,57 @@ typename CurveType::base_field_type::value_type shift_scalar(typename CurveType: return shifted_base_value_type; } -BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) - -BOOST_AUTO_TEST_CASE(blueprint_plonk_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; - - typename BlueprintScalarType::value_type b_scalar = 0x20000000000000000000000000000000224698fc094cf91b992d30ed00000000_cppui256;//nil::crypto3::algebra::random_element(); - typename curve_type::scalar_field_type::value_type shift_base = 2; - 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; - shift_scalar(b_scalar); - - curve_type::template g1_type::value_type T = nil::crypto3::algebra::random_element>(); - curve_type::template g1_type::value_type zero_point = {0, 0}; - std::vector public_input = {T.X, T.Y, x_scalar}; - curve_type::template g1_type::value_type expected; - if (b_scalar != 0) { - expected = b_scalar * T; - } else { - expected = {0, 0}; - } - - test_variable_base_scalar_mul({T.X, T.Y, shift_scalar(b_scalar)}, expected); - test_variable_base_scalar_mul({T.X, T.Y, shift_scalar(-1)}, {T.X, -T.Y}); - test_variable_base_scalar_mul({T.X, T.Y, shift_scalar(0)}, zero_point); - test_variable_base_scalar_mul({T.X, T.Y, shift_scalar(1)}, T); - - test_variable_base_scalar_mul({0, 0, shift_scalar(b_scalar)}, zero_point); - test_variable_base_scalar_mul({0, 0, shift_scalar(-1)}, zero_point); - test_variable_base_scalar_mul({0, 0, shift_scalar(0)}, zero_point); - test_variable_base_scalar_mul({0, 0, shift_scalar(1)}, zero_point); -} - -BOOST_AUTO_TEST_CASE(blueprint_plonk_variable_base_scalar_mul_scalar_one_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; - - typename BlueprintScalarType::value_type b_scalar = 1; - - typename curve_type::scalar_field_type::value_type shift_base = 2; - 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; - - curve_type::template g1_type::value_type T = nil::crypto3::algebra::random_element>(); - std::vector public_input = {T.X, T.Y, x_scalar}; - curve_type::template g1_type::value_type expected; - if (b_scalar != 0) { - expected = b_scalar * T; - } else { - expected = {0, 0}; - } - - test_variable_base_scalar_mul(public_input, expected); -} - -BOOST_AUTO_TEST_CASE(blueprint_plonk_variable_base_scalar_mul_scalar_zero_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; - - typename BlueprintScalarType::value_type b_scalar = 0; - - typename curve_type::scalar_field_type::value_type shift_base = 2; - 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; - - curve_type::template g1_type::value_type T = nil::crypto3::algebra::random_element>(); - std::vector public_input = {T.X, T.Y, x_scalar}; - curve_type::template g1_type::value_type expected; - if (b_scalar != 0) { - expected = b_scalar * T; - } else { - expected = {0, 0}; - } - - test_variable_base_scalar_mul(public_input, expected); -} - -BOOST_AUTO_TEST_CASE(blueprint_plonk_variable_base_scalar_mul_scalar_minus_one_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; - - typename BlueprintScalarType::value_type b_scalar = -1; - - typename curve_type::scalar_field_type::value_type shift_base = 2; - 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; - - curve_type::template g1_type::value_type T = nil::crypto3::algebra::random_element>(); - std::vector public_input = {T.X, T.Y, x_scalar}; - curve_type::template g1_type::value_type expected; - if (b_scalar != 0) { - expected = b_scalar * T; - } else { - expected = {0, 0}; - } - - test_variable_base_scalar_mul(public_input, expected); -} - -BOOST_AUTO_TEST_CASE(blueprint_plonk_variable_base_scalar_mul_random_scalar_vesta) { - using curve_type = nil::crypto3::algebra::curves::vesta; - using BlueprintFieldType = typename curve_type::base_field_type; - using BlueprintScalarType = typename curve_type::scalar_field_type; - - typename BlueprintScalarType::value_type b_scalar = nil::crypto3::algebra::random_element(); - - typename curve_type::scalar_field_type::value_type shift_base = 2; - 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; - - curve_type::template g1_type::value_type T = nil::crypto3::algebra::random_element>(); - std::vector public_input = {T.X, T.Y, x_scalar}; - curve_type::template g1_type::value_type expected; - if (b_scalar != 0) { - expected = b_scalar * T; - } else { - expected = {0, 0}; - } - - test_variable_base_scalar_mul(public_input, expected); -} - -BOOST_AUTO_TEST_CASE(blueprint_plonk_variable_base_scalar_mul_scalar_one_vesta) { - using curve_type = nil::crypto3::algebra::curves::vesta; - using BlueprintFieldType = typename curve_type::base_field_type; - using BlueprintScalarType = typename curve_type::scalar_field_type; - - typename BlueprintScalarType::value_type b_scalar = 1; - - typename curve_type::scalar_field_type::value_type shift_base = 2; - auto shift = shift_base.pow(255); - typename BlueprintScalarType::value_type x = (b_scalar - shift); - typename BlueprintScalarType::integral_type integral_x = typename BlueprintScalarType::integral_type(x.data); - typename BlueprintFieldType::value_type x_scalar = integral_x; - - curve_type::template g1_type::value_type T = nil::crypto3::algebra::random_element>(); - std::vector public_input = {T.X, T.Y, x_scalar}; - curve_type::template g1_type::value_type expected; - if (b_scalar != 0) { - expected = b_scalar * T; - } else { - expected = {0, 0}; - } - - test_variable_base_scalar_mul(public_input, expected); -} - -BOOST_AUTO_TEST_CASE(blueprint_plonk_variable_base_scalar_mul_scalar_zero_vesta) { - using curve_type = nil::crypto3::algebra::curves::vesta; - using BlueprintFieldType = typename curve_type::base_field_type; - using BlueprintScalarType = typename curve_type::scalar_field_type; - - typename BlueprintScalarType::value_type b_scalar = 0; - - typename curve_type::scalar_field_type::value_type shift_base = 2; - auto shift = shift_base.pow(255); - typename BlueprintScalarType::value_type x = (b_scalar - shift); - typename BlueprintScalarType::integral_type integral_x = typename BlueprintScalarType::integral_type(x.data); - typename BlueprintFieldType::value_type x_scalar = integral_x; - - curve_type::template g1_type::value_type T = nil::crypto3::algebra::random_element>(); - std::vector public_input = {T.X, T.Y, x_scalar}; - curve_type::template g1_type::value_type expected; - if (b_scalar != 0) { - expected = b_scalar * T; - } else { - expected = {0, 0}; +template +void test_vbsm( + typename CurveType::template g1_type::value_type point, + typename CurveType::scalar_field_type::value_type scalar) { + typename CurveType::template g1_type::value_type zero_point = {0, 0}; + typename CurveType::template g1_type::value_type expected; + if (scalar != 0) { + expected = point * scalar; + } else { + expected = {0, 0}; + } + + test_variable_base_scalar_mul({point.X, point.Y, shift_scalar(scalar)}, expected); } - test_variable_base_scalar_mul(public_input, expected); -} +BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) -BOOST_AUTO_TEST_CASE(blueprint_plonk_variable_base_scalar_mul_scalar_minus_one_vesta) { +BOOST_AUTO_TEST_CASE(blueprint_plonk_variable_base_scalar_mul_random_scalar_pallas) { using curve_type = nil::crypto3::algebra::curves::vesta; using BlueprintFieldType = typename curve_type::base_field_type; using BlueprintScalarType = typename curve_type::scalar_field_type; - typename BlueprintScalarType::value_type b_scalar = -1; - - typename curve_type::scalar_field_type::value_type shift_base = 2; - auto shift = shift_base.pow(255); - typename BlueprintScalarType::value_type x = (b_scalar - shift); - typename BlueprintScalarType::integral_type integral_x = typename BlueprintScalarType::integral_type(x.data); - typename BlueprintFieldType::value_type x_scalar = integral_x; - - curve_type::template g1_type::value_type T = nil::crypto3::algebra::random_element>(); - std::vector public_input = {T.X, T.Y, x_scalar}; - curve_type::template g1_type::value_type expected; - if (b_scalar != 0) { - expected = b_scalar * T; - } else { - expected = {0, 0}; - } - - test_variable_base_scalar_mul(public_input, expected); + nil::crypto3::random::algebraic_engine> random_point; + boost::random::mt19937 seed_seq; + random_point.seed(seed_seq); + + nil::crypto3::random::algebraic_engine 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_vbsm(random_point(), two + two.pow(255) + 1); + test_vbsm(random_point(), two - two + two.pow(255) + 1); + test_vbsm(random_point(), two - two - two + two.pow(255) + 1); + test_vbsm(random_point(), unshifted_threefff); + test_vbsm(random_point(), random_scalar()); + test_vbsm(random_point(), 1); + test_vbsm(random_point(), 0); + test_vbsm(random_point(), -1); + + test_vbsm({0, 0}, two + two.pow(255) + 1); + test_vbsm({0, 0}, two - two + two.pow(255) + 1); + test_vbsm({0, 0}, two - two - two + two.pow(255) + 1); + test_vbsm({0, 0}, unshifted_threefff); + test_vbsm({0, 0}, random_scalar()); + test_vbsm({0, 0}, 1); + test_vbsm({0, 0}, 0); + test_vbsm({0, 0}, -1); } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/algebra/fields/plonk/non_native/multiplication.cpp b/test/algebra/fields/plonk/non_native/multiplication.cpp index 9b32650f6f..610e50587b 100644 --- a/test/algebra/fields/plonk/non_native/multiplication.cpp +++ b/test/algebra/fields/plonk/non_native/multiplication.cpp @@ -141,17 +141,21 @@ void test_field_mul_all_cases(){ typename NonNativeFieldType::value_type f = 0xf; typename NonNativeFieldType::integral_type f_integral; - for (std::size_t i = 0; i < 63; i++) { + for (std::size_t i = 0; i < 256; i++) { f_integral = typename NonNativeFieldType::integral_type(f.data); - f_integral = (f_integral << 4) + 0xf; + f_integral = (f_integral << 1) + 1; f = typename NonNativeFieldType::value_type(f_integral); - test_field_mul_useable(f, f); + test_field_mul_useable(f, lalala); } + test_field_mul_useable( + glue_non_native({0,0,0x3ffffffffffffffff_cppui255,0}), + glue_non_native({0,0,0x3ffffffffffffffff_cppui255,0})); + test_field_mul_useable(0, 0); test_field_mul_useable(1, 1); - test_field_mul_useable(-1, -1); test_field_mul_useable(1, -1); + test_field_mul_useable(-1, -1); test_field_mul_useable(-1, 0); test_field_mul_useable(1000, -1000); test_field_mul_useable( diff --git a/test/hashes/plonk/decomposition.cpp b/test/hashes/plonk/decomposition.cpp index c461b3a06c..5e45a047d9 100644 --- a/test/hashes/plonk/decomposition.cpp +++ b/test/hashes/plonk/decomposition.cpp @@ -43,7 +43,8 @@ using namespace nil; template -void test_decomposition(std::vector public_input){ +void test_decomposition(std::vector public_input, + std::vector expected_res) { constexpr std::size_t WitnessColumns = 9; constexpr std::size_t PublicInputColumns = 1; @@ -66,8 +67,11 @@ void test_decomposition(std::vector pub typename component_type::input_type instance_input = {input_state_var}; - auto result_check = [](AssignmentType &assignment, + auto result_check = [&expected_res](AssignmentType &assignment, typename component_type::result_type &real_res) { + for (std::size_t i = 0; i < real_res.output.size(); 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},{},{}); @@ -78,9 +82,78 @@ void test_decomposition(std::vector pub BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) +template +std::vector calculate_decomposition(std::vector data_value) { + std::array data = { + typename FieldType::integral_type(data_value[0].data), + typename FieldType::integral_type(data_value[1].data)}; + std::array range_chunks; + std::size_t shift = 0; + + for (std::size_t i = 0; i < 8; i++) { + range_chunks[i] = (data[0] >> shift) & ((1 << 16) - 1); + range_chunks[i + 8] = (data[1] >> shift) & ((1 << 16) - 1); + shift += 16; + } + + std::array output; + + output[0] = range_chunks[1] * (1 << 16) + range_chunks[0]; + output[1] = range_chunks[3] * (1 << 16) + range_chunks[2]; + output[2] = range_chunks[5] * (1 << 16) + range_chunks[4]; + output[3] = range_chunks[7] * (1 << 16) + range_chunks[6]; + output[4] = range_chunks[9] * (1 << 16) + range_chunks[8]; + output[5] = range_chunks[11] * (1 << 16) + range_chunks[10]; + output[6] = range_chunks[13] * (1 << 16) + range_chunks[12]; + output[7] = range_chunks[15] * (1 << 16) + range_chunks[14]; + + std::vector output_value; + + for (std::size_t i = 0; i < output.size(); i++){ + output_value.push_back(typename FieldType::value_type(output[i])); + } + + return output_value; +} + BOOST_AUTO_TEST_CASE(blueprint_plonk_decomposition_test0) { - test_decomposition( - {0x8d741211e928fdd4d33a13970d0ce7f3_cppui255, 0x92f209334030f9ec8fa8a025e987a5dd_cppui255}); + using field_type = typename crypto3::algebra::curves::pallas::base_field_type; + + test_decomposition( + {0x8d741211e928fdd4d33a13970d0ce7f3_cppui255, 0x92f209334030f9ec8fa8a025e987a5dd_cppui255}, + calculate_decomposition({0x8d741211e928fdd4d33a13970d0ce7f3_cppui255, 0x92f209334030f9ec8fa8a025e987a5dd_cppui255})); + + test_decomposition( + {0, 0}, + calculate_decomposition({0, 0})); + + test_decomposition( + {0xffffffffffffffffffffffffffffffff_cppui255, 0xffffffffffffffffffffffffffffffff_cppui255}, + calculate_decomposition({0xffffffffffffffffffffffffffffffff_cppui255, 0xffffffffffffffffffffffffffffffff_cppui255})); +} + +BOOST_AUTO_TEST_CASE(blueprint_plonk_decomposition_must_fail) { + using field_type = typename crypto3::algebra::curves::pallas::base_field_type; + + typename field_type::value_type bad = 0x100000000000000000000000000000000_cppui255; + + test_decomposition( + {0, bad}, + calculate_decomposition({0, bad})); + + test_decomposition( + {bad, 0}, + calculate_decomposition({bad, 0})); + + bad = 0x4000000000000000000000000000000000000000000000000000000000000000_cppui255; + + test_decomposition( + {0, bad}, + calculate_decomposition({0, bad})); + + test_decomposition( + {bad, 0}, + calculate_decomposition({bad, 0})); } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/non_native/plonk/bool_scalar_multiplication.cpp b/test/non_native/plonk/bool_scalar_multiplication.cpp index deeae4a206..459589947a 100644 --- a/test/non_native/plonk/bool_scalar_multiplication.cpp +++ b/test/non_native/plonk/bool_scalar_multiplication.cpp @@ -31,7 +31,8 @@ #include #include -#include +#include +#include <../test/algebra/fields/plonk/non_native/chop_and_glue_non_native.hpp> #include @@ -43,8 +44,9 @@ using namespace nil; -template -void test_bool_scalar_multiplication(std::vector public_input){ +template +void test_bool_scalar_multiplication(std::vector public_input, + std::vector expected_res){ constexpr std::size_t WitnessColumns = 9; constexpr std::size_t PublicInputColumns = 1; @@ -56,12 +58,12 @@ void test_bool_scalar_multiplication(std::vector; using hash_type = crypto3::hashes::keccak_1600<256>; constexpr std::size_t Lambda = 1; - using ed25519_type = crypto3::algebra::curves::ed25519; + using NonNativeFieldType = typename NonNativeCurveType::base_field_type; using var = crypto3::zk::snark::plonk_variable; using component_type = blueprint::components::bool_scalar_multiplication; + NonNativeCurveType, 9, blueprint::basic_non_native_policy>; std::array T_x = { var(0, 0, false, var::column_type::public_input), var(0, 1, false, var::column_type::public_input), @@ -72,8 +74,53 @@ void test_bool_scalar_multiplication(std::vector x, y, expected_x, expected_y, real_x, real_y; + for (std::size_t i = 0; i < 4; i++) { + x[i] = public_input[i]; + y[i] = public_input[i+4]; + expected_x[i] = expected_res[i]; + expected_y[i] = expected_res[i+4]; + real_x[i] = var_value(assignment, real_res.output.x[i]); + real_y[i] = var_value(assignment, real_res.output.y[i]); + } + + std::cout << std::hex; + + std::cout << "_________________________________________________________________________________________________________________________________________________\n"; + std::cout << "input x: "; + for (std::size_t i = 0; i < 4; i++) {std::cout << x[3-i].data << " ";} + std::cout << "(" << glue_non_native(x).data << ")\n"; + + std::cout << " y: "; + for (std::size_t i = 0; i < 4; i++) {std::cout << y[3-i].data << " ";} + std::cout << "(" << glue_non_native(y).data << ")\n"; + + std::cout << " bool: " << public_input[8].data << "\n"; + + std::cout << "expected: "; + for (std::size_t i = 0; i < 4; i++) {std::cout << expected_x[3-i].data << " ";} + std::cout << "(" << glue_non_native(expected_x).data << ")\n"; + std::cout << " "; + for (std::size_t i = 0; i < 4; i++) {std::cout << expected_y[3-i].data << " ";} + std::cout << "(" << glue_non_native(expected_y).data << ")\n"; + + + std::cout << "real : "; + for (std::size_t i = 0; i < 4; i++) {std::cout << real_x[3-i].data << " ";} + std::cout << "(" << glue_non_native(real_x).data << ")\n"; + std::cout << " "; + for (std::size_t i = 0; i < 4; i++) {std::cout << real_y[3-i].data << " ";} + // std::cout << "(" << glue_non_native(real_y).data << ")" << std::endl; + #endif + + for(std::size_t i = 0; i < 4; i++) { + assert(expected_res[i] == var_value(assignment, real_res.output.x[i])); + assert(expected_res[i+4] == var_value(assignment, real_res.output.y[i])); + } }; component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8},{},{}); @@ -82,26 +129,62 @@ void test_bool_scalar_multiplication(std::vector +void test_bool_scalar_multiplication_usable (typename NonNativeCurveType::template g1_type::value_type point, typename FieldType::value_type scalar_bool) { + + std::vector public_input = create_public_input( + chop_non_native(point.X), + chop_non_native(point.Y)); + + std::vector expected_res; + if (scalar_bool == 1) { + expected_res = public_input; + } else { + expected_res = {0,0,0,0,1,0,0,0}; + } + public_input.push_back(scalar_bool); + + test_bool_scalar_multiplication(public_input, expected_res); +} + +constexpr static const std::size_t random_tests_amount = 3; + BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite) -BOOST_AUTO_TEST_CASE(blueprint_non_native_bit_decomposition_test0) { +BOOST_AUTO_TEST_CASE(blueprint_non_native_bool_scalar_mul_test1) { using field_type = typename crypto3::algebra::curves::pallas::base_field_type; - std::vector input(9); - for (int i = 0; i < 8; ++i) { - input[i] = crypto3::algebra::random_element(); + using non_native_curve_type = crypto3::algebra::curves::ed25519; + using non_native_field_type = non_native_curve_type::base_field_type; + + nil::crypto3::random::algebraic_engine> rand; + boost::random::mt19937 seed_seq; + rand.seed(seed_seq); + + test_bool_scalar_multiplication_usable({0,1}, 1); + test_bool_scalar_multiplication_usable({0,1}, 0); + + for (std::size_t i = 0; i < random_tests_amount; i++) { + test_bool_scalar_multiplication_usable(rand(), 1); + test_bool_scalar_multiplication_usable(rand(), 0); } - input[8] = 0; - test_bool_scalar_multiplication(input); } -BOOST_AUTO_TEST_CASE(blueprint_non_native_bit_decomposition_test1) { +BOOST_AUTO_TEST_CASE(blueprint_non_native_bool_scalar_mul_must_fail) { // test should pass if component fails on wrong data, feature is not implemented yet using field_type = typename crypto3::algebra::curves::pallas::base_field_type; - std::vector input(9); - for (int i = 0; i < 8; ++i) { - input[i] = crypto3::algebra::random_element(); - } - input[8] = 1; - test_bool_scalar_multiplication(input); + using non_native_curve_type = crypto3::algebra::curves::ed25519; + using non_native_field_type = non_native_curve_type::base_field_type; + + nil::crypto3::random::algebraic_engine> rand; + boost::random::mt19937 seed_seq; + rand.seed(seed_seq); + + test_bool_scalar_multiplication_usable({0,1}, 2); + test_bool_scalar_multiplication_usable({0,1}, 10); + test_bool_scalar_multiplication_usable({0,1}, -1); + + test_bool_scalar_multiplication_usable(rand(), 2); + test_bool_scalar_multiplication_usable(rand(), 10); + test_bool_scalar_multiplication_usable(rand(), -1); } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file