From 2a85796cd98c34198a8cf37c0acc164652cb67aa Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Tue, 14 Nov 2023 20:43:51 -0500 Subject: [PATCH 1/6] add benchmarking for Montgomery form host functions --- benchmark/benchmark.cpp | 2 +- benchmark/bls.cpp | 435 ++++++++++++++++++++++++++++++---------- 2 files changed, 331 insertions(+), 106 deletions(-) diff --git a/benchmark/benchmark.cpp b/benchmark/benchmark.cpp index 5c142c4162..a8ede0f68f 100644 --- a/benchmark/benchmark.cpp +++ b/benchmark/benchmark.cpp @@ -19,7 +19,7 @@ std::map> features { }; // values to control cout format -constexpr auto name_width = 28; +constexpr auto name_width = 40; constexpr auto runs_width = 5; constexpr auto time_width = 12; constexpr auto ns_width = 2; diff --git a/benchmark/bls.cpp b/benchmark/bls.cpp index fe03a66ccb..623ac1c281 100644 --- a/benchmark/bls.cpp +++ b/benchmark/bls.cpp @@ -107,6 +107,32 @@ std::array random_scalar() }; } +// utilility to create a random fp +fp random_fe() +{ + std::random_device rd; + std::mt19937_64 gen(rd()); + std::uniform_int_distribution dis; + + return fp({ + dis(gen) % 0xb9feffffffffaaab, + dis(gen) % 0x1eabfffeb153ffff, + dis(gen) % 0x6730d2a0f6b0f624, + dis(gen) % 0x64774b84f38512bf, + dis(gen) % 0x4b1ba7b6434bacd7, + dis(gen) % 0x1a0111ea397fe69a + }); +} + +// utilility to create a random fp2 +fp2 random_fe2() +{ + return fp2({ + random_fe(), + random_fe() + }); +} + // utilility to create a random g1 bls12_381::g1 random_g1() { @@ -122,11 +148,11 @@ bls12_381::g2 random_g2() } // bls_g1_add benchmarking -void benchmark_bls_g1_add() { +void benchmark_bls_g1_add_impl(std::string test_name, bool mont) { // prepare g1 operand in Jacobian LE format g1 p = random_g1(); std::vector buf(96); - p.toAffineBytesLE(std::span((uint8_t*)buf.data(), 96), true); + p.toAffineBytesLE(std::span((uint8_t*)buf.data(), 96), mont); eosio::chain::span op1(buf.data(), buf.size()); // prepare result operand @@ -135,19 +161,34 @@ void benchmark_bls_g1_add() { // set up bls_g1_add to be benchmarked interface_in_benchmark interface; - auto g1_add_func = [&]() { - interface.interface->bls_g1_add(op1, op1, result); - }; + std::function benchmarked_func {}; + if (mont) { + benchmarked_func = [&]() { + interface.interface->bls_g1_add_mont(op1, op1, result); + }; + } else { + benchmarked_func = [&]() { + interface.interface->bls_g1_add(op1, op1, result); + }; + } - benchmarking("bls_g1_add", g1_add_func); + benchmarking(test_name, benchmarked_func); +} + +void benchmark_bls_g1_add() { + benchmark_bls_g1_add_impl("bls_g1_add", false); +} + +void benchmark_bls_g1_add_mont() { + benchmark_bls_g1_add_impl("bls_g1_add_mont", true); } // bls_g2_add benchmarking -void benchmark_bls_g2_add() { +void benchmark_bls_g2_add_impl(std::string test_name, bool mont) { // prepare g2 operand in Jacobian LE format g2 p = random_g2(); std::vector buf(192); - p.toAffineBytesLE(std::span((uint8_t*)buf.data(), 192), true); + p.toAffineBytesLE(std::span((uint8_t*)buf.data(), 192), mont); eosio::chain::span op(buf.data(), buf.size()); // prepare result operand @@ -156,73 +197,35 @@ void benchmark_bls_g2_add() { // set up bls_g2_add to be benchmarked interface_in_benchmark interface; - auto benchmarked_func = [&]() { - interface.interface->bls_g2_add(op, op, result); - }; + std::function benchmarked_func {}; + if (mont) { + benchmarked_func = [&]() { + interface.interface->bls_g2_add_mont(op, op, result); + }; + } else { + benchmarked_func = [&]() { + interface.interface->bls_g2_add(op, op, result); + }; + } - benchmarking("bls_g2_add", benchmarked_func); + benchmarking(test_name, benchmarked_func); } -/* -// bls_g1_mul benchmarking -void benchmark_bls_g1_mul() { - // prepare g1 operand - g1 p = random_g1(); - std::vector buf(96); - p.toAffineBytesLE(std::span((uint8_t*)buf.data(), 96), true); - eosio::chain::span point(buf.data(), buf.size()); - // prepare scalar operand - std::array s = random_scalar(); - std::vector scalar_buf(32); - scalar::toBytesLE(s, std::span((uint8_t*)scalar_buf.data(), 32)); - eosio::chain::span scalar(scalar_buf.data(), scalar_buf.size()); - - // prepare result operand - std::vector result_buf(96); - eosio::chain::span result(result_buf.data(), result_buf.size()); - - // set up bls_g1_mul to be benchmarked - interface_in_benchmark interface; - auto benchmarked_func = [&]() { - interface.interface->bls_g1_mul(point, scalar, result); - }; - - benchmarking("bls_g1_mul", benchmarked_func); +void benchmark_bls_g2_add() { + benchmark_bls_g2_add_impl("bls_g2_add", false); } -// bls_g2_mul benchmarking -void benchmark_bls_g2_mul() { - g2 p = random_g2(); - std::vector buf(192); - p.toAffineBytesLE(std::span((uint8_t*)buf.data(), 192), true); - eosio::chain::span point(buf.data(), buf.size()); - - // prepare scalar operand - std::array s = random_scalar(); - std::vector scalar_buf(32); - scalar::toBytesLE(s, std::span((uint8_t*)scalar_buf.data(), 32)); - eosio::chain::span scalar(scalar_buf.data(), scalar_buf.size()); - - // prepare result operand - std::vector result_buf(192); - eosio::chain::span result(result_buf.data(), result_buf.size()); - - // set up bls_g2_mul to be benchmarked - interface_in_benchmark interface; - auto benchmarked_func = [&]() { - interface.interface->bls_g2_mul(point, scalar, result); - }; - - benchmarking("bls_g2_mul", benchmarked_func); +void benchmark_bls_g2_add_mont() { + benchmark_bls_g2_add_impl("bls_g2_add_mont", true); } -*/ + // bls_g1_weighted_sum benchmarking utility -void benchmark_bls_g1_weighted_sum(std::string test_name, uint32_t num_points) { +void benchmark_bls_g1_weighted_sum_impl(std::string test_name, uint32_t num_points, bool mont) { // prepare g1 points operand std::vector g1_buf(96*num_points); for (auto i=0u; i < num_points; ++i) { g1 p = random_g1(); - p.toAffineBytesLE(std::span((uint8_t*)g1_buf.data() + i * 96, 96), true); + p.toAffineBytesLE(std::span((uint8_t*)g1_buf.data() + i * 96, 96), mont); } chain::span g1_points(g1_buf.data(), g1_buf.size()); @@ -240,30 +243,57 @@ void benchmark_bls_g1_weighted_sum(std::string test_name, uint32_t num_points) { // set up bls_g1_weighted_sum to be benchmarked interface_in_benchmark interface; - auto benchmarked_func = [&]() { - interface.interface->bls_g1_weighted_sum(g1_points, scalars, num_points, result); - }; + std::function benchmarked_func {}; + if (mont) { + benchmarked_func = [&]() { + interface.interface->bls_g1_weighted_sum_mont(g1_points, scalars, num_points, result); + }; + } else { + benchmarked_func = [&]() { + interface.interface->bls_g1_weighted_sum(g1_points, scalars, num_points, result); + }; + } benchmarking(test_name, benchmarked_func); } // bls_g1_weighted_sum benchmarking with 1 input point void benchmark_bls_g1_weighted_sum_one_point() { - benchmark_bls_g1_weighted_sum("bls_g1_weighted_sum 1 point", 1); + benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum 1 point", 1, false); } // bls_g1_weighted_sum benchmarking with 3 input points void benchmark_bls_g1_weighted_sum_three_point() { - benchmark_bls_g1_weighted_sum("bls_g1_weighted_sum 3 points", 3); + benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum 3 points", 3, false); +} + +// bls_g1_weighted_sum benchmarking with 5 input points +void benchmark_bls_g1_weighted_sum_five_point() { + benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum 5 points", 5, false); +} + +// bls_g1_weighted_sum benchmarking with 1 input point +void benchmark_bls_g1_weighted_sum_mont_one_point() { + benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum_mont 1 point", 1, false); +} + +// bls_g1_weighted_sum_mont benchmarking with 3 input points +void benchmark_bls_g1_weighted_sum_mont_three_point() { + benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum_mont 3 points", 3, false); +} + +// bls_g1_weighted_sum_mont benchmarking with 5 input points +void benchmark_bls_g1_weighted_sum_mont_five_point() { + benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum_mont 5 points", 5, false); } // bls_g2_weighted_sum benchmarking utility -void benchmark_bls_g2_weighted_sum(std::string test_name, uint32_t num_points) { +void benchmark_bls_g2_weighted_sum_impl(std::string test_name, uint32_t num_points, bool mont) { // prepare g2 points operand std::vector g2_buf(192*num_points); for (auto i=0u; i < num_points; ++i) { g2 p = random_g2(); - p.toAffineBytesLE(std::span((uint8_t*)g2_buf.data() + i * 192, 192), true); + p.toAffineBytesLE(std::span((uint8_t*)g2_buf.data() + i * 192, 192), mont); } eosio::chain::span g2_points(g2_buf.data(), g2_buf.size()); @@ -281,31 +311,58 @@ void benchmark_bls_g2_weighted_sum(std::string test_name, uint32_t num_points) { // set up bls_g2_weighted_sum to be benchmarked interface_in_benchmark interface; - auto benchmarked_func = [&]() { - interface.interface->bls_g2_weighted_sum(g2_points, scalars, num_points, result); - }; + std::function benchmarked_func {}; + if (mont) { + benchmarked_func = [&]() { + interface.interface->bls_g2_weighted_sum_mont(g2_points, scalars, num_points, result); + }; + } else { + benchmarked_func = [&]() { + interface.interface->bls_g2_weighted_sum(g2_points, scalars, num_points, result); + }; + } benchmarking(test_name, benchmarked_func); } // bls_g2_weighted_sum benchmarking with 1 input point void benchmark_bls_g2_weighted_sum_one_point() { - benchmark_bls_g2_weighted_sum("bls_g2_weighted_sum 1 point", 1); + benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum 1 point", 1, false); } // bls_g2_weighted_sum benchmarking with 3 input points void benchmark_bls_g2_weighted_sum_three_point() { - benchmark_bls_g2_weighted_sum("bls_g2_weighted_sum 3 points", 3); + benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum 3 points", 3, false); +} + +// bls_g2_weighted_sum benchmarking with 5 input points +void benchmark_bls_g2_weighted_sum_five_point() { + benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum 5 points", 5, false); +} + +// bls_g2_weighted_sum_mont benchmarking with 1 input point +void benchmark_bls_g2_weighted_sum_mont_one_point() { + benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum_mont 1 point", 1, false); +} + +// bls_g2_weighted_sum_mont benchmarking with 3 input points +void benchmark_bls_g2_weighted_sum_mont_three_point() { + benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum_mont 3 points", 3, false); +} + +// bls_g2_weighted_sum_mont benchmarking with 5 input points +void benchmark_bls_g2_weighted_sum_mont_five_point() { + benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum_mont 5 points", 5, false); } // bls_pairing benchmarking utility -void benchmark_bls_pairing(std::string test_name, uint32_t num_pairs) { +void benchmark_bls_pairing_impl(std::string test_name, uint32_t num_pairs, bool mont) { // prepare g1 operand std::vector g1_buf(96*num_pairs); //g1_buf.reserve(96*num_pairs); for (auto i=0u; i < num_pairs; ++i) { g1 p = random_g1(); - p.toAffineBytesLE(std::span((uint8_t*)g1_buf.data() + i * 96, 96), true); + p.toAffineBytesLE(std::span((uint8_t*)g1_buf.data() + i * 96, 96), mont); } eosio::chain::span g1_points(g1_buf.data(), g1_buf.size()); @@ -313,7 +370,7 @@ void benchmark_bls_pairing(std::string test_name, uint32_t num_pairs) { std::vector g2_buf(192*num_pairs); for (auto i=0u; i < num_pairs; ++i) { g2 p2 = random_g2(); - p2.toAffineBytesLE(std::span((uint8_t*)g2_buf.data() + i * 192, (192)), true); + p2.toAffineBytesLE(std::span((uint8_t*)g2_buf.data() + i * 192, (192)), mont); } eosio::chain::span g2_points(g2_buf.data(), g2_buf.size()); @@ -323,28 +380,47 @@ void benchmark_bls_pairing(std::string test_name, uint32_t num_pairs) { // set up bls_pairing to be benchmarked interface_in_benchmark interface; - auto benchmarked_func = [&]() { - interface.interface->bls_pairing(g1_points, g2_points, num_pairs, result); - }; + std::function benchmarked_func {}; + if (mont) { + benchmarked_func = [&]() { + interface.interface->bls_pairing_mont(g1_points, g2_points, num_pairs, result); + }; + } else { + benchmarked_func = [&]() { + interface.interface->bls_pairing(g1_points, g2_points, num_pairs, result); + }; + } benchmarking(test_name, benchmarked_func); } // bls_pairing benchmarking with 1 input pair void benchmark_bls_pairing_one_pair() { - benchmark_bls_pairing("bls_pairing 1 pair", 1); + benchmark_bls_pairing_impl("bls_pairing 1 pair", 1, false); } // bls_pairing benchmarking with 3 input pairs void benchmark_bls_pairing_three_pair() { - benchmark_bls_pairing("bls_pairing 3 pairs", 3); + benchmark_bls_pairing_impl("bls_pairing 3 pairs", 3, false); +} + +// bls_pairing_mont benchmarking with 1 input pair +void benchmark_bls_pairing_mont_one_pair() { + benchmark_bls_pairing_impl("bls_pairing_mont 1 pair", 1, true); +} + +// bls_pairing_mont benchmarking with 3 input pairs +void benchmark_bls_pairing_mont_three_pair() { + benchmark_bls_pairing_impl("bls_pairing_mont 3 pairs", 3, true); } // bls_g1_map benchmarking -void benchmark_bls_g1_map() { +void benchmark_bls_g1_map_impl(std::string test_name, bool mont) { // prepare e operand. Must be fp LE. - std::vector e_buf = {0xc9, 0x3f,0x81,0x7b, 0x15, 0x9b, 0xdf, 0x84, 0x04, 0xdc, 0x37, 0x85, 0x14, 0xf8, 0x45, 0x19, 0x2b, 0xba, 0xe4, 0xfa, 0xac, 0x7f, 0x4a, 0x56, 0x89, 0x24, 0xf2, 0xd9, 0x72, 0x51, 0x25, 0x00, 0x04, 0x89, 0x40, 0x8f, 0xd7, 0x96, 0x46, 0x1c, 0x28, 0x89, 0x00, 0xad, 0xd0, 0x0d, 0x46, 0x18}; - eosio::chain::span e((char*)e_buf.data(), e_buf.size()); + std::vector e_buf(48); + fp a = random_fe(); + a.toBytesLE(std::span((uint8_t*)e_buf.data(), 48), mont); + eosio::chain::span e(e_buf.data(), e_buf.size()); // prepare result operand std::vector result_buf(96); @@ -352,18 +428,35 @@ void benchmark_bls_g1_map() { // set up bls_g1_map to be benchmarked interface_in_benchmark interface; - auto benchmarked_func = [&]() { - interface.interface->bls_g1_map(e, result); - }; + std::function benchmarked_func {}; + if (mont) { + benchmarked_func = [&]() { + interface.interface->bls_g1_map_mont(e, result); + }; + } else { + benchmarked_func = [&]() { + interface.interface->bls_g1_map(e, result); + }; + } - benchmarking("bls_g1_map", benchmarked_func); + benchmarking(test_name, benchmarked_func); +} + +void benchmark_bls_g1_map() { + benchmark_bls_g1_map_impl("bls_g1_map", false); +} + +void benchmark_bls_g1_map_mont() { + benchmark_bls_g1_map_impl("bls_g1_map_mont", true); } // bls_g2_map benchmarking -void benchmark_bls_g2_map() { +void benchmark_bls_g2_map_impl(std::string test_name, bool mont) { // prepare e operand. Must be fp2 LE. - std::vector e_buf = {0xd4, 0xf2, 0xcf, 0xec, 0x99, 0x38, 0x78, 0x09, 0x57, 0x4f, 0xcc, 0x2d, 0xba, 0x10, 0x56, 0x03, 0xd9, 0x50, 0xd4, 0x90, 0xe2, 0xbe, 0xbe, 0x0c, 0x21, 0x2c, 0x05, 0xe1, 0x6b, 0x78, 0x47, 0x45, 0xef, 0x4f, 0xe8, 0xe7, 0x0b, 0x55, 0x4d, 0x0a, 0x52, 0xfe, 0x0b, 0xed, 0x5e, 0xa6, 0x69, 0x0a, 0xde, 0x23, 0x48, 0xeb, 0x89, 0x72, 0xa9, 0x67, 0x40, 0xa4, 0x30, 0xdf, 0x16, 0x2d, 0x92, 0x0e, 0x17, 0x5f, 0x59, 0x23, 0xa7, 0x6d, 0x18, 0x65, 0x0e, 0xa2, 0x4a, 0x8e, 0xc0, 0x6d, 0x41, 0x4c, 0x6d, 0x1d, 0x21, 0x8d, 0x67, 0x3d, 0xac, 0x36, 0x19, 0xa1, 0xa5, 0xc1, 0x42, 0x78, 0x57, 0x08}; - eosio::chain::span e((char*)e_buf.data(), e_buf.size()); + std::vector e_buf(96); + fp2 a = random_fe2(); + a.toBytesLE(std::span((uint8_t*)e_buf.data(), 96), mont); + eosio::chain::span e(e_buf.data(), e_buf.size()); // prepare result operand std::vector result_buf(192); @@ -371,15 +464,30 @@ void benchmark_bls_g2_map() { // set up bls_g2_map to be benchmarked interface_in_benchmark interface; - auto benchmarked_func = [&]() { - interface.interface->bls_g2_map(e, result); - }; + std::function benchmarked_func {}; + if (mont) { + benchmarked_func = [&]() { + interface.interface->bls_g2_map_mont(e, result); + }; + } else { + benchmarked_func = [&]() { + interface.interface->bls_g2_map(e, result); + }; + } + + benchmarking(test_name, benchmarked_func); +} + +void benchmark_bls_g2_map() { + benchmark_bls_g2_map_impl("bls_g2_map", false); +} - benchmarking("bls_g2_map", benchmarked_func); +void benchmark_bls_g2_map_mont() { + benchmark_bls_g2_map_impl("bls_g2_map_mont", true); } // bls_fp_mod benchmarking -void benchmark_bls_fp_mod() { +void benchmark_bls_fp_mod_impl(std::string test_name, bool mont) { // prepare scalar operand std::vector scalar_buf(64); // random_scalar returns 32 bytes. need to call it twice @@ -395,27 +503,144 @@ void benchmark_bls_fp_mod() { // set up bls_fp_mod to be benchmarked interface_in_benchmark interface; - auto benchmarked_func = [&]() { - interface.interface->bls_fp_mod(scalar, result); - }; + std::function benchmarked_func {}; + if (mont) { + benchmarked_func = [&]() { + interface.interface->bls_fp_mod_mont(scalar, result); + }; + } else { + benchmarked_func = [&]() { + interface.interface->bls_fp_mod(scalar, result); + }; + } + + benchmarking(test_name, benchmarked_func); +} + +void benchmark_bls_fp_mod() { + benchmark_bls_fp_mod_impl("bls_fp_mod", false); +} + +void benchmark_bls_fp_mod_mont() { + benchmark_bls_fp_mod_impl("bls_fp_mod_mont", true); +} + +void benchmark_bls_fp_mul_impl(std::string test_name, bool mont) { + // prepare op1 + std::vector op1_buf(48); + fp a = random_fe(); + a.toBytesLE(std::span((uint8_t*)op1_buf.data(), 48), mont); + eosio::chain::span op1(op1_buf.data(), op1_buf.size()); + + // prepare op2 + std::vector op2_buf(48); + fp b = random_fe(); + b.toBytesLE(std::span((uint8_t*)op2_buf.data(), 48), mont); + eosio::chain::span op2(op1_buf.data(), op2_buf.size()); + + // prepare result operand + std::vector result_buf(48); + eosio::chain::span result(result_buf.data(), result_buf.size()); + + // set up bls_pairing to be benchmarked + interface_in_benchmark interface; + std::function benchmarked_func {}; + if (mont) { + benchmarked_func = [&]() { + interface.interface->bls_fp_mul_mont(op1, op2, result); + }; + } else { + benchmarked_func = [&]() { + interface.interface->bls_fp_mul(op1, op2, result); + }; + } + + benchmarking(test_name, benchmarked_func); +} + +void benchmark_bls_fp_mul() { + benchmark_bls_fp_mul_impl("bls_fp_mul", false); +} + +void benchmark_bls_fp_mul_mont() { + benchmark_bls_fp_mul_impl("bls_fp_mul_mont", true); +} + +void benchmark_bls_fp_exp_impl(std::string test_name, bool mont) { + // prepare base + std::vector base_buf(48); + fp a = random_fe(); + a.toBytesLE(std::span((uint8_t*)base_buf.data(), 48), mont); + eosio::chain::span base(base_buf.data(), base_buf.size()); + + // prepare exp operand + std::vector exp_buf(64); + // random_scalar returns 32 bytes. need to call it twice + for (auto i=0u; i < 2; ++i) { + std::array s = random_scalar(); + scalar::toBytesLE(s, std::span((uint8_t*)exp_buf.data() + i*32, 32)); + } + eosio::chain::span exp(exp_buf.data(), exp_buf.size()); + + // prepare result operand + std::vector result_buf(48); + eosio::chain::span result(result_buf.data(), result_buf.size()); + + // set up bls_fp_exp to be benchmarked + interface_in_benchmark interface; + std::function benchmarked_func {}; + if (mont) { + benchmarked_func = [&]() { + interface.interface->bls_fp_exp_mont(base, exp, result); + }; + } else { + benchmarked_func = [&]() { + interface.interface->bls_fp_exp(base, exp, result); + }; + } + + benchmarking(test_name, benchmarked_func); +} + +void benchmark_bls_fp_exp() { + benchmark_bls_fp_exp_impl("bls_fp_exp", false); +} - benchmarking("bls_fp_mod", benchmarked_func); +void benchmark_bls_fp_exp_mont() { + benchmark_bls_fp_exp_impl("bls_fp_exp_mont", true); } // register benchmarking functions void bls_benchmarking() { benchmark_bls_g1_add(); + benchmark_bls_g1_add_mont(); benchmark_bls_g2_add(); - // benchmark_bls_g1_mul(); - // benchmark_bls_g2_mul(); + benchmark_bls_g2_add_mont(); benchmark_bls_pairing_one_pair(); benchmark_bls_pairing_three_pair(); + benchmark_bls_pairing_mont_one_pair(); + benchmark_bls_pairing_mont_three_pair(); benchmark_bls_g1_weighted_sum_one_point(); benchmark_bls_g1_weighted_sum_three_point(); + benchmark_bls_g1_weighted_sum_five_point(); + benchmark_bls_g1_weighted_sum_mont_one_point(); + benchmark_bls_g1_weighted_sum_mont_three_point(); + benchmark_bls_g1_weighted_sum_mont_five_point(); benchmark_bls_g2_weighted_sum_one_point(); benchmark_bls_g2_weighted_sum_three_point(); + benchmark_bls_g2_weighted_sum_five_point(); + benchmark_bls_g2_weighted_sum_mont_one_point(); + benchmark_bls_g2_weighted_sum_mont_three_point(); + benchmark_bls_g2_weighted_sum_mont_five_point(); benchmark_bls_g1_map(); + benchmark_bls_g1_map_mont(); benchmark_bls_g2_map(); + benchmark_bls_g2_map_mont(); benchmark_bls_fp_mod(); + benchmark_bls_fp_mod_mont(); + benchmark_bls_fp_mul(); + benchmark_bls_fp_mul_mont(); + benchmark_bls_fp_exp(); + benchmark_bls_fp_exp_mont(); } } // namespace benchmark From 8819030169c0e590bfa0f7b48b40fbc5c821695f Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Wed, 15 Nov 2023 12:12:03 -0500 Subject: [PATCH 2/6] fix weighted sum montgomery form flag --- benchmark/bls.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/benchmark/bls.cpp b/benchmark/bls.cpp index 623ac1c281..98985c0d7d 100644 --- a/benchmark/bls.cpp +++ b/benchmark/bls.cpp @@ -274,17 +274,17 @@ void benchmark_bls_g1_weighted_sum_five_point() { // bls_g1_weighted_sum benchmarking with 1 input point void benchmark_bls_g1_weighted_sum_mont_one_point() { - benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum_mont 1 point", 1, false); + benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum_mont 1 point", 1, true); } // bls_g1_weighted_sum_mont benchmarking with 3 input points void benchmark_bls_g1_weighted_sum_mont_three_point() { - benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum_mont 3 points", 3, false); + benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum_mont 3 points", 3, true); } // bls_g1_weighted_sum_mont benchmarking with 5 input points void benchmark_bls_g1_weighted_sum_mont_five_point() { - benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum_mont 5 points", 5, false); + benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum_mont 5 points", 5, true); } // bls_g2_weighted_sum benchmarking utility @@ -342,17 +342,17 @@ void benchmark_bls_g2_weighted_sum_five_point() { // bls_g2_weighted_sum_mont benchmarking with 1 input point void benchmark_bls_g2_weighted_sum_mont_one_point() { - benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum_mont 1 point", 1, false); + benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum_mont 1 point", 1, true); } // bls_g2_weighted_sum_mont benchmarking with 3 input points void benchmark_bls_g2_weighted_sum_mont_three_point() { - benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum_mont 3 points", 3, false); + benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum_mont 3 points", 3, true); } // bls_g2_weighted_sum_mont benchmarking with 5 input points void benchmark_bls_g2_weighted_sum_mont_five_point() { - benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum_mont 5 points", 5, false); + benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum_mont 5 points", 5, true); } // bls_pairing benchmarking utility @@ -617,20 +617,20 @@ void bls_benchmarking() { benchmark_bls_g2_add(); benchmark_bls_g2_add_mont(); benchmark_bls_pairing_one_pair(); - benchmark_bls_pairing_three_pair(); benchmark_bls_pairing_mont_one_pair(); + benchmark_bls_pairing_three_pair(); benchmark_bls_pairing_mont_three_pair(); benchmark_bls_g1_weighted_sum_one_point(); - benchmark_bls_g1_weighted_sum_three_point(); - benchmark_bls_g1_weighted_sum_five_point(); benchmark_bls_g1_weighted_sum_mont_one_point(); + benchmark_bls_g1_weighted_sum_three_point(); benchmark_bls_g1_weighted_sum_mont_three_point(); + benchmark_bls_g1_weighted_sum_five_point(); benchmark_bls_g1_weighted_sum_mont_five_point(); benchmark_bls_g2_weighted_sum_one_point(); - benchmark_bls_g2_weighted_sum_three_point(); - benchmark_bls_g2_weighted_sum_five_point(); benchmark_bls_g2_weighted_sum_mont_one_point(); + benchmark_bls_g2_weighted_sum_three_point(); benchmark_bls_g2_weighted_sum_mont_three_point(); + benchmark_bls_g2_weighted_sum_five_point(); benchmark_bls_g2_weighted_sum_mont_five_point(); benchmark_bls_g1_map(); benchmark_bls_g1_map_mont(); From f280d5ee169dbc4ba26e2177b3fc4ac965f4194e Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Wed, 15 Nov 2023 13:29:19 -0500 Subject: [PATCH 3/6] add const& to std::string parameters in all _impl methods --- benchmark/bls.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/benchmark/bls.cpp b/benchmark/bls.cpp index 98985c0d7d..72e46b19f6 100644 --- a/benchmark/bls.cpp +++ b/benchmark/bls.cpp @@ -148,7 +148,7 @@ bls12_381::g2 random_g2() } // bls_g1_add benchmarking -void benchmark_bls_g1_add_impl(std::string test_name, bool mont) { +void benchmark_bls_g1_add_impl(const std::string& test_name, bool mont) { // prepare g1 operand in Jacobian LE format g1 p = random_g1(); std::vector buf(96); @@ -184,7 +184,7 @@ void benchmark_bls_g1_add_mont() { } // bls_g2_add benchmarking -void benchmark_bls_g2_add_impl(std::string test_name, bool mont) { +void benchmark_bls_g2_add_impl(const std::string& test_name, bool mont) { // prepare g2 operand in Jacobian LE format g2 p = random_g2(); std::vector buf(192); @@ -220,7 +220,7 @@ void benchmark_bls_g2_add_mont() { } // bls_g1_weighted_sum benchmarking utility -void benchmark_bls_g1_weighted_sum_impl(std::string test_name, uint32_t num_points, bool mont) { +void benchmark_bls_g1_weighted_sum_impl(const std::string& test_name, uint32_t num_points, bool mont) { // prepare g1 points operand std::vector g1_buf(96*num_points); for (auto i=0u; i < num_points; ++i) { @@ -288,7 +288,7 @@ void benchmark_bls_g1_weighted_sum_mont_five_point() { } // bls_g2_weighted_sum benchmarking utility -void benchmark_bls_g2_weighted_sum_impl(std::string test_name, uint32_t num_points, bool mont) { +void benchmark_bls_g2_weighted_sum_impl(const std::string& test_name, uint32_t num_points, bool mont) { // prepare g2 points operand std::vector g2_buf(192*num_points); for (auto i=0u; i < num_points; ++i) { @@ -356,7 +356,7 @@ void benchmark_bls_g2_weighted_sum_mont_five_point() { } // bls_pairing benchmarking utility -void benchmark_bls_pairing_impl(std::string test_name, uint32_t num_pairs, bool mont) { +void benchmark_bls_pairing_impl(const std::string& test_name, uint32_t num_pairs, bool mont) { // prepare g1 operand std::vector g1_buf(96*num_pairs); //g1_buf.reserve(96*num_pairs); @@ -415,7 +415,7 @@ void benchmark_bls_pairing_mont_three_pair() { } // bls_g1_map benchmarking -void benchmark_bls_g1_map_impl(std::string test_name, bool mont) { +void benchmark_bls_g1_map_impl(const std::string& test_name, bool mont) { // prepare e operand. Must be fp LE. std::vector e_buf(48); fp a = random_fe(); @@ -451,7 +451,7 @@ void benchmark_bls_g1_map_mont() { } // bls_g2_map benchmarking -void benchmark_bls_g2_map_impl(std::string test_name, bool mont) { +void benchmark_bls_g2_map_impl(const std::string& test_name, bool mont) { // prepare e operand. Must be fp2 LE. std::vector e_buf(96); fp2 a = random_fe2(); @@ -487,7 +487,7 @@ void benchmark_bls_g2_map_mont() { } // bls_fp_mod benchmarking -void benchmark_bls_fp_mod_impl(std::string test_name, bool mont) { +void benchmark_bls_fp_mod_impl(const std::string& test_name, bool mont) { // prepare scalar operand std::vector scalar_buf(64); // random_scalar returns 32 bytes. need to call it twice @@ -525,7 +525,7 @@ void benchmark_bls_fp_mod_mont() { benchmark_bls_fp_mod_impl("bls_fp_mod_mont", true); } -void benchmark_bls_fp_mul_impl(std::string test_name, bool mont) { +void benchmark_bls_fp_mul_impl(const std::string& test_name, bool mont) { // prepare op1 std::vector op1_buf(48); fp a = random_fe(); @@ -566,7 +566,7 @@ void benchmark_bls_fp_mul_mont() { benchmark_bls_fp_mul_impl("bls_fp_mul_mont", true); } -void benchmark_bls_fp_exp_impl(std::string test_name, bool mont) { +void benchmark_bls_fp_exp_impl(const std::string& test_name, bool mont) { // prepare base std::vector base_buf(48); fp a = random_fe(); From 65b54ab2eeb59ac381ed78463badcb83779e61cb Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Thu, 16 Nov 2023 09:29:43 -0500 Subject: [PATCH 4/6] resolve merge conflicts --- benchmark/bls.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/benchmark/bls.cpp b/benchmark/bls.cpp index 9906b6402e..6eb19c8de7 100644 --- a/benchmark/bls.cpp +++ b/benchmark/bls.cpp @@ -619,10 +619,7 @@ void bls_benchmarking() { benchmark_bls_g1_add(); benchmark_bls_g1_add_mont(); benchmark_bls_g2_add(); -<<<<<<< HEAD benchmark_bls_g2_add_mont(); -======= ->>>>>>> origin/yarkin/update_bls benchmark_bls_pairing_one_pair(); benchmark_bls_pairing_mont_one_pair(); benchmark_bls_pairing_three_pair(); From c39e930491c2345dd175aec12d6d7abc26fc7e03 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Thu, 16 Nov 2023 09:59:34 -0500 Subject: [PATCH 5/6] remove _mont* functions --- benchmark/bls.cpp | 319 ++++++++++------------------------------------ 1 file changed, 67 insertions(+), 252 deletions(-) diff --git a/benchmark/bls.cpp b/benchmark/bls.cpp index 6eb19c8de7..2b83069145 100644 --- a/benchmark/bls.cpp +++ b/benchmark/bls.cpp @@ -148,12 +148,12 @@ bls12_381::g2 random_g2() } // bls_g1_add benchmarking -void benchmark_bls_g1_add_impl(const std::string& test_name, bool mont) { +void benchmark_bls_g1_add() { // prepare g1 operand in Jacobian LE format g1 p = random_g1(); std::vector buf(96); - p.toAffineBytesLE(std::span((uint8_t*)buf.data(), 96), mont); - eosio::chain::span op1(buf.data(), buf.size()); + p.toAffineBytesLE(std::span((uint8_t*)buf.data(), 96), false); + eosio::chain::span op(buf.data(), buf.size()); // prepare result operand std::vector result_buf(96); @@ -161,34 +161,19 @@ void benchmark_bls_g1_add_impl(const std::string& test_name, bool mont) { // set up bls_g1_add to be benchmarked interface_in_benchmark interface; - std::function benchmarked_func {}; - if (mont) { - benchmarked_func = [&]() { - interface.interface->bls_g1_add_mont(op1, op1, result); - }; - } else { - benchmarked_func = [&]() { - interface.interface->bls_g1_add(op1, op1, result); - }; - } - - benchmarking(test_name, benchmarked_func); -} - -void benchmark_bls_g1_add() { - benchmark_bls_g1_add_impl("bls_g1_add", false); -} + auto benchmarked_func = [&]() { + interface.interface->bls_g1_add(op, op, result); + }; -void benchmark_bls_g1_add_mont() { - benchmark_bls_g1_add_impl("bls_g1_add_mont", true); + benchmarking("bls_g1_add", benchmarked_func); } // bls_g2_add benchmarking -void benchmark_bls_g2_add_impl(const std::string& test_name, bool mont) { +void benchmark_bls_g2_add() { // prepare g2 operand in Jacobian LE format g2 p = random_g2(); std::vector buf(192); - p.toAffineBytesLE(std::span((uint8_t*)buf.data(), 192), mont); + p.toAffineBytesLE(std::span((uint8_t*)buf.data(), 192), false); eosio::chain::span op(buf.data(), buf.size()); // prepare result operand @@ -197,39 +182,20 @@ void benchmark_bls_g2_add_impl(const std::string& test_name, bool mont) { // set up bls_g2_add to be benchmarked interface_in_benchmark interface; - std::function benchmarked_func {}; - if (mont) { - benchmarked_func = [&]() { - interface.interface->bls_g2_add_mont(op, op, result); - }; - } else { - benchmarked_func = [&]() { - interface.interface->bls_g2_add(op, op, result); - }; - } - -<<<<<<< HEAD - benchmarking(test_name, benchmarked_func); -} - -void benchmark_bls_g2_add() { - benchmark_bls_g2_add_impl("bls_g2_add", false); -} + auto benchmarked_func = [&]() { + interface.interface->bls_g2_add(op, op, result); + }; -void benchmark_bls_g2_add_mont() { - benchmark_bls_g2_add_impl("bls_g2_add_mont", true); -======= benchmarking("bls_g2_add", benchmarked_func); ->>>>>>> origin/yarkin/update_bls } // bls_g1_weighted_sum benchmarking utility -void benchmark_bls_g1_weighted_sum_impl(const std::string& test_name, uint32_t num_points, bool mont) { +void benchmark_bls_g1_weighted_sum_impl(const std::string& test_name, uint32_t num_points) { // prepare g1 points operand std::vector g1_buf(96*num_points); for (auto i=0u; i < num_points; ++i) { g1 p = random_g1(); - p.toAffineBytesLE(std::span((uint8_t*)g1_buf.data() + i * 96, 96), mont); + p.toAffineBytesLE(std::span((uint8_t*)g1_buf.data() + i * 96, 96), false); } chain::span g1_points(g1_buf.data(), g1_buf.size()); @@ -247,57 +213,35 @@ void benchmark_bls_g1_weighted_sum_impl(const std::string& test_name, uint32_t n // set up bls_g1_weighted_sum to be benchmarked interface_in_benchmark interface; - std::function benchmarked_func {}; - if (mont) { - benchmarked_func = [&]() { - interface.interface->bls_g1_weighted_sum_mont(g1_points, scalars, num_points, result); - }; - } else { - benchmarked_func = [&]() { - interface.interface->bls_g1_weighted_sum(g1_points, scalars, num_points, result); - }; - } + auto benchmarked_func = [&]() { + interface.interface->bls_g1_weighted_sum(g1_points, scalars, num_points, result); + }; benchmarking(test_name, benchmarked_func); } // bls_g1_weighted_sum benchmarking with 1 input point void benchmark_bls_g1_weighted_sum_one_point() { - benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum 1 point", 1, false); + benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum 1 point", 1); } // bls_g1_weighted_sum benchmarking with 3 input points void benchmark_bls_g1_weighted_sum_three_point() { - benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum 3 points", 3, false); + benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum 3 points", 3); } // bls_g1_weighted_sum benchmarking with 5 input points void benchmark_bls_g1_weighted_sum_five_point() { - benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum 5 points", 5, false); -} - -// bls_g1_weighted_sum benchmarking with 1 input point -void benchmark_bls_g1_weighted_sum_mont_one_point() { - benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum_mont 1 point", 1, true); -} - -// bls_g1_weighted_sum_mont benchmarking with 3 input points -void benchmark_bls_g1_weighted_sum_mont_three_point() { - benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum_mont 3 points", 3, true); -} - -// bls_g1_weighted_sum_mont benchmarking with 5 input points -void benchmark_bls_g1_weighted_sum_mont_five_point() { - benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum_mont 5 points", 5, true); + benchmark_bls_g1_weighted_sum_impl("bls_g1_weighted_sum 5 points", 5); } // bls_g2_weighted_sum benchmarking utility -void benchmark_bls_g2_weighted_sum_impl(const std::string& test_name, uint32_t num_points, bool mont) { +void benchmark_bls_g2_weighted_sum_impl(const std::string& test_name, uint32_t num_points) { // prepare g2 points operand std::vector g2_buf(192*num_points); for (auto i=0u; i < num_points; ++i) { g2 p = random_g2(); - p.toAffineBytesLE(std::span((uint8_t*)g2_buf.data() + i * 192, 192), mont); + p.toAffineBytesLE(std::span((uint8_t*)g2_buf.data() + i * 192, 192), false); } eosio::chain::span g2_points(g2_buf.data(), g2_buf.size()); @@ -315,58 +259,36 @@ void benchmark_bls_g2_weighted_sum_impl(const std::string& test_name, uint32_t n // set up bls_g2_weighted_sum to be benchmarked interface_in_benchmark interface; - std::function benchmarked_func {}; - if (mont) { - benchmarked_func = [&]() { - interface.interface->bls_g2_weighted_sum_mont(g2_points, scalars, num_points, result); - }; - } else { - benchmarked_func = [&]() { - interface.interface->bls_g2_weighted_sum(g2_points, scalars, num_points, result); - }; - } + auto benchmarked_func = [&]() { + interface.interface->bls_g2_weighted_sum(g2_points, scalars, num_points, result); + }; benchmarking(test_name, benchmarked_func); } // bls_g2_weighted_sum benchmarking with 1 input point void benchmark_bls_g2_weighted_sum_one_point() { - benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum 1 point", 1, false); + benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum 1 point", 1); } // bls_g2_weighted_sum benchmarking with 3 input points void benchmark_bls_g2_weighted_sum_three_point() { - benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum 3 points", 3, false); + benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum 3 points", 3); } // bls_g2_weighted_sum benchmarking with 5 input points void benchmark_bls_g2_weighted_sum_five_point() { - benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum 5 points", 5, false); -} - -// bls_g2_weighted_sum_mont benchmarking with 1 input point -void benchmark_bls_g2_weighted_sum_mont_one_point() { - benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum_mont 1 point", 1, true); -} - -// bls_g2_weighted_sum_mont benchmarking with 3 input points -void benchmark_bls_g2_weighted_sum_mont_three_point() { - benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum_mont 3 points", 3, true); -} - -// bls_g2_weighted_sum_mont benchmarking with 5 input points -void benchmark_bls_g2_weighted_sum_mont_five_point() { - benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum_mont 5 points", 5, true); + benchmark_bls_g2_weighted_sum_impl("bls_g2_weighted_sum 5 points", 5); } // bls_pairing benchmarking utility -void benchmark_bls_pairing_impl(const std::string& test_name, uint32_t num_pairs, bool mont) { +void benchmark_bls_pairing_impl(const std::string& test_name, uint32_t num_pairs) { // prepare g1 operand std::vector g1_buf(96*num_pairs); //g1_buf.reserve(96*num_pairs); for (auto i=0u; i < num_pairs; ++i) { g1 p = random_g1(); - p.toAffineBytesLE(std::span((uint8_t*)g1_buf.data() + i * 96, 96), mont); + p.toAffineBytesLE(std::span((uint8_t*)g1_buf.data() + i * 96, 96), false); } eosio::chain::span g1_points(g1_buf.data(), g1_buf.size()); @@ -374,7 +296,7 @@ void benchmark_bls_pairing_impl(const std::string& test_name, uint32_t num_pairs std::vector g2_buf(192*num_pairs); for (auto i=0u; i < num_pairs; ++i) { g2 p2 = random_g2(); - p2.toAffineBytesLE(std::span((uint8_t*)g2_buf.data() + i * 192, (192)), mont); + p2.toAffineBytesLE(std::span((uint8_t*)g2_buf.data() + i * 192, (192)), false); } eosio::chain::span g2_points(g2_buf.data(), g2_buf.size()); @@ -384,46 +306,29 @@ void benchmark_bls_pairing_impl(const std::string& test_name, uint32_t num_pairs // set up bls_pairing to be benchmarked interface_in_benchmark interface; - std::function benchmarked_func {}; - if (mont) { - benchmarked_func = [&]() { - interface.interface->bls_pairing_mont(g1_points, g2_points, num_pairs, result); - }; - } else { - benchmarked_func = [&]() { - interface.interface->bls_pairing(g1_points, g2_points, num_pairs, result); - }; - } + auto benchmarked_func = [&]() { + interface.interface->bls_pairing(g1_points, g2_points, num_pairs, result); + }; benchmarking(test_name, benchmarked_func); } // bls_pairing benchmarking with 1 input pair void benchmark_bls_pairing_one_pair() { - benchmark_bls_pairing_impl("bls_pairing 1 pair", 1, false); + benchmark_bls_pairing_impl("bls_pairing 1 pair", 1); } // bls_pairing benchmarking with 3 input pairs void benchmark_bls_pairing_three_pair() { - benchmark_bls_pairing_impl("bls_pairing 3 pairs", 3, false); -} - -// bls_pairing_mont benchmarking with 1 input pair -void benchmark_bls_pairing_mont_one_pair() { - benchmark_bls_pairing_impl("bls_pairing_mont 1 pair", 1, true); -} - -// bls_pairing_mont benchmarking with 3 input pairs -void benchmark_bls_pairing_mont_three_pair() { - benchmark_bls_pairing_impl("bls_pairing_mont 3 pairs", 3, true); + benchmark_bls_pairing_impl("bls_pairing 3 pairs", 3); } // bls_g1_map benchmarking -void benchmark_bls_g1_map_impl(const std::string& test_name, bool mont) { +void benchmark_bls_g1_map() { // prepare e operand. Must be fp LE. std::vector e_buf(48); fp a = random_fe(); - a.toBytesLE(std::span((uint8_t*)e_buf.data(), 48), mont); + a.toBytesLE(std::span((uint8_t*)e_buf.data(), 48), false); eosio::chain::span e(e_buf.data(), e_buf.size()); // prepare result operand @@ -432,34 +337,19 @@ void benchmark_bls_g1_map_impl(const std::string& test_name, bool mont) { // set up bls_g1_map to be benchmarked interface_in_benchmark interface; - std::function benchmarked_func {}; - if (mont) { - benchmarked_func = [&]() { - interface.interface->bls_g1_map_mont(e, result); - }; - } else { - benchmarked_func = [&]() { - interface.interface->bls_g1_map(e, result); - }; - } - - benchmarking(test_name, benchmarked_func); -} - -void benchmark_bls_g1_map() { - benchmark_bls_g1_map_impl("bls_g1_map", false); -} + auto benchmarked_func = [&]() { + interface.interface->bls_g1_map(e, result); + }; -void benchmark_bls_g1_map_mont() { - benchmark_bls_g1_map_impl("bls_g1_map_mont", true); + benchmarking("bls_g1_map", benchmarked_func); } // bls_g2_map benchmarking -void benchmark_bls_g2_map_impl(const std::string& test_name, bool mont) { +void benchmark_bls_g2_map() { // prepare e operand. Must be fp2 LE. std::vector e_buf(96); fp2 a = random_fe2(); - a.toBytesLE(std::span((uint8_t*)e_buf.data(), 96), mont); + a.toBytesLE(std::span((uint8_t*)e_buf.data(), 96), false); eosio::chain::span e(e_buf.data(), e_buf.size()); // prepare result operand @@ -468,30 +358,15 @@ void benchmark_bls_g2_map_impl(const std::string& test_name, bool mont) { // set up bls_g2_map to be benchmarked interface_in_benchmark interface; - std::function benchmarked_func {}; - if (mont) { - benchmarked_func = [&]() { - interface.interface->bls_g2_map_mont(e, result); - }; - } else { - benchmarked_func = [&]() { - interface.interface->bls_g2_map(e, result); - }; - } - - benchmarking(test_name, benchmarked_func); -} - -void benchmark_bls_g2_map() { - benchmark_bls_g2_map_impl("bls_g2_map", false); -} + auto benchmarked_func = [&]() { + interface.interface->bls_g2_map(e, result); + }; -void benchmark_bls_g2_map_mont() { - benchmark_bls_g2_map_impl("bls_g2_map_mont", true); + benchmarking("bls_g2_map", benchmarked_func); } // bls_fp_mod benchmarking -void benchmark_bls_fp_mod_impl(const std::string& test_name, bool mont) { +void benchmark_bls_fp_mod() { // prepare scalar operand std::vector scalar_buf(64); // random_scalar returns 32 bytes. need to call it twice @@ -507,74 +382,44 @@ void benchmark_bls_fp_mod_impl(const std::string& test_name, bool mont) { // set up bls_fp_mod to be benchmarked interface_in_benchmark interface; - std::function benchmarked_func {}; - if (mont) { - benchmarked_func = [&]() { - interface.interface->bls_fp_mod_mont(scalar, result); - }; - } else { - benchmarked_func = [&]() { - interface.interface->bls_fp_mod(scalar, result); - }; - } - - benchmarking(test_name, benchmarked_func); -} - -void benchmark_bls_fp_mod() { - benchmark_bls_fp_mod_impl("bls_fp_mod", false); -} + auto benchmarked_func = [&]() { + interface.interface->bls_fp_mod(scalar, result); + }; -void benchmark_bls_fp_mod_mont() { - benchmark_bls_fp_mod_impl("bls_fp_mod_mont", true); + benchmarking("bls_fp_mod", benchmarked_func); } -void benchmark_bls_fp_mul_impl(const std::string& test_name, bool mont) { +void benchmark_bls_fp_mul() { // prepare op1 std::vector op1_buf(48); fp a = random_fe(); - a.toBytesLE(std::span((uint8_t*)op1_buf.data(), 48), mont); + a.toBytesLE(std::span((uint8_t*)op1_buf.data(), 48), false); eosio::chain::span op1(op1_buf.data(), op1_buf.size()); // prepare op2 std::vector op2_buf(48); fp b = random_fe(); - b.toBytesLE(std::span((uint8_t*)op2_buf.data(), 48), mont); + b.toBytesLE(std::span((uint8_t*)op2_buf.data(), 48), false); eosio::chain::span op2(op1_buf.data(), op2_buf.size()); // prepare result operand std::vector result_buf(48); eosio::chain::span result(result_buf.data(), result_buf.size()); - // set up bls_pairing to be benchmarked + // set up bls_fp_mul to be benchmarked interface_in_benchmark interface; - std::function benchmarked_func {}; - if (mont) { - benchmarked_func = [&]() { - interface.interface->bls_fp_mul_mont(op1, op2, result); - }; - } else { - benchmarked_func = [&]() { - interface.interface->bls_fp_mul(op1, op2, result); - }; - } - - benchmarking(test_name, benchmarked_func); -} - -void benchmark_bls_fp_mul() { - benchmark_bls_fp_mul_impl("bls_fp_mul", false); -} + auto benchmarked_func = [&]() { + interface.interface->bls_fp_mul(op1, op2, result); + }; -void benchmark_bls_fp_mul_mont() { - benchmark_bls_fp_mul_impl("bls_fp_mul_mont", true); + benchmarking("bls_fp_mul", benchmarked_func); } -void benchmark_bls_fp_exp_impl(const std::string& test_name, bool mont) { +void benchmark_bls_fp_exp() { // prepare base std::vector base_buf(48); fp a = random_fe(); - a.toBytesLE(std::span((uint8_t*)base_buf.data(), 48), mont); + a.toBytesLE(std::span((uint8_t*)base_buf.data(), 48), false); eosio::chain::span base(base_buf.data(), base_buf.size()); // prepare exp operand @@ -592,59 +437,29 @@ void benchmark_bls_fp_exp_impl(const std::string& test_name, bool mont) { // set up bls_fp_exp to be benchmarked interface_in_benchmark interface; - std::function benchmarked_func {}; - if (mont) { - benchmarked_func = [&]() { - interface.interface->bls_fp_exp_mont(base, exp, result); - }; - } else { - benchmarked_func = [&]() { - interface.interface->bls_fp_exp(base, exp, result); - }; - } - - benchmarking(test_name, benchmarked_func); -} - -void benchmark_bls_fp_exp() { - benchmark_bls_fp_exp_impl("bls_fp_exp", false); -} + auto benchmarked_func = [&]() { + interface.interface->bls_fp_exp(base, exp, result); + }; -void benchmark_bls_fp_exp_mont() { - benchmark_bls_fp_exp_impl("bls_fp_exp_mont", true); + benchmarking("bls_fp_exp", benchmarked_func); } // register benchmarking functions void bls_benchmarking() { benchmark_bls_g1_add(); - benchmark_bls_g1_add_mont(); benchmark_bls_g2_add(); - benchmark_bls_g2_add_mont(); benchmark_bls_pairing_one_pair(); - benchmark_bls_pairing_mont_one_pair(); benchmark_bls_pairing_three_pair(); - benchmark_bls_pairing_mont_three_pair(); benchmark_bls_g1_weighted_sum_one_point(); - benchmark_bls_g1_weighted_sum_mont_one_point(); benchmark_bls_g1_weighted_sum_three_point(); - benchmark_bls_g1_weighted_sum_mont_three_point(); benchmark_bls_g1_weighted_sum_five_point(); - benchmark_bls_g1_weighted_sum_mont_five_point(); benchmark_bls_g2_weighted_sum_one_point(); - benchmark_bls_g2_weighted_sum_mont_one_point(); benchmark_bls_g2_weighted_sum_three_point(); - benchmark_bls_g2_weighted_sum_mont_three_point(); benchmark_bls_g2_weighted_sum_five_point(); - benchmark_bls_g2_weighted_sum_mont_five_point(); benchmark_bls_g1_map(); - benchmark_bls_g1_map_mont(); benchmark_bls_g2_map(); - benchmark_bls_g2_map_mont(); benchmark_bls_fp_mod(); - benchmark_bls_fp_mod_mont(); benchmark_bls_fp_mul(); - benchmark_bls_fp_mul_mont(); benchmark_bls_fp_exp(); - benchmark_bls_fp_exp_mont(); } } // namespace benchmark From 6a9a8b1d24f2fa50e7b76f4eecce9e3088c59bfc Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Thu, 16 Nov 2023 10:38:13 -0500 Subject: [PATCH 6/6] use std::array instead of std::vector to simply conversion to eosio::chain::span --- benchmark/bls.cpp | 77 +++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 49 deletions(-) diff --git a/benchmark/bls.cpp b/benchmark/bls.cpp index 2b83069145..4c86e78ba1 100644 --- a/benchmark/bls.cpp +++ b/benchmark/bls.cpp @@ -151,13 +151,11 @@ bls12_381::g2 random_g2() void benchmark_bls_g1_add() { // prepare g1 operand in Jacobian LE format g1 p = random_g1(); - std::vector buf(96); - p.toAffineBytesLE(std::span((uint8_t*)buf.data(), 96), false); - eosio::chain::span op(buf.data(), buf.size()); + std::array op; + p.toAffineBytesLE(std::span((uint8_t*)op.data(), 96), false); // prepare result operand - std::vector result_buf(96); - eosio::chain::span result(result_buf.data(), result_buf.size()); + std::array result; // set up bls_g1_add to be benchmarked interface_in_benchmark interface; @@ -172,13 +170,11 @@ void benchmark_bls_g1_add() { void benchmark_bls_g2_add() { // prepare g2 operand in Jacobian LE format g2 p = random_g2(); - std::vector buf(192); - p.toAffineBytesLE(std::span((uint8_t*)buf.data(), 192), false); - eosio::chain::span op(buf.data(), buf.size()); + std::array op; + p.toAffineBytesLE(std::span((uint8_t*)op.data(), 192), false); // prepare result operand - std::vector result_buf(192); - eosio::chain::span result(result_buf.data(), result_buf.size()); + std::array result; // set up bls_g2_add to be benchmarked interface_in_benchmark interface; @@ -208,8 +204,7 @@ void benchmark_bls_g1_weighted_sum_impl(const std::string& test_name, uint32_t n chain::span scalars(scalars_buf.data(), scalars_buf.size()); // prepare result operand - std::vector result_buf(96); - eosio::chain::span result(result_buf.data(), result_buf.size()); + std::array result; // set up bls_g1_weighted_sum to be benchmarked interface_in_benchmark interface; @@ -254,8 +249,7 @@ void benchmark_bls_g2_weighted_sum_impl(const std::string& test_name, uint32_t n eosio::chain::span scalars(scalars_buf.data(), scalars_buf.size()); // prepare result operand - std::vector result_buf(192); - eosio::chain::span result(result_buf.data(), result_buf.size()); + std::array result; // set up bls_g2_weighted_sum to be benchmarked interface_in_benchmark interface; @@ -285,7 +279,6 @@ void benchmark_bls_g2_weighted_sum_five_point() { void benchmark_bls_pairing_impl(const std::string& test_name, uint32_t num_pairs) { // prepare g1 operand std::vector g1_buf(96*num_pairs); - //g1_buf.reserve(96*num_pairs); for (auto i=0u; i < num_pairs; ++i) { g1 p = random_g1(); p.toAffineBytesLE(std::span((uint8_t*)g1_buf.data() + i * 96, 96), false); @@ -301,8 +294,7 @@ void benchmark_bls_pairing_impl(const std::string& test_name, uint32_t num_pairs eosio::chain::span g2_points(g2_buf.data(), g2_buf.size()); // prepare result operand - std::vector result_buf(576); - eosio::chain::span result(result_buf.data(), result_buf.size()); + std::array result; // set up bls_pairing to be benchmarked interface_in_benchmark interface; @@ -326,14 +318,12 @@ void benchmark_bls_pairing_three_pair() { // bls_g1_map benchmarking void benchmark_bls_g1_map() { // prepare e operand. Must be fp LE. - std::vector e_buf(48); + std::array e; fp a = random_fe(); - a.toBytesLE(std::span((uint8_t*)e_buf.data(), 48), false); - eosio::chain::span e(e_buf.data(), e_buf.size()); + a.toBytesLE(std::span((uint8_t*)e.data(), 48), false); // prepare result operand - std::vector result_buf(96); - eosio::chain::span result(result_buf.data(), result_buf.size()); + std::array result; // set up bls_g1_map to be benchmarked interface_in_benchmark interface; @@ -346,15 +336,12 @@ void benchmark_bls_g1_map() { // bls_g2_map benchmarking void benchmark_bls_g2_map() { - // prepare e operand. Must be fp2 LE. - std::vector e_buf(96); + std::array e; fp2 a = random_fe2(); - a.toBytesLE(std::span((uint8_t*)e_buf.data(), 96), false); - eosio::chain::span e(e_buf.data(), e_buf.size()); + a.toBytesLE(std::span((uint8_t*)e.data(), 96), false); // prepare result operand - std::vector result_buf(192); - eosio::chain::span result(result_buf.data(), result_buf.size()); + std::array result; // set up bls_g2_map to be benchmarked interface_in_benchmark interface; @@ -368,17 +355,15 @@ void benchmark_bls_g2_map() { // bls_fp_mod benchmarking void benchmark_bls_fp_mod() { // prepare scalar operand - std::vector scalar_buf(64); + std::array scalar; // random_scalar returns 32 bytes. need to call it twice for (auto i=0u; i < 2; ++i) { std::array s = random_scalar(); - scalar::toBytesLE(s, std::span((uint8_t*)scalar_buf.data() + i*32, 32)); + scalar::toBytesLE(s, std::span((uint8_t*)scalar.data() + i*32, 32)); } - chain::span scalar(scalar_buf.data(), scalar_buf.size()); // prepare result operand - std::vector result_buf(48); - eosio::chain::span result(result_buf.data(), result_buf.size()); + std::array result; // set up bls_fp_mod to be benchmarked interface_in_benchmark interface; @@ -391,20 +376,17 @@ void benchmark_bls_fp_mod() { void benchmark_bls_fp_mul() { // prepare op1 - std::vector op1_buf(48); + std::array op1; fp a = random_fe(); - a.toBytesLE(std::span((uint8_t*)op1_buf.data(), 48), false); - eosio::chain::span op1(op1_buf.data(), op1_buf.size()); + a.toBytesLE(std::span((uint8_t*)op1.data(), 48), false); // prepare op2 - std::vector op2_buf(48); + std::array op2; fp b = random_fe(); - b.toBytesLE(std::span((uint8_t*)op2_buf.data(), 48), false); - eosio::chain::span op2(op1_buf.data(), op2_buf.size()); + b.toBytesLE(std::span((uint8_t*)op2.data(), 48), false); // prepare result operand - std::vector result_buf(48); - eosio::chain::span result(result_buf.data(), result_buf.size()); + std::array result; // set up bls_fp_mul to be benchmarked interface_in_benchmark interface; @@ -417,23 +399,20 @@ void benchmark_bls_fp_mul() { void benchmark_bls_fp_exp() { // prepare base - std::vector base_buf(48); + std::array base; fp a = random_fe(); - a.toBytesLE(std::span((uint8_t*)base_buf.data(), 48), false); - eosio::chain::span base(base_buf.data(), base_buf.size()); + a.toBytesLE(std::span((uint8_t*)base.data(), 48), false); // prepare exp operand - std::vector exp_buf(64); + std::array exp; // random_scalar returns 32 bytes. need to call it twice for (auto i=0u; i < 2; ++i) { std::array s = random_scalar(); - scalar::toBytesLE(s, std::span((uint8_t*)exp_buf.data() + i*32, 32)); + scalar::toBytesLE(s, std::span((uint8_t*)exp.data() + i*32, 32)); } - eosio::chain::span exp(exp_buf.data(), exp_buf.size()); // prepare result operand - std::vector result_buf(48); - eosio::chain::span result(result_buf.data(), result_buf.size()); + std::array result; // set up bls_fp_exp to be benchmarked interface_in_benchmark interface;