aboutsummaryrefslogtreecommitdiff
path: root/tests/performance_tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/performance_tests')
-rw-r--r--tests/performance_tests/CMakeLists.txt5
-rw-r--r--tests/performance_tests/bulletproof.h100
-rw-r--r--tests/performance_tests/check_tx_signature.h84
-rw-r--r--tests/performance_tests/construct_tx.h4
-rw-r--r--tests/performance_tests/crypto_ops.h122
-rw-r--r--tests/performance_tests/main.cpp532
-rw-r--r--tests/performance_tests/multiexp.h94
-rw-r--r--tests/performance_tests/performance_tests.h126
-rw-r--r--tests/performance_tests/range_proof.h63
-rw-r--r--tests/performance_tests/signature.h68
10 files changed, 1103 insertions, 95 deletions
diff --git a/tests/performance_tests/CMakeLists.txt b/tests/performance_tests/CMakeLists.txt
index 8cbd71444..837d39bd3 100644
--- a/tests/performance_tests/CMakeLists.txt
+++ b/tests/performance_tests/CMakeLists.txt
@@ -40,8 +40,13 @@ set(performance_tests_headers
generate_key_image.h
generate_key_image_helper.h
generate_keypair.h
+ signature.h
is_out_to_acc.h
subaddress_expand.h
+ range_proof.h
+ bulletproof.h
+ crypto_ops.h
+ multiexp.h
multi_tx_test_base.h
performance_tests.h
performance_utils.h
diff --git a/tests/performance_tests/bulletproof.h b/tests/performance_tests/bulletproof.h
new file mode 100644
index 000000000..7bb702c3d
--- /dev/null
+++ b/tests/performance_tests/bulletproof.h
@@ -0,0 +1,100 @@
+// Copyright (c) 2014-2017, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#pragma once
+
+#include "ringct/rctSigs.h"
+#include "ringct/bulletproofs.h"
+
+template<bool a_verify, size_t n_amounts>
+class test_bulletproof
+{
+public:
+ static const size_t approx_loop_count = 100 / n_amounts;
+ static const size_t loop_count = (approx_loop_count >= 10 ? approx_loop_count : 10) / (a_verify ? 1 : 5);
+ static const bool verify = a_verify;
+
+ bool init()
+ {
+ proof = rct::bulletproof_PROVE(std::vector<uint64_t>(n_amounts, 749327532984), rct::skvGen(n_amounts));
+ return true;
+ }
+
+ bool test()
+ {
+ bool ret = true;
+ if (verify)
+ ret = rct::bulletproof_VERIFY(proof);
+ else
+ rct::bulletproof_PROVE(std::vector<uint64_t>(n_amounts, 749327532984), rct::skvGen(n_amounts));
+ return ret;
+ }
+
+private:
+ rct::Bulletproof proof;
+};
+
+template<bool batch, size_t start, size_t repeat, size_t mul, size_t add, size_t N>
+class test_aggregated_bulletproof
+{
+public:
+ static const size_t loop_count = 500 / (N * repeat);
+
+ bool init()
+ {
+ size_t o = start;
+ for (size_t n = 0; n < N; ++n)
+ {
+ //printf("adding %zu times %zu\n", repeat, o);
+ for (size_t i = 0; i < repeat; ++i)
+ proofs.push_back(rct::bulletproof_PROVE(std::vector<uint64_t>(o, 749327532984), rct::skvGen(o)));
+ o = o * mul + add;
+ }
+ return true;
+ }
+
+ bool test()
+ {
+ if (batch)
+ {
+ return rct::bulletproof_VERIFY(proofs);
+ }
+ else
+ {
+ for (const rct::Bulletproof &proof: proofs)
+ if (!rct::bulletproof_VERIFY(proof))
+ return false;
+ return true;
+ }
+ }
+
+private:
+ std::vector<rct::Bulletproof> proofs;
+};
diff --git a/tests/performance_tests/check_tx_signature.h b/tests/performance_tests/check_tx_signature.h
index ec570e69d..ee382d9ad 100644
--- a/tests/performance_tests/check_tx_signature.h
+++ b/tests/performance_tests/check_tx_signature.h
@@ -40,14 +40,15 @@
#include "multi_tx_test_base.h"
-template<size_t a_ring_size, bool a_rct>
+template<size_t a_ring_size, size_t a_outputs, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean>
class test_check_tx_signature : private multi_tx_test_base<a_ring_size>
{
static_assert(0 < a_ring_size, "ring_size must be greater than 0");
public:
- static const size_t loop_count = a_rct ? 10 : a_ring_size < 100 ? 100 : 10;
+ static const size_t loop_count = a_rct ? (a_ring_size <= 2 ? 50 : 10) : a_ring_size < 100 ? 100 : 10;
static const size_t ring_size = a_ring_size;
+ static const size_t outputs = a_outputs;
static const bool rct = a_rct;
typedef multi_tx_test_base<a_ring_size> base_class;
@@ -62,13 +63,15 @@ public:
m_alice.generate();
std::vector<tx_destination_entry> destinations;
- destinations.push_back(tx_destination_entry(this->m_source_amount, m_alice.get_keys().m_account_address, false));
+ destinations.push_back(tx_destination_entry(this->m_source_amount - outputs + 1, m_alice.get_keys().m_account_address, false));
+ for (size_t n = 1; n < outputs; ++n)
+ destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false));
crypto::secret_key tx_key;
std::vector<crypto::secret_key> additional_tx_keys;
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0};
- if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct))
+ if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, range_proof_type))
return false;
get_transaction_prefix_hash(m_tx, m_tx_prefix_hash);
@@ -80,7 +83,7 @@ public:
{
if (rct)
{
- if (m_tx.rct_signatures.type == rct::RCTTypeFull || m_tx.rct_signatures.type == rct::RCTTypeFullBulletproof)
+ if (m_tx.rct_signatures.type == rct::RCTTypeFull)
return rct::verRct(m_tx.rct_signatures);
else
return rct::verRctSimple(m_tx.rct_signatures);
@@ -97,3 +100,74 @@ private:
cryptonote::transaction m_tx;
crypto::hash m_tx_prefix_hash;
};
+
+template<size_t a_ring_size, size_t a_outputs, size_t a_num_txes, size_t extra_outs = 0>
+class test_check_tx_signature_aggregated_bulletproofs : private multi_tx_test_base<a_ring_size>
+{
+ static_assert(0 < a_ring_size, "ring_size must be greater than 0");
+
+public:
+ static const size_t loop_count = a_ring_size <= 2 ? 50 : 10;
+ static const size_t ring_size = a_ring_size;
+ static const size_t outputs = a_outputs;
+
+ typedef multi_tx_test_base<a_ring_size> base_class;
+
+ bool init()
+ {
+ using namespace cryptonote;
+
+ if (!base_class::init())
+ return false;
+
+ m_alice.generate();
+
+ std::vector<tx_destination_entry> destinations;
+ destinations.push_back(tx_destination_entry(this->m_source_amount - outputs + 1, m_alice.get_keys().m_account_address, false));
+ for (size_t n = 1; n < outputs; ++n)
+ destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false));
+
+ crypto::secret_key tx_key;
+ std::vector<crypto::secret_key> additional_tx_keys;
+ std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
+ subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0};
+
+ m_txes.resize(a_num_txes + (extra_outs > 0 ? 1 : 0));
+ for (size_t n = 0; n < a_num_txes; ++n)
+ {
+ if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes[n], 0, tx_key, additional_tx_keys, true, rct::RangeProofPaddedBulletproof))
+ return false;
+ }
+
+ if (extra_outs)
+ {
+ destinations.clear();
+ destinations.push_back(tx_destination_entry(this->m_source_amount - extra_outs + 1, m_alice.get_keys().m_account_address, false));
+ for (size_t n = 1; n < extra_outs; ++n)
+ destinations.push_back(tx_destination_entry(1, m_alice.get_keys().m_account_address, false));
+
+ if (!construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_txes.back(), 0, tx_key, additional_tx_keys, true, rct::RangeProofMultiOutputBulletproof))
+ return false;
+ }
+
+ return true;
+ }
+
+ bool test()
+ {
+ std::vector<const rct::rctSig*> rvv;
+ rvv.reserve(m_txes.size());
+ for (size_t n = 0; n < m_txes.size(); ++n)
+ {
+ const rct::rctSig &rv = m_txes[n].rct_signatures;
+ if (!rct::verRctNonSemanticsSimple(rv))
+ return false;
+ rvv.push_back(&rv);
+ }
+ return rct::verRctSemanticsSimple(rvv);
+ }
+
+private:
+ cryptonote::account_base m_alice;
+ std::vector<cryptonote::transaction> m_txes;
+};
diff --git a/tests/performance_tests/construct_tx.h b/tests/performance_tests/construct_tx.h
index 99c7f1b18..378065ddd 100644
--- a/tests/performance_tests/construct_tx.h
+++ b/tests/performance_tests/construct_tx.h
@@ -36,7 +36,7 @@
#include "multi_tx_test_base.h"
-template<size_t a_in_count, size_t a_out_count, bool a_rct>
+template<size_t a_in_count, size_t a_out_count, bool a_rct, rct::RangeProofType range_proof_type = rct::RangeProofBorromean>
class test_construct_tx : private multi_tx_test_base<a_in_count>
{
static_assert(0 < a_in_count, "in_count must be greater than 0");
@@ -73,7 +73,7 @@ public:
std::vector<crypto::secret_key> additional_tx_keys;
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
subaddresses[this->m_miners[this->real_source_idx].get_keys().m_account_address.m_spend_public_key] = {0,0};
- return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct);
+ return cryptonote::construct_tx_and_get_tx_key(this->m_miners[this->real_source_idx].get_keys(), subaddresses, this->m_sources, m_destinations, cryptonote::account_public_address{}, std::vector<uint8_t>(), m_tx, 0, tx_key, additional_tx_keys, rct, range_proof_type);
}
private:
diff --git a/tests/performance_tests/crypto_ops.h b/tests/performance_tests/crypto_ops.h
new file mode 100644
index 000000000..3c68583c5
--- /dev/null
+++ b/tests/performance_tests/crypto_ops.h
@@ -0,0 +1,122 @@
+// Copyright (c) 2014-2017, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#pragma once
+
+#include "crypto/crypto.h"
+#include "ringct/rctOps.h"
+
+enum test_op
+{
+ op_sc_add,
+ op_sc_sub,
+ op_sc_mul,
+ op_ge_add_raw,
+ op_ge_add_p3_p3,
+ ops_fast,
+
+ op_addKeys,
+ op_scalarmultBase,
+ op_scalarmultKey,
+ op_scalarmultH,
+ op_scalarmult8,
+ op_ge_double_scalarmult_base_vartime,
+ op_ge_double_scalarmult_precomp_vartime,
+ op_ge_double_scalarmult_precomp_vartime2,
+ op_addKeys2,
+ op_addKeys3,
+ op_addKeys3_2,
+ op_isInMainSubgroup,
+};
+
+template<test_op op>
+class test_crypto_ops
+{
+public:
+ static const size_t loop_count = op < ops_fast ? 10000000 : 1000;
+
+ bool init()
+ {
+ scalar0 = rct::skGen();
+ scalar1 = rct::skGen();
+ point0 = rct::scalarmultBase(rct::skGen());
+ point1 = rct::scalarmultBase(rct::skGen());
+ if (ge_frombytes_vartime(&p3_0, point0.bytes) != 0)
+ return false;
+ if (ge_frombytes_vartime(&p3_1, point1.bytes) != 0)
+ return false;
+ ge_p3_to_cached(&cached, &p3_0);
+ rct::precomp(precomp0, point0);
+ rct::precomp(precomp1, point1);
+ return true;
+ }
+
+ bool test()
+ {
+ rct::key key;
+ ge_cached tmp_cached;
+ ge_p1p1 tmp_p1p1;
+ ge_p2 tmp_p2;
+ switch (op)
+ {
+ case op_sc_add: sc_add(key.bytes, scalar0.bytes, scalar1.bytes); break;
+ case op_sc_sub: sc_sub(key.bytes, scalar0.bytes, scalar1.bytes); break;
+ case op_sc_mul: sc_mul(key.bytes, scalar0.bytes, scalar1.bytes); break;
+ case op_ge_add_p3_p3: {
+ ge_p3_to_cached(&tmp_cached, &p3_0);
+ ge_add(&tmp_p1p1, &p3_1, &tmp_cached);
+ ge_p1p1_to_p3(&p3_1, &tmp_p1p1);
+ break;
+ }
+ case op_ge_add_raw: ge_add(&tmp_p1p1, &p3_1, &cached); break;
+ case op_addKeys: rct::addKeys(key, point0, point1); break;
+ case op_scalarmultBase: rct::scalarmultBase(scalar0); break;
+ case op_scalarmultKey: rct::scalarmultKey(point0, scalar0); break;
+ case op_scalarmultH: rct::scalarmultH(scalar0); break;
+ case op_scalarmult8: rct::scalarmult8(point0); break;
+ case op_ge_double_scalarmult_base_vartime: ge_double_scalarmult_base_vartime(&tmp_p2, scalar0.bytes, &p3_0, scalar1.bytes); break;
+ case op_ge_double_scalarmult_precomp_vartime: ge_double_scalarmult_precomp_vartime(&tmp_p2, scalar0.bytes, &p3_0, scalar1.bytes, precomp0); break;
+ case op_ge_double_scalarmult_precomp_vartime2: ge_double_scalarmult_precomp_vartime2(&tmp_p2, scalar0.bytes, precomp0, scalar1.bytes, precomp1); break;
+ case op_addKeys2: rct::addKeys2(key, scalar0, scalar1, point0); break;
+ case op_addKeys3: rct::addKeys3(key, scalar0, point0, scalar1, precomp1); break;
+ case op_addKeys3_2: rct::addKeys3(key, scalar0, precomp0, scalar1, precomp1); break;
+ case op_isInMainSubgroup: rct::isInMainSubgroup(point0); break;
+ default: return false;
+ }
+ return true;
+ }
+
+private:
+ rct::key scalar0, scalar1;
+ rct::key point0, point1;
+ ge_p3 p3_0, p3_1;
+ ge_cached cached;
+ ge_dsmp precomp0, precomp1;
+};
diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp
index 1733e3409..7c5135c65 100644
--- a/tests/performance_tests/main.cpp
+++ b/tests/performance_tests/main.cpp
@@ -46,12 +46,18 @@
#include "generate_key_image.h"
#include "generate_key_image_helper.h"
#include "generate_keypair.h"
+#include "signature.h"
#include "is_out_to_acc.h"
#include "subaddress_expand.h"
#include "sc_reduce32.h"
#include "cn_fast_hash.h"
#include "rct_mlsag.h"
#include "equality.h"
+#include "range_proof.h"
+#include "rct_mlsag.h"
+#include "bulletproof.h"
+#include "crypto_ops.h"
+#include "multiexp.h"
namespace po = boost::program_options;
@@ -63,11 +69,16 @@ int main(int argc, char** argv)
set_thread_high_priority();
mlog_configure(mlog_get_default_log_path("performance_tests.log"), true);
- mlog_set_log_level(0);
po::options_description desc_options("Command line options");
const command_line::arg_descriptor<std::string> arg_filter = { "filter", "Regular expression filter for which tests to run" };
- command_line::add_arg(desc_options, arg_filter);
+ const command_line::arg_descriptor<bool> arg_verbose = { "verbose", "Verbose output", false };
+ const command_line::arg_descriptor<bool> arg_stats = { "stats", "Including statistics (min/median)", false };
+ const command_line::arg_descriptor<unsigned> arg_loop_multiplier = { "loop-multiplier", "Run for that many times more loops", 1 };
+ command_line::add_arg(desc_options, arg_filter, "");
+ command_line::add_arg(desc_options, arg_verbose, "");
+ command_line::add_arg(desc_options, arg_stats, "");
+ command_line::add_arg(desc_options, arg_loop_multiplier, "");
po::variables_map vm;
bool r = command_line::handle_error_helper(desc_options, [&]()
@@ -80,82 +91,455 @@ int main(int argc, char** argv)
return 1;
const std::string filter = tools::glob_to_regex(command_line::get_arg(vm, arg_filter));
+ Params p;
+ p.verbose = command_line::get_arg(vm, arg_verbose);
+ p.stats = command_line::get_arg(vm, arg_stats);
+ p.loop_multiplier = command_line::get_arg(vm, arg_loop_multiplier);
performance_timer timer;
timer.start();
- TEST_PERFORMANCE3(filter, test_construct_tx, 1, 1, false);
- TEST_PERFORMANCE3(filter, test_construct_tx, 1, 2, false);
- TEST_PERFORMANCE3(filter, test_construct_tx, 1, 10, false);
- TEST_PERFORMANCE3(filter, test_construct_tx, 1, 100, false);
- TEST_PERFORMANCE3(filter, test_construct_tx, 1, 1000, false);
-
- TEST_PERFORMANCE3(filter, test_construct_tx, 2, 1, false);
- TEST_PERFORMANCE3(filter, test_construct_tx, 2, 2, false);
- TEST_PERFORMANCE3(filter, test_construct_tx, 2, 10, false);
- TEST_PERFORMANCE3(filter, test_construct_tx, 2, 100, false);
-
- TEST_PERFORMANCE3(filter, test_construct_tx, 10, 1, false);
- TEST_PERFORMANCE3(filter, test_construct_tx, 10, 2, false);
- TEST_PERFORMANCE3(filter, test_construct_tx, 10, 10, false);
- TEST_PERFORMANCE3(filter, test_construct_tx, 10, 100, false);
-
- TEST_PERFORMANCE3(filter, test_construct_tx, 100, 1, false);
- TEST_PERFORMANCE3(filter, test_construct_tx, 100, 2, false);
- TEST_PERFORMANCE3(filter, test_construct_tx, 100, 10, false);
- TEST_PERFORMANCE3(filter, test_construct_tx, 100, 100, false);
-
- TEST_PERFORMANCE3(filter, test_construct_tx, 2, 1, true);
- TEST_PERFORMANCE3(filter, test_construct_tx, 2, 2, true);
- TEST_PERFORMANCE3(filter, test_construct_tx, 2, 10, true);
-
- TEST_PERFORMANCE3(filter, test_construct_tx, 10, 1, true);
- TEST_PERFORMANCE3(filter, test_construct_tx, 10, 2, true);
- TEST_PERFORMANCE3(filter, test_construct_tx, 10, 10, true);
-
- TEST_PERFORMANCE3(filter, test_construct_tx, 100, 1, true);
- TEST_PERFORMANCE3(filter, test_construct_tx, 100, 2, true);
- TEST_PERFORMANCE3(filter, test_construct_tx, 100, 10, true);
-
- TEST_PERFORMANCE2(filter, test_check_tx_signature, 1, false);
- TEST_PERFORMANCE2(filter, test_check_tx_signature, 2, false);
- TEST_PERFORMANCE2(filter, test_check_tx_signature, 10, false);
- TEST_PERFORMANCE2(filter, test_check_tx_signature, 100, false);
-
- TEST_PERFORMANCE2(filter, test_check_tx_signature, 2, true);
- TEST_PERFORMANCE2(filter, test_check_tx_signature, 10, true);
- TEST_PERFORMANCE2(filter, test_check_tx_signature, 100, true);
-
- TEST_PERFORMANCE0(filter, test_is_out_to_acc);
- TEST_PERFORMANCE0(filter, test_is_out_to_acc_precomp);
- TEST_PERFORMANCE0(filter, test_generate_key_image_helper);
- TEST_PERFORMANCE0(filter, test_generate_key_derivation);
- TEST_PERFORMANCE0(filter, test_generate_key_image);
- TEST_PERFORMANCE0(filter, test_derive_public_key);
- TEST_PERFORMANCE0(filter, test_derive_secret_key);
- TEST_PERFORMANCE0(filter, test_ge_frombytes_vartime);
- TEST_PERFORMANCE0(filter, test_generate_keypair);
- TEST_PERFORMANCE0(filter, test_sc_reduce32);
-
- TEST_PERFORMANCE2(filter, test_wallet2_expand_subaddresses, 50, 200);
-
- TEST_PERFORMANCE0(filter, test_cn_slow_hash);
- TEST_PERFORMANCE1(filter, test_cn_fast_hash, 32);
- TEST_PERFORMANCE1(filter, test_cn_fast_hash, 16384);
-
- TEST_PERFORMANCE3(filter, test_ringct_mlsag, 1, 3, false);
- TEST_PERFORMANCE3(filter, test_ringct_mlsag, 1, 5, false);
- TEST_PERFORMANCE3(filter, test_ringct_mlsag, 1, 10, false);
- TEST_PERFORMANCE3(filter, test_ringct_mlsag, 1, 100, false);
- TEST_PERFORMANCE3(filter, test_ringct_mlsag, 1, 3, true);
- TEST_PERFORMANCE3(filter, test_ringct_mlsag, 1, 5, true);
- TEST_PERFORMANCE3(filter, test_ringct_mlsag, 1, 10, true);
- TEST_PERFORMANCE3(filter, test_ringct_mlsag, 1, 100, true);
-
- TEST_PERFORMANCE2(filter, test_equality, memcmp32, true);
- TEST_PERFORMANCE2(filter, test_equality, memcmp32, false);
- TEST_PERFORMANCE2(filter, test_equality, verify32, false);
- TEST_PERFORMANCE2(filter, test_equality, verify32, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 1, 1, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 1, 2, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 1, 10, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 1, 100, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 1, 1000, false);
+
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 2, 1, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 2, 2, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 2, 10, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 2, 100, false);
+
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 10, 1, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 10, 2, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 10, 10, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 10, 100, false);
+
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 1, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 2, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 10, false);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 100, false);
+
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 2, 1, true);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 2, 2, true);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 2, 10, true);
+
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 10, 1, true);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 10, 2, true);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 10, 10, true);
+
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 1, true);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 2, true);
+ TEST_PERFORMANCE3(filter, p, test_construct_tx, 100, 10, true);
+
+ TEST_PERFORMANCE4(filter, p, test_construct_tx, 2, 1, true, rct::RangeProofPaddedBulletproof);
+ TEST_PERFORMANCE4(filter, p, test_construct_tx, 2, 2, true, rct::RangeProofPaddedBulletproof);
+ TEST_PERFORMANCE4(filter, p, test_construct_tx, 2, 10, true, rct::RangeProofPaddedBulletproof);
+
+ TEST_PERFORMANCE4(filter, p, test_construct_tx, 10, 1, true, rct::RangeProofPaddedBulletproof);
+ TEST_PERFORMANCE4(filter, p, test_construct_tx, 10, 2, true, rct::RangeProofPaddedBulletproof);
+ TEST_PERFORMANCE4(filter, p, test_construct_tx, 10, 10, true, rct::RangeProofPaddedBulletproof);
+
+ TEST_PERFORMANCE4(filter, p, test_construct_tx, 100, 1, true, rct::RangeProofPaddedBulletproof);
+ TEST_PERFORMANCE4(filter, p, test_construct_tx, 100, 2, true, rct::RangeProofPaddedBulletproof);
+ TEST_PERFORMANCE4(filter, p, test_construct_tx, 100, 10, true, rct::RangeProofPaddedBulletproof);
+
+ TEST_PERFORMANCE3(filter, p, test_check_tx_signature, 1, 2, false);
+ TEST_PERFORMANCE3(filter, p, test_check_tx_signature, 2, 2, false);
+ TEST_PERFORMANCE3(filter, p, test_check_tx_signature, 10, 2, false);
+ TEST_PERFORMANCE3(filter, p, test_check_tx_signature, 100, 2, false);
+ TEST_PERFORMANCE3(filter, p, test_check_tx_signature, 2, 10, false);
+
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofBorromean);
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofBorromean);
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofBorromean);
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofBorromean);
+
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofPaddedBulletproof);
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 2, true, rct::RangeProofMultiOutputBulletproof);
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofPaddedBulletproof);
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 10, 2, true, rct::RangeProofMultiOutputBulletproof);
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofPaddedBulletproof);
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 100, 2, true, rct::RangeProofMultiOutputBulletproof);
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofPaddedBulletproof);
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature, 2, 10, true, rct::RangeProofMultiOutputBulletproof);
+
+ TEST_PERFORMANCE3(filter, p, test_check_tx_signature_aggregated_bulletproofs, 2, 2, 64);
+ TEST_PERFORMANCE3(filter, p, test_check_tx_signature_aggregated_bulletproofs, 10, 2, 64);
+ TEST_PERFORMANCE3(filter, p, test_check_tx_signature_aggregated_bulletproofs, 100, 2, 64);
+ TEST_PERFORMANCE3(filter, p, test_check_tx_signature_aggregated_bulletproofs, 2, 10, 64);
+
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature_aggregated_bulletproofs, 2, 2, 62, 4);
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature_aggregated_bulletproofs, 10, 2, 62, 4);
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature_aggregated_bulletproofs, 2, 2, 56, 16);
+ TEST_PERFORMANCE4(filter, p, test_check_tx_signature_aggregated_bulletproofs, 10, 2, 56, 16);
+
+ TEST_PERFORMANCE0(filter, p, test_is_out_to_acc);
+ TEST_PERFORMANCE0(filter, p, test_is_out_to_acc_precomp);
+ TEST_PERFORMANCE0(filter, p, test_generate_key_image_helper);
+ TEST_PERFORMANCE0(filter, p, test_generate_key_derivation);
+ TEST_PERFORMANCE0(filter, p, test_generate_key_image);
+ TEST_PERFORMANCE0(filter, p, test_derive_public_key);
+ TEST_PERFORMANCE0(filter, p, test_derive_secret_key);
+ TEST_PERFORMANCE0(filter, p, test_ge_frombytes_vartime);
+ TEST_PERFORMANCE0(filter, p, test_generate_keypair);
+ TEST_PERFORMANCE0(filter, p, test_sc_reduce32);
+ TEST_PERFORMANCE1(filter, p, test_signature, false);
+ TEST_PERFORMANCE1(filter, p, test_signature, true);
+
+ TEST_PERFORMANCE2(filter, p, test_wallet2_expand_subaddresses, 50, 200);
+
+ TEST_PERFORMANCE0(filter, p, test_cn_slow_hash);
+ TEST_PERFORMANCE1(filter, p, test_cn_fast_hash, 32);
+ TEST_PERFORMANCE1(filter, p, test_cn_fast_hash, 16384);
+
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 3, false);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 5, false);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 10, false);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 100, false);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 3, true);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 5, true);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 10, true);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 100, true);
+
+ TEST_PERFORMANCE2(filter, p, test_equality, memcmp32, true);
+ TEST_PERFORMANCE2(filter, p, test_equality, memcmp32, false);
+ TEST_PERFORMANCE2(filter, p, test_equality, verify32, false);
+ TEST_PERFORMANCE2(filter, p, test_equality, verify32, false);
+
+ TEST_PERFORMANCE1(filter, p, test_range_proof, true);
+ TEST_PERFORMANCE1(filter, p, test_range_proof, false);
+
+ TEST_PERFORMANCE2(filter, p, test_bulletproof, true, 1); // 1 bulletproof with 1 amount
+ TEST_PERFORMANCE2(filter, p, test_bulletproof, false, 1);
+
+ TEST_PERFORMANCE2(filter, p, test_bulletproof, true, 2); // 1 bulletproof with 2 amounts
+ TEST_PERFORMANCE2(filter, p, test_bulletproof, false, 2);
+
+ TEST_PERFORMANCE2(filter, p, test_bulletproof, true, 15); // 1 bulletproof with 15 amounts
+ TEST_PERFORMANCE2(filter, p, test_bulletproof, false, 15);
+
+ TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, false, 2, 1, 1, 0, 4);
+ TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, true, 2, 1, 1, 0, 4); // 4 proofs, each with 2 amounts
+ TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, false, 8, 1, 1, 0, 4);
+ TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, true, 8, 1, 1, 0, 4); // 4 proofs, each with 8 amounts
+ TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, false, 1, 1, 2, 0, 4);
+ TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, true, 1, 1, 2, 0, 4); // 4 proofs with 1, 2, 4, 8 amounts
+ TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, false, 1, 8, 1, 1, 4);
+ TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, true, 1, 8, 1, 1, 4); // 32 proofs, with 1, 2, 3, 4 amounts, 8 of each
+ TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, false, 2, 1, 1, 0, 64);
+ TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, true, 2, 1, 1, 0, 64); // 64 proof, each with 2 amounts
+
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 3, false);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 5, false);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 10, false);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 100, false);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 3, true);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 5, true);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 10, true);
+ TEST_PERFORMANCE3(filter, p, test_ringct_mlsag, 1, 100, true);
+
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_sc_add);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_sc_sub);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_sc_mul);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_ge_add_raw);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_ge_add_p3_p3);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_addKeys);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_scalarmultBase);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_scalarmultKey);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_scalarmultH);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_scalarmult8);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_ge_double_scalarmult_base_vartime);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_ge_double_scalarmult_precomp_vartime);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_ge_double_scalarmult_precomp_vartime2);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_addKeys2);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_addKeys3);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_addKeys3_2);
+ TEST_PERFORMANCE1(filter, p, test_crypto_ops, op_isInMainSubgroup);
+
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_bos_coster, 2);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_bos_coster, 4);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_bos_coster, 8);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_bos_coster, 16);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_bos_coster, 32);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_bos_coster, 64);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_bos_coster, 128);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_bos_coster, 256);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_bos_coster, 512);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_bos_coster, 1024);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_bos_coster, 2048);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_bos_coster, 4096);
+
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus, 2);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus, 4);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus, 8);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus, 16);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus, 32);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus, 64);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus, 128);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus, 256);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus, 512);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus, 1024);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus, 2048);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus, 4096);
+
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus_cached, 2);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus_cached, 4);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus_cached, 8);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus_cached, 16);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus_cached, 32);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus_cached, 64);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus_cached, 128);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus_cached, 256);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus_cached, 512);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus_cached, 1024);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus_cached, 2048);
+ TEST_PERFORMANCE2(filter, p, test_multiexp, multiexp_straus_cached, 4096);
+
+#if 1
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 8, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 16, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 32, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 64, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 128, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 256, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 512, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 1024, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2048, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4096, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 8, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 16, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 32, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 64, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 128, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 256, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 512, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 1024, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2048, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4096, 9);
+#else
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 8, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 8, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 8, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 8, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 8, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 8, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 8, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 8, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 8, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 16, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 16, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 16, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 16, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 16, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 16, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 16, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 16, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 16, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 32, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 32, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 32, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 32, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 32, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 32, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 32, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 32, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 32, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 64, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 64, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 64, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 64, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 64, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 64, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 64, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 64, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 64, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 128, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 128, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 128, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 128, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 128, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 128, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 128, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 128, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 128, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 256, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 256, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 256, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 256, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 256, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 256, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 256, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 256, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 256, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 512, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 512, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 512, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 512, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 512, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 512, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 512, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 512, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 512, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 1024, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 1024, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 1024, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 1024, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 1024, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 1024, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 1024, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 1024, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 1024, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2048, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2048, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2048, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2048, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2048, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2048, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2048, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2048, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 2048, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4096, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4096, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4096, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4096, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4096, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4096, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4096, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4096, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger_cached, 4096, 9);
+
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 8, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 8, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 8, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 8, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 8, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 8, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 8, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 8, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 8, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 16, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 16, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 16, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 16, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 16, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 16, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 16, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 16, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 16, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 32, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 32, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 32, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 32, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 32, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 32, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 32, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 32, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 32, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 64, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 64, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 64, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 64, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 64, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 64, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 64, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 64, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 64, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 128, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 128, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 128, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 128, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 128, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 128, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 128, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 128, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 128, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 256, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 256, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 256, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 256, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 256, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 256, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 256, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 256, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 256, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 512, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 512, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 512, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 512, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 512, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 512, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 512, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 512, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 512, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 1024, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 1024, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 1024, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 1024, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 1024, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 1024, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 1024, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 1024, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 1024, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2048, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2048, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2048, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2048, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2048, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2048, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2048, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2048, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2048, 9);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4096, 1);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4096, 2);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4096, 3);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4096, 4);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4096, 5);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4096, 6);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4096, 7);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4096, 8);
+ TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4096, 9);
+#endif
std::cout << "Tests finished. Elapsed time: " << timer.elapsed_ms() / 1000 << " sec" << std::endl;
diff --git a/tests/performance_tests/multiexp.h b/tests/performance_tests/multiexp.h
new file mode 100644
index 000000000..b8b87b3a6
--- /dev/null
+++ b/tests/performance_tests/multiexp.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2018, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#pragma once
+
+#include <vector>
+#include "ringct/rctOps.h"
+#include "ringct/multiexp.h"
+
+enum test_multiexp_algorithm
+{
+ multiexp_bos_coster,
+ multiexp_straus,
+ multiexp_straus_cached,
+ multiexp_pippenger,
+ multiexp_pippenger_cached,
+};
+
+template<test_multiexp_algorithm algorithm, size_t npoints, size_t c=0>
+class test_multiexp
+{
+public:
+ static const size_t loop_count = npoints >= 1024 ? 10 : npoints < 256 ? 1000 : 100;
+
+ bool init()
+ {
+ data.resize(npoints);
+ res = rct::identity();
+ for (size_t n = 0; n < npoints; ++n)
+ {
+ data[n].scalar = rct::skGen();
+ rct::key point = rct::scalarmultBase(rct::skGen());
+ if (ge_frombytes_vartime(&data[n].point, point.bytes))
+ return false;
+ rct::key kn = rct::scalarmultKey(point, data[n].scalar);
+ res = rct::addKeys(res, kn);
+ }
+ straus_cache = rct::straus_init_cache(data);
+ pippenger_cache = rct::pippenger_init_cache(data);
+ return true;
+ }
+
+ bool test()
+ {
+ switch (algorithm)
+ {
+ case multiexp_bos_coster:
+ return res == bos_coster_heap_conv_robust(data);
+ case multiexp_straus:
+ return res == straus(data);
+ case multiexp_straus_cached:
+ return res == straus(data, straus_cache);
+ case multiexp_pippenger:
+ return res == pippenger(data, NULL, c);
+ case multiexp_pippenger_cached:
+ return res == pippenger(data, pippenger_cache, c);
+ default:
+ return false;
+ }
+ }
+
+private:
+ std::vector<rct::MultiexpData> data;
+ std::shared_ptr<rct::straus_cached_data> straus_cache;
+ std::shared_ptr<rct::pippenger_cached_data> pippenger_cache;
+ rct::key res;
+};
diff --git a/tests/performance_tests/performance_tests.h b/tests/performance_tests/performance_tests.h
index 29d296571..d37dda729 100644
--- a/tests/performance_tests/performance_tests.h
+++ b/tests/performance_tests/performance_tests.h
@@ -36,6 +36,9 @@
#include <boost/chrono.hpp>
#include <boost/regex.hpp>
+#include "misc_language.h"
+#include "common/perf_timer.h"
+
class performance_timer
{
public:
@@ -62,13 +65,21 @@ private:
clock::time_point m_start;
};
+struct Params
+{
+ bool verbose;
+ bool stats;
+ unsigned loop_multiplier;
+};
template <typename T>
class test_runner
{
public:
- test_runner()
+ test_runner(const Params &params)
: m_elapsed(0)
+ , m_params(params)
+ , m_per_call_timers(T::loop_count * params.loop_multiplier, {true})
{
}
@@ -81,13 +92,18 @@ public:
performance_timer timer;
timer.start();
warm_up();
- std::cout << "Warm up: " << timer.elapsed_ms() << " ms" << std::endl;
+ if (m_params.verbose)
+ std::cout << "Warm up: " << timer.elapsed_ms() << " ms" << std::endl;
timer.start();
- for (size_t i = 0; i < T::loop_count; ++i)
+ for (size_t i = 0; i < T::loop_count * m_params.loop_multiplier; ++i)
{
+ if (m_params.stats)
+ m_per_call_timers[i].resume();
if (!test.test())
return false;
+ if (m_params.stats)
+ m_per_call_timers[i].pause();
}
m_elapsed = timer.elapsed_ms();
@@ -99,9 +115,62 @@ public:
int time_per_call(int scale = 1) const
{
static_assert(0 < T::loop_count, "T::loop_count must be greater than 0");
- return m_elapsed * scale / T::loop_count;
+ return m_elapsed * scale / (T::loop_count * m_params.loop_multiplier);
+ }
+
+ uint64_t per_call_min() const
+ {
+ uint64_t v = std::numeric_limits<uint64_t>::max();
+ for (const auto &pt: m_per_call_timers)
+ v = std::min(v, pt.value());
+ return v;
+ }
+
+ uint64_t per_call_max() const
+ {
+ uint64_t v = std::numeric_limits<uint64_t>::min();
+ for (const auto &pt: m_per_call_timers)
+ v = std::max(v, pt.value());
+ return v;
}
+ uint64_t per_call_mean() const
+ {
+ uint64_t v = 0;
+ for (const auto &pt: m_per_call_timers)
+ v += pt.value();
+ return v / m_per_call_timers.size();
+ }
+
+ uint64_t per_call_median() const
+ {
+ std::vector<uint64_t> values;
+ values.reserve(m_per_call_timers.size());
+ for (const auto &pt: m_per_call_timers)
+ values.push_back(pt.value());
+ return epee::misc_utils::median(values);
+ }
+
+ uint64_t per_call_stddev() const
+ {
+ if (m_per_call_timers.size() <= 1)
+ return 0;
+ const uint64_t mean = per_call_mean();
+ uint64_t acc = 0;
+ for (const auto &pt: m_per_call_timers)
+ {
+ int64_t dv = pt.value() - mean;
+ acc += dv * dv;
+ }
+ acc /= m_per_call_timers.size () - 1;
+ return sqrt(acc);
+ }
+
+ uint64_t min_time_ns() const { return tools::ticks_to_ns(per_call_min()); }
+ uint64_t max_time_ns() const { return tools::ticks_to_ns(per_call_max()); }
+ uint64_t median_time_ns() const { return tools::ticks_to_ns(per_call_median()); }
+ uint64_t standard_deviation_time_ns() const { return tools::ticks_to_ns(per_call_stddev()); }
+
private:
/**
* Warm up processor core, enabling turbo boost, etc.
@@ -120,22 +189,39 @@ private:
private:
volatile uint64_t m_warm_up; ///<! This field is intended for preclude compiler optimizations
int m_elapsed;
+ Params m_params;
+ std::vector<tools::PerformanceTimer> m_per_call_timers;
};
template <typename T>
-void run_test(const std::string &filter, const char* test_name)
+void run_test(const std::string &filter, const Params &params, const char* test_name)
{
boost::smatch match;
if (!filter.empty() && !boost::regex_match(std::string(test_name), match, boost::regex(filter)))
return;
- test_runner<T> runner;
+ test_runner<T> runner(params);
if (runner.run())
{
- std::cout << test_name << " - OK:\n";
- std::cout << " loop count: " << T::loop_count << '\n';
- std::cout << " elapsed: " << runner.elapsed_time() << " ms\n";
+ if (params.verbose)
+ {
+ std::cout << test_name << " - OK:\n";
+ std::cout << " loop count: " << T::loop_count * params.loop_multiplier << '\n';
+ std::cout << " elapsed: " << runner.elapsed_time() << " ms\n";
+ if (params.stats)
+ {
+ std::cout << " min: " << runner.min_time_ns() << " ns\n";
+ std::cout << " max: " << runner.max_time_ns() << " ns\n";
+ std::cout << " median: " << runner.median_time_ns() << " ns\n";
+ std::cout << " std dev: " << runner.standard_deviation_time_ns() << " ns\n";
+ }
+ }
+ else
+ {
+ std::cout << test_name << " (" << T::loop_count * params.loop_multiplier << " calls) - OK:";
+ }
const char *unit = "ms";
+ uint64_t scale = 1000000;
int time_per_call = runner.time_per_call();
if (time_per_call < 30000) {
time_per_call = runner.time_per_call(1000);
@@ -144,8 +230,17 @@ void run_test(const std::string &filter, const char* test_name)
#else
unit = "µs";
#endif
+ scale = 1000;
+ }
+ std::cout << (params.verbose ? " time per call: " : " ") << time_per_call << " " << unit << "/call" << (params.verbose ? "\n" : "");
+ if (params.stats)
+ {
+ uint64_t min_ns = runner.min_time_ns() / scale;
+ uint64_t med_ns = runner.median_time_ns() / scale;
+ uint64_t stddev_ns = runner.standard_deviation_time_ns() / scale;
+ std::cout << " (min " << min_ns << " " << unit << ", median " << med_ns << " " << unit << ", std dev " << stddev_ns << " " << unit << ")";
}
- std::cout << " time per call: " << time_per_call << " " << unit << "/call\n" << std::endl;
+ std::cout << std::endl;
}
else
{
@@ -154,7 +249,10 @@ void run_test(const std::string &filter, const char* test_name)
}
#define QUOTEME(x) #x
-#define TEST_PERFORMANCE0(filter, test_class) run_test< test_class >(filter, QUOTEME(test_class))
-#define TEST_PERFORMANCE1(filter, test_class, a0) run_test< test_class<a0> >(filter, QUOTEME(test_class<a0>))
-#define TEST_PERFORMANCE2(filter, test_class, a0, a1) run_test< test_class<a0, a1> >(filter, QUOTEME(test_class) "<" QUOTEME(a0) ", " QUOTEME(a1) ">")
-#define TEST_PERFORMANCE3(filter, test_class, a0, a1, a2) run_test< test_class<a0, a1, a2> >(filter, QUOTEME(test_class) "<" QUOTEME(a0) ", " QUOTEME(a1) ", " QUOTEME(a2) ">")
+#define TEST_PERFORMANCE0(filter, params, test_class) run_test< test_class >(filter, params, QUOTEME(test_class))
+#define TEST_PERFORMANCE1(filter, params, test_class, a0) run_test< test_class<a0> >(filter, params, QUOTEME(test_class<a0>))
+#define TEST_PERFORMANCE2(filter, params, test_class, a0, a1) run_test< test_class<a0, a1> >(filter, params, QUOTEME(test_class) "<" QUOTEME(a0) ", " QUOTEME(a1) ">")
+#define TEST_PERFORMANCE3(filter, params, test_class, a0, a1, a2) run_test< test_class<a0, a1, a2> >(filter, params, QUOTEME(test_class) "<" QUOTEME(a0) ", " QUOTEME(a1) ", " QUOTEME(a2) ">")
+#define TEST_PERFORMANCE4(filter, params, test_class, a0, a1, a2, a3) run_test< test_class<a0, a1, a2, a3> >(filter, params, QUOTEME(test_class) "<" QUOTEME(a0) ", " QUOTEME(a1) ", " QUOTEME(a2) ", " QUOTEME(a3) ">")
+#define TEST_PERFORMANCE5(filter, params, test_class, a0, a1, a2, a3, a4) run_test< test_class<a0, a1, a2, a3, a4> >(filter, params, QUOTEME(test_class) "<" QUOTEME(a0) ", " QUOTEME(a1) ", " QUOTEME(a2) ", " QUOTEME(a3) ", " QUOTEME(a4) ">")
+#define TEST_PERFORMANCE6(filter, params, test_class, a0, a1, a2, a3, a4, a5) run_test< test_class<a0, a1, a2, a3, a4, a5> >(filter, params, QUOTEME(test_class) "<" QUOTEME(a0) ", " QUOTEME(a1) ", " QUOTEME(a2) ", " QUOTEME(a3) ", " QUOTEME(a4) ", " QUOTEME(a5) ">")
diff --git a/tests/performance_tests/range_proof.h b/tests/performance_tests/range_proof.h
new file mode 100644
index 000000000..0ce962cd9
--- /dev/null
+++ b/tests/performance_tests/range_proof.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2014-2017, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#pragma once
+
+#include "ringct/rctSigs.h"
+
+template<bool a_verify>
+class test_range_proof
+{
+public:
+ static const size_t loop_count = 50;
+ static const bool verify = a_verify;
+
+ bool init()
+ {
+ rct::key mask;
+ sig = rct::proveRange(C, mask, 84932483243793);
+ return true;
+ }
+
+ bool test()
+ {
+ bool ret = true;
+ rct::key mask;
+ if (verify)
+ ret = rct::verRange(C, sig);
+ else
+ rct::proveRange(C, mask, 84932483243793);
+ return ret;
+ }
+
+private:
+ rct::key C;
+ rct::rangeSig sig;
+};
diff --git a/tests/performance_tests/signature.h b/tests/performance_tests/signature.h
new file mode 100644
index 000000000..21110b525
--- /dev/null
+++ b/tests/performance_tests/signature.h
@@ -0,0 +1,68 @@
+// Copyright (c) 2014-2018, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#pragma once
+
+#include "crypto/crypto.h"
+#include "cryptonote_basic/cryptonote_basic.h"
+
+#include "single_tx_test_base.h"
+
+template<bool verify>
+class test_signature : public single_tx_test_base
+{
+public:
+ static const size_t loop_count = 10000;
+
+ bool init()
+ {
+ if (!single_tx_test_base::init())
+ return false;
+
+ message = crypto::rand<crypto::hash>();
+ keys = cryptonote::keypair::generate(hw::get_device("default"));
+ crypto::generate_signature(message, keys.pub, keys.sec, m_signature);
+
+ return true;
+ }
+
+ bool test()
+ {
+ if (verify)
+ return crypto::check_signature(message, keys.pub, m_signature);
+ crypto::generate_signature(message, keys.pub, keys.sec, m_signature);
+ return true;
+ }
+
+private:
+ cryptonote::keypair keys;
+ crypto::hash message;
+ crypto::signature m_signature;
+};