Skip to content

Commit

Permalink
ec_double bbf
Browse files Browse the repository at this point in the history
  • Loading branch information
AntoineCyr committed Jan 25, 2025
1 parent 4a7a195 commit 3eb2601
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 179 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ namespace nil {
bool make_links = true)
: generic_component<FieldType, stage>(context_object) {

using double_non_native_integral_type = nil::crypto3::multiprecision::big_uint<2* NonNativeFieldType::modulus_bits>;
using extended_integral_type = nil::crypto3::multiprecision::big_uint<2* NonNativeFieldType::modulus_bits>;

using native_integral_type = typename FieldType::integral_type;
using integral_type = typename FieldType::integral_type;

using Check_Mod_P = typename bbf::components::check_mod_p<FieldType,stage>;
using Range_Check = typename bbf::components::range_check_multi<FieldType,stage>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,137 +40,143 @@ using namespace nil;
using namespace nil::blueprint;

template<typename BlueprintFieldType, typename NonNativeFieldType, std::size_t num_chunks,
std::size_t bit_size_chunk>
std::size_t bit_size_chunk>
void test_ec_double(
const std::vector<typename BlueprintFieldType::value_type> &public_input) {
const std::vector<typename BlueprintFieldType::value_type>& public_input) {
using FieldType = BlueprintFieldType;
using TYPE = typename FieldType::value_type;
using NON_NATIVE_TYPE = typename NonNativeFieldType::value_type;
using integral_type = typename BlueprintFieldType::integral_type;
typedef nil::crypto3::multiprecision::big_uint<2 * NonNativeFieldType::modulus_bits>
extended_integral_type;
using non_native_integral_type = typename BlueprintFieldType::integral_type;


extended_integral_type B = extended_integral_type(1)
<< bit_size_chunk,
pow = 0;
non_native_integral_type pow = 1;
NON_NATIVE_TYPE xQ = 0, yQ = 0;

for (std::size_t i = 0; i < num_chunks; ++i) {
xQ += extended_integral_type(integral_type(public_input[i].data)) * pow;
yQ += extended_integral_type(integral_type(public_input[i + num_chunks].data)) *
xQ += non_native_integral_type(integral_type(public_input[i].data)) * pow;
yQ += non_native_integral_type(integral_type(public_input[i + num_chunks].data)) * pow;
pow <<= bit_size_chunk;
}


NON_NATIVE_TYPE lambda =
(yQ == 0)
? 0
: 3 * xQ * xQ *
((2 * yQ).inversed()), // if yQ = 0, lambda = 0
(yQ == 0)
? 0
: 3 * xQ * xQ *
((2 * yQ).inversed()), // if yQ = 0, lambda = 0
z = (yQ == 0) ? 0 : yQ.inversed(), // if yQ = 0, z = 0
expected_xR = lambda * lambda - 2 * xQ, expected_yR = lambda * (xQ - expected_xR) - yQ;

auto assign_and_check = [&](auto &B, auto &raw_input) {

auto assign_and_check = [&](auto& B, auto& raw_input) {
raw_input.xQ =
std::vector<TYPE>(public_input.begin(), public_input.begin() + num_chunks);
raw_input.yQ =
std::vector<TYPE>(public_input.begin(), public_input.begin() + num_chunks);
raw_input.p = std::vector<TYPE>(public_input.begin() + num_chunks,
public_input.begin() + 2 * num_chunks);
raw_input.pp = std::vector<TYPE>(public_input.begin() + 2 * num_chunks,
public_input.begin() + 3 * num_chunks);
raw_input.zero = public_input[3 * num_chunks];
std::vector<TYPE>(public_input.begin() + num_chunks, public_input.begin() + 2 * num_chunks);
raw_input.p = std::vector<TYPE>(public_input.begin() + 2 * num_chunks,
public_input.begin() + 3 * num_chunks);
raw_input.pp = std::vector<TYPE>(public_input.begin() + 3 * num_chunks,
public_input.begin() + 4 * num_chunks);
raw_input.zero = public_input[4 * num_chunks];

auto [at, A, desc] = B.assign(raw_input);
bool pass = B.is_satisfied(at);
std::cout << "Is_satisfied = " << pass << std::endl;

assert(pass == true);
extended_integral_type xR = 0;
extended_integral_type yR = 0;
assert(pass == true);
non_native_integral_type xR = 0;
non_native_integral_type yR = 0;
pow = 1;
for (std::size_t i = 0; i < num_chunks; i++) {
xR += extended_integral_type(integral_type(A.res_xR[i].data)) * pow;
yR += extended_integral_type(integral_type(A.res_yR[i].data)) * pow;
xR += non_native_integral_type(integral_type(A.res_xR[i].data)) * pow;
yR += non_native_integral_type(integral_type(A.res_yR[i].data)) * pow;
pow <<= bit_size_chunk;
}
#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED
std::cout << "negation_mod_p test" << std::endl;
std::cout << "Expected xR - yR: " << std::dec << expected_xR.data << " - " << expected_yR.data << std::endl;
//#ifdef BLUEPRINT_PLONK_PROFILING_ENABLED
std::cout << "Expected xR - yR: " << std::dec << expected_xR.data << " - " << expected_yR.data << std::endl;
std::cout << "Real res xR - yR: " << std::dec << xR << " - " << yR << std::endl;
#endif
//#endif
assert(xR == expected_xR.data);
assert(yR == expected_yR.data);
};
};

if constexpr (std::is_same_v<NonNativeFieldType,
crypto3::algebra::curves::pallas::base_field_type>) {
typename bbf::components::vesta_ec_double<
crypto3::algebra::curves::pallas::base_field_type>) {
typename bbf::components::pallas_ec_double<
FieldType, bbf::GenerationStage::ASSIGNMENT>::raw_input_type raw_input;

auto B =
bbf::circuit_builder<FieldType, bbf::components::vesta_ec_double,
std::size_t, std::size_t>(num_chunks, bit_size_chunk);
bbf::circuit_builder<FieldType, bbf::components::pallas_ec_double,
std::size_t, std::size_t>(num_chunks, bit_size_chunk);

assign_and_check(B, raw_input);
} else if constexpr (std::is_same_v<
NonNativeFieldType,
crypto3::algebra::curves::vesta::base_field_type>) {
typename bbf::components::pallas_ec_double<
}
else if constexpr (std::is_same_v<
NonNativeFieldType,
crypto3::algebra::curves::vesta::base_field_type>) {
typename bbf::components::vesta_ec_double<
FieldType, bbf::GenerationStage::ASSIGNMENT>::raw_input_type raw_input;
auto B =
bbf::circuit_builder<FieldType, bbf::components::pallas_ec_double,
std::size_t, std::size_t>(num_chunks, bit_size_chunk);
bbf::circuit_builder<FieldType, bbf::components::vesta_ec_double,
std::size_t, std::size_t>(num_chunks, bit_size_chunk);

assign_and_check(B, raw_input);
}
}

template<typename BlueprintFieldType, typename NonNativeFieldType, std::size_t num_chunks,
std::size_t bit_size_chunk, std::size_t RandomTestsAmount>
template<typename BlueprintFieldType, typename Curve, std::size_t num_chunks,
std::size_t bit_size_chunk, std::size_t RandomTestsAmount>
void ec_double_tests() {
using NonNativeFieldType = typename Curve::base_field_type;
using value_type = typename BlueprintFieldType::value_type;
using integral_type = typename BlueprintFieldType::integral_type;
using foreign_value_type = typename NonNativeFieldType::value_type;
using ec_point_value_type = typename Curve::template g1_type<nil::crypto3::algebra::curves::coordinates::affine>::value_type;

typedef nil::crypto3::multiprecision::big_uint<2 * NonNativeFieldType::modulus_bits>
extended_integral_type;

static boost::random::mt19937 seed_seq;
static nil::crypto3::random::algebraic_engine<NonNativeFieldType> generate_random(
static nil::crypto3::random::algebraic_engine<BlueprintFieldType> generate_random(
seed_seq);
boost::random::uniform_int_distribution<> t_dist(0, 1);


extended_integral_type mask = (extended_integral_type(1) << bit_size_chunk) - 1;

for (std::size_t i = 0; i < RandomTestsAmount; i++) {
std::vector<typename BlueprintFieldType::value_type> public_input;

foreign_value_type src_x = generate_random(), src_y = generate_random();
extended_integral_type extended_base = 1,
ext_pow = extended_base << (num_chunks * bit_size_chunk),
p = NonNativeFieldType::modulus,
pp = ext_pow - p;

extended_integral_type xQ = extended_integral_type(integral_type(src_x.data)),
yQ = extended_integral_type(integral_type(src_y.data)),
extended_base = 1,
ext_pow = extended_base << (num_chunks * bit_size_chunk),
p = NonNativeFieldType::modulus;
extended_integral_type pp = ext_pow - p;
value_type d = generate_random();
ec_point_value_type Q = ec_point_value_type::one();
Q = Q * d;

public_input.resize(3 * num_chunks + 1);
public_input.resize(4 * num_chunks + 1);
integral_type xQ = integral_type(Q.X.data);
integral_type yQ = integral_type(Q.Y.data);
for (std::size_t j = 0; j < num_chunks; j++) {
public_input[j] = value_type(xQ & mask);
xQ >>= bit_size_chunk;

public_input[j] = value_type(yQ & mask);
public_input[1 * num_chunks + j] = value_type(yQ & mask);
yQ >>= bit_size_chunk;

public_input[1 * num_chunks + j] = value_type(p & mask);
public_input[2 * num_chunks + j] = value_type(p & mask);
p >>= bit_size_chunk;

public_input[2 * num_chunks + j] = value_type(pp & mask);
public_input[3 * num_chunks + j] = value_type(pp & mask);
pp >>= bit_size_chunk;
}
public_input.push_back(value_type(0)); // the zero

test_ec_double<BlueprintFieldType, NonNativeFieldType, num_chunks,
bit_size_chunk>(public_input);
bit_size_chunk>(public_input);
}
}

Expand All @@ -179,26 +185,20 @@ constexpr static const std::size_t random_tests_amount = 10;
BOOST_AUTO_TEST_SUITE(blueprint_plonk_test_suite)

BOOST_AUTO_TEST_CASE(blueprint_plonk_bbf_ec_double_test) {
using pallas_field_type = typename crypto3::algebra::curves::pallas::base_field_type;
using vesta_field_type = typename crypto3::algebra::curves::vesta::base_field_type;

ec_double_tests<pallas_field_type, vesta_field_type, 8, 32,
random_tests_amount>();
using pallas = typename crypto3::algebra::curves::pallas;
using vesta = typename crypto3::algebra::curves::vesta;

ec_double_tests<pallas_field_type, vesta_field_type, 4, 65,
random_tests_amount>();
ec_double_tests<pallas::base_field_type, vesta, 8, 32,
random_tests_amount>();

ec_double_tests<pallas_field_type, pallas_field_type, 8, 34,
random_tests_amount>();
ec_double_tests<pallas::base_field_type, vesta, 4, 65, random_tests_amount>();

ec_double_tests<vesta_field_type, pallas_field_type, 2, 253,
random_tests_amount>();
ec_double_tests<vesta::base_field_type, pallas, 4, 65,
random_tests_amount>();

ec_double_tests<vesta_field_type, pallas_field_type, 12, 22,
random_tests_amount>();
ec_double_tests<vesta::base_field_type, pallas, 12, 22,
random_tests_amount>();

ec_double_tests<vesta_field_type, vesta_field_type, 8, 33,
random_tests_amount>();
}

BOOST_AUTO_TEST_SUITE_END()
Original file line number Diff line number Diff line change
Expand Up @@ -101,23 +101,23 @@ void test_addition_mod_p(const std::vector<typename BlueprintFieldType::value_ty

if constexpr (std::is_same_v<NonNativeFieldType,
crypto3::algebra::curves::pallas::base_field_type>) {
typename bbf::components::vesta_addition_mod_p<
typename bbf::components::pallas_addition_mod_p<
FieldType, bbf::GenerationStage::ASSIGNMENT>::raw_input_type raw_input;

auto B =
bbf::circuit_builder<FieldType,
bbf::components::vesta_addition_mod_p,
bbf::components::pallas_addition_mod_p,
std::size_t, std::size_t>(num_chunks, bit_size_chunk);

assign_and_check(B, raw_input);
} else if constexpr (std::is_same_v<
NonNativeFieldType,
crypto3::algebra::curves::vesta::base_field_type>) {
typename bbf::components::pallas_addition_mod_p<
typename bbf::components::vesta_addition_mod_p<
FieldType, bbf::GenerationStage::ASSIGNMENT>::raw_input_type raw_input;
auto B =
bbf::circuit_builder<FieldType,
bbf::components::pallas_addition_mod_p,
bbf::components::vesta_addition_mod_p,
std::size_t, std::size_t>(num_chunks, bit_size_chunk);

assign_and_check(B, raw_input);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,24 +110,24 @@ void test_mult(const std::vector<typename BlueprintFieldType::value_type> &publi

if constexpr (std::is_same_v<NonNativeFieldType,
crypto3::algebra::curves::pallas::base_field_type>) {
typename bbf::components::vesta_flexible_multiplication<
typename bbf::components::pallas_flexible_multiplication<
FieldType, bbf::GenerationStage::ASSIGNMENT>::raw_input_type raw_input;

auto B =
bbf::circuit_builder<FieldType,
bbf::components::vesta_flexible_multiplication,
bbf::components::pallas_flexible_multiplication,
std::size_t, std::size_t>(num_chunks, bit_size_chunk);

assign_and_check(B, raw_input);
} else if constexpr (std::is_same_v<
NonNativeFieldType,
crypto3::algebra::curves::vesta::base_field_type>) {
typename bbf::components::pallas_flexible_multiplication<
typename bbf::components::vesta_flexible_multiplication<
FieldType, bbf::GenerationStage::ASSIGNMENT>::raw_input_type raw_input;

auto B =
bbf::circuit_builder<FieldType,
bbf::components::pallas_flexible_multiplication,
bbf::components::vesta_flexible_multiplication,
std::size_t, std::size_t>(num_chunks, bit_size_chunk);

assign_and_check(B, raw_input);
Expand Down Expand Up @@ -232,6 +232,7 @@ void mult_tests_to_fail() {
public_input[3 * num_chunks + j] = value_type(pp & mask);
pp >>= bit_size_chunk;
}
public_input.push_back(value_type(0)); // the zero

test_mult<BlueprintFieldType, NonNativeFieldType, num_chunks, bit_size_chunk,
false>(public_input);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,21 +91,21 @@ void test_negation_mod_p(

if constexpr (std::is_same_v<NonNativeFieldType,
crypto3::algebra::curves::pallas::base_field_type>) {
typename bbf::components::vesta_negation_mod_p<
typename bbf::components::pallas_negation_mod_p<
FieldType, bbf::GenerationStage::ASSIGNMENT>::raw_input_type raw_input;

auto B =
bbf::circuit_builder<FieldType, bbf::components::vesta_negation_mod_p,
bbf::circuit_builder<FieldType, bbf::components::pallas_negation_mod_p,
std::size_t, std::size_t>(num_chunks, bit_size_chunk);

assign_and_check(B, raw_input);
} else if constexpr (std::is_same_v<
NonNativeFieldType,
crypto3::algebra::curves::vesta::base_field_type>) {
typename bbf::components::pallas_negation_mod_p<
typename bbf::components::vesta_negation_mod_p<
FieldType, bbf::GenerationStage::ASSIGNMENT>::raw_input_type raw_input;
auto B =
bbf::circuit_builder<FieldType, bbf::components::pallas_negation_mod_p,
bbf::circuit_builder<FieldType, bbf::components::vesta_negation_mod_p,
std::size_t, std::size_t>(num_chunks, bit_size_chunk);

assign_and_check(B, raw_input);
Expand Down

0 comments on commit 3eb2601

Please sign in to comment.