mirror of
https://github.com/monero-project/monero.git
synced 2024-11-17 16:27:39 +00:00
Add Pippenger cache and limit Straus cache size
This commit is contained in:
parent
51eb3bdcd6
commit
0b05a0fa74
5 changed files with 217 additions and 39 deletions
|
@ -49,6 +49,9 @@ extern "C"
|
||||||
|
|
||||||
#define PERF_TIMER_START_BP(x) PERF_TIMER_START_UNIT(x, 1000000)
|
#define PERF_TIMER_START_BP(x) PERF_TIMER_START_UNIT(x, 1000000)
|
||||||
|
|
||||||
|
#define STRAUS_SIZE_LIMIT 128
|
||||||
|
#define PIPPENGER_SIZE_LIMIT 0
|
||||||
|
|
||||||
namespace rct
|
namespace rct
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -61,8 +64,8 @@ static constexpr size_t maxN = 64;
|
||||||
static constexpr size_t maxM = BULLETPROOF_MAX_OUTPUTS;
|
static constexpr size_t maxM = BULLETPROOF_MAX_OUTPUTS;
|
||||||
static rct::key Hi[maxN*maxM], Gi[maxN*maxM];
|
static rct::key Hi[maxN*maxM], Gi[maxN*maxM];
|
||||||
static ge_p3 Hi_p3[maxN*maxM], Gi_p3[maxN*maxM];
|
static ge_p3 Hi_p3[maxN*maxM], Gi_p3[maxN*maxM];
|
||||||
static ge_dsmp Gprecomp[maxN*maxM], Hprecomp[maxN*maxM];
|
static std::shared_ptr<straus_cached_data> straus_HiGi_cache;
|
||||||
static std::shared_ptr<straus_cached_data> HiGi_cache;
|
static std::shared_ptr<pippenger_cached_data> pippenger_HiGi_cache;
|
||||||
static const rct::key TWO = { {0x02, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 } };
|
static const rct::key TWO = { {0x02, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 } };
|
||||||
static const rct::keyV oneN = vector_dup(rct::identity(), maxN);
|
static const rct::keyV oneN = vector_dup(rct::identity(), maxN);
|
||||||
static const rct::keyV twoN = vector_powers(TWO, maxN);
|
static const rct::keyV twoN = vector_powers(TWO, maxN);
|
||||||
|
@ -73,9 +76,12 @@ static inline rct::key multiexp(const std::vector<MultiexpData> &data, bool HiGi
|
||||||
{
|
{
|
||||||
static const size_t STEP = getenv("STRAUS_STEP") ? atoi(getenv("STRAUS_STEP")) : 0;
|
static const size_t STEP = getenv("STRAUS_STEP") ? atoi(getenv("STRAUS_STEP")) : 0;
|
||||||
if (HiGi)
|
if (HiGi)
|
||||||
return data.size() <= 256 ? straus(data, HiGi_cache, STEP) : pippenger(data, get_pippenger_c(data.size()));
|
{
|
||||||
|
static_assert(128 <= STRAUS_SIZE_LIMIT, "Straus in precalc mode can only be calculated till STRAUS_SIZE_LIMIT");
|
||||||
|
return data.size() <= 128 ? straus(data, straus_HiGi_cache, STEP) : pippenger(data, pippenger_HiGi_cache, get_pippenger_c(data.size()));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return data.size() <= 64 ? straus(data, NULL, STEP) : pippenger(data, get_pippenger_c(data.size()));
|
return data.size() <= 64 ? straus(data, NULL, STEP) : pippenger(data, NULL, get_pippenger_c(data.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//addKeys3acc_p3
|
//addKeys3acc_p3
|
||||||
|
@ -123,18 +129,23 @@ static void init_exponents()
|
||||||
for (size_t i = 0; i < maxN*maxM; ++i)
|
for (size_t i = 0; i < maxN*maxM; ++i)
|
||||||
{
|
{
|
||||||
Hi[i] = get_exponent(rct::H, i * 2);
|
Hi[i] = get_exponent(rct::H, i * 2);
|
||||||
rct::precomp(Hprecomp[i], Hi[i]);
|
|
||||||
CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&Hi_p3[i], Hi[i].bytes) == 0, "ge_frombytes_vartime failed");
|
CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&Hi_p3[i], Hi[i].bytes) == 0, "ge_frombytes_vartime failed");
|
||||||
Gi[i] = get_exponent(rct::H, i * 2 + 1);
|
Gi[i] = get_exponent(rct::H, i * 2 + 1);
|
||||||
rct::precomp(Gprecomp[i], Gi[i]);
|
|
||||||
CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&Gi_p3[i], Gi[i].bytes) == 0, "ge_frombytes_vartime failed");
|
CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&Gi_p3[i], Gi[i].bytes) == 0, "ge_frombytes_vartime failed");
|
||||||
|
|
||||||
data.push_back({rct::zero(), Gi[i]});
|
data.push_back({rct::zero(), Gi[i]});
|
||||||
data.push_back({rct::zero(), Hi[i]});
|
data.push_back({rct::zero(), Hi[i]});
|
||||||
}
|
}
|
||||||
HiGi_cache = straus_init_cache(data);
|
|
||||||
size_t cache_size = (sizeof(Hi)+sizeof(Hprecomp)+sizeof(Hi_p3))*2 + straus_get_cache_size(HiGi_cache);
|
straus_HiGi_cache = straus_init_cache(data, STRAUS_SIZE_LIMIT);
|
||||||
MINFO("cache size: " << cache_size/1024 << " kB");
|
pippenger_HiGi_cache = pippenger_init_cache(data, PIPPENGER_SIZE_LIMIT);
|
||||||
|
|
||||||
|
MINFO("Hi/Gi cache size: " << (sizeof(Hi)+sizeof(Gi))/1024 << " kB");
|
||||||
|
MINFO("Hi_p3/Gi_p3 cache size: " << (sizeof(Hi_p3)+sizeof(Gi_p3))/1024 << " kB");
|
||||||
|
MINFO("Straus cache size: " << straus_get_cache_size(straus_HiGi_cache)/1024 << " kB");
|
||||||
|
MINFO("Pippenger cache size: " << pippenger_get_cache_size(pippenger_HiGi_cache)/1024 << " kB");
|
||||||
|
size_t cache_size = (sizeof(Hi)+sizeof(Hi_p3))*2 + straus_get_cache_size(straus_HiGi_cache) + pippenger_get_cache_size(pippenger_HiGi_cache);
|
||||||
|
MINFO("Total cache size: " << cache_size/1024 << "kB");
|
||||||
init_done = true;
|
init_done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -343,9 +343,12 @@ struct straus_cached_data
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::shared_ptr<straus_cached_data> straus_init_cache(const std::vector<MultiexpData> &data)
|
std::shared_ptr<straus_cached_data> straus_init_cache(const std::vector<MultiexpData> &data, size_t N)
|
||||||
{
|
{
|
||||||
MULTIEXP_PERF(PERF_TIMER_START_UNIT(multiples, 1000000));
|
MULTIEXP_PERF(PERF_TIMER_START_UNIT(multiples, 1000000));
|
||||||
|
if (N == 0)
|
||||||
|
N = data.size();
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(N <= data.size(), "Bad cache base data");
|
||||||
ge_cached cached;
|
ge_cached cached;
|
||||||
ge_p1p1 p1;
|
ge_p1p1 p1;
|
||||||
ge_p3 p3;
|
ge_p3 p3;
|
||||||
|
@ -353,9 +356,10 @@ std::shared_ptr<straus_cached_data> straus_init_cache(const std::vector<Multiexp
|
||||||
|
|
||||||
#ifdef RAW_MEMORY_BLOCK
|
#ifdef RAW_MEMORY_BLOCK
|
||||||
const size_t offset = cache->size;
|
const size_t offset = cache->size;
|
||||||
cache->multiples = (ge_cached*)aligned_realloc(cache->multiples, sizeof(ge_cached) * ((1<<STRAUS_C)-1) * std::max(offset, data.size()), 4096);
|
cache->multiples = (ge_cached*)aligned_realloc(cache->multiples, sizeof(ge_cached) * ((1<<STRAUS_C)-1) * std::max(offset, N), 4096);
|
||||||
cache->size = data.size();
|
CHECK_AND_ASSERT_THROW_MES(cache->multiples, "Out of memory");
|
||||||
for (size_t j=offset;j<data.size();++j)
|
cache->size = N;
|
||||||
|
for (size_t j=offset;j<N;++j)
|
||||||
{
|
{
|
||||||
ge_p3_to_cached(&CACHE_OFFSET(cache, j, 1), &data[j].point);
|
ge_p3_to_cached(&CACHE_OFFSET(cache, j, 1), &data[j].point);
|
||||||
for (size_t i=2;i<1<<STRAUS_C;++i)
|
for (size_t i=2;i<1<<STRAUS_C;++i)
|
||||||
|
@ -368,8 +372,8 @@ std::shared_ptr<straus_cached_data> straus_init_cache(const std::vector<Multiexp
|
||||||
#else
|
#else
|
||||||
#ifdef ALTERNATE_LAYOUT
|
#ifdef ALTERNATE_LAYOUT
|
||||||
const size_t offset = cache->multiples.size();
|
const size_t offset = cache->multiples.size();
|
||||||
cache->multiples.resize(std::max(offset, data.size()));
|
cache->multiples.resize(std::max(offset, N));
|
||||||
for (size_t i = offset; i < data.size(); ++i)
|
for (size_t i = offset; i < N; ++i)
|
||||||
{
|
{
|
||||||
cache->multiples[i].resize((1<<STRAUS_C)-1);
|
cache->multiples[i].resize((1<<STRAUS_C)-1);
|
||||||
ge_p3_to_cached(&cache->multiples[i][0], &data[i].point);
|
ge_p3_to_cached(&cache->multiples[i][0], &data[i].point);
|
||||||
|
@ -383,12 +387,12 @@ std::shared_ptr<straus_cached_data> straus_init_cache(const std::vector<Multiexp
|
||||||
#else
|
#else
|
||||||
cache->multiples.resize(1<<STRAUS_C);
|
cache->multiples.resize(1<<STRAUS_C);
|
||||||
size_t offset = cache->multiples[1].size();
|
size_t offset = cache->multiples[1].size();
|
||||||
cache->multiples[1].resize(std::max(offset, data.size()));
|
cache->multiples[1].resize(std::max(offset, N));
|
||||||
for (size_t i = offset; i < data.size(); ++i)
|
for (size_t i = offset; i < N; ++i)
|
||||||
ge_p3_to_cached(&cache->multiples[1][i], &data[i].point);
|
ge_p3_to_cached(&cache->multiples[1][i], &data[i].point);
|
||||||
for (size_t i=2;i<1<<STRAUS_C;++i)
|
for (size_t i=2;i<1<<STRAUS_C;++i)
|
||||||
cache->multiples[i].resize(std::max(offset, data.size()));
|
cache->multiples[i].resize(std::max(offset, N));
|
||||||
for (size_t j=offset;j<data.size();++j)
|
for (size_t j=offset;j<N;++j)
|
||||||
{
|
{
|
||||||
for (size_t i=2;i<1<<STRAUS_C;++i)
|
for (size_t i=2;i<1<<STRAUS_C;++i)
|
||||||
{
|
{
|
||||||
|
@ -418,6 +422,7 @@ size_t straus_get_cache_size(const std::shared_ptr<straus_cached_data> &cache)
|
||||||
|
|
||||||
rct::key straus(const std::vector<MultiexpData> &data, const std::shared_ptr<straus_cached_data> &cache, size_t STEP)
|
rct::key straus(const std::vector<MultiexpData> &data, const std::shared_ptr<straus_cached_data> &cache, size_t STEP)
|
||||||
{
|
{
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(cache == NULL || cache->size >= data.size(), "Cache is too small");
|
||||||
MULTIEXP_PERF(PERF_TIMER_UNIT(straus, 1000000));
|
MULTIEXP_PERF(PERF_TIMER_UNIT(straus, 1000000));
|
||||||
bool HiGi = cache != NULL;
|
bool HiGi = cache != NULL;
|
||||||
STEP = STEP ? STEP : 192;
|
STEP = STEP ? STEP : 192;
|
||||||
|
@ -533,7 +538,8 @@ skipfirst:
|
||||||
|
|
||||||
size_t get_pippenger_c(size_t N)
|
size_t get_pippenger_c(size_t N)
|
||||||
{
|
{
|
||||||
// 2:1, 4:2, 8:2, 16:3, 32:4, 64:4, 128:5, 256:6, 512:7, 1024:7, 2048:8, 4096:9
|
// uncached: 2:1, 4:2, 8:2, 16:3, 32:4, 64:4, 128:5, 256:6, 512:7, 1024:7, 2048:8, 4096:9
|
||||||
|
// cached: 2:1, 4:2, 8:2, 16:3, 32:4, 64:4, 128:5, 256:6, 512:7, 1024:7, 2048:8, 4096:9
|
||||||
if (N <= 2) return 1;
|
if (N <= 2) return 1;
|
||||||
if (N <= 8) return 2;
|
if (N <= 8) return 2;
|
||||||
if (N <= 16) return 3;
|
if (N <= 16) return 3;
|
||||||
|
@ -545,23 +551,55 @@ size_t get_pippenger_c(size_t N)
|
||||||
return 9;
|
return 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
rct::key pippenger(const std::vector<MultiexpData> &data, size_t c)
|
struct pippenger_cached_data
|
||||||
{
|
{
|
||||||
|
size_t size;
|
||||||
|
ge_cached *cached;
|
||||||
|
pippenger_cached_data(): size(0), cached(NULL) {}
|
||||||
|
~pippenger_cached_data() { aligned_free(cached); }
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<pippenger_cached_data> pippenger_init_cache(const std::vector<MultiexpData> &data, size_t N)
|
||||||
|
{
|
||||||
|
MULTIEXP_PERF(PERF_TIMER_START_UNIT(pippenger_init_cache, 1000000));
|
||||||
|
if (N == 0)
|
||||||
|
N = data.size();
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(N <= data.size(), "Bad cache base data");
|
||||||
|
ge_cached cached;
|
||||||
|
std::shared_ptr<pippenger_cached_data> cache(new pippenger_cached_data());
|
||||||
|
|
||||||
|
cache->size = N;
|
||||||
|
cache->cached = (ge_cached*)aligned_realloc(cache->cached, N * sizeof(ge_cached), 4096);
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(cache->cached, "Out of memory");
|
||||||
|
for (size_t i = 0; i < N; ++i)
|
||||||
|
ge_p3_to_cached(&cache->cached[i], &data[i].point);
|
||||||
|
|
||||||
|
MULTIEXP_PERF(PERF_TIMER_STOP(pippenger_init_cache));
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t pippenger_get_cache_size(const std::shared_ptr<pippenger_cached_data> &cache)
|
||||||
|
{
|
||||||
|
return cache->size * sizeof(*cache->cached);
|
||||||
|
}
|
||||||
|
|
||||||
|
rct::key pippenger(const std::vector<MultiexpData> &data, const std::shared_ptr<pippenger_cached_data> &cache, size_t c)
|
||||||
|
{
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(cache == NULL || cache->size >= data.size(), "Cache is too small");
|
||||||
|
if (c == 0)
|
||||||
|
c = get_pippenger_c(data.size());
|
||||||
CHECK_AND_ASSERT_THROW_MES(c <= 9, "c is too large");
|
CHECK_AND_ASSERT_THROW_MES(c <= 9, "c is too large");
|
||||||
|
|
||||||
ge_p3 result = ge_p3_identity;
|
ge_p3 result = ge_p3_identity;
|
||||||
std::unique_ptr<ge_p3[]> buckets{new ge_p3[1<<c]};
|
std::unique_ptr<ge_p3[]> buckets{new ge_p3[1<<c]};
|
||||||
std::unique_ptr<ge_cached[]> cached_points{new ge_cached[data.size()]};
|
std::shared_ptr<pippenger_cached_data> local_cache = cache == NULL ? pippenger_init_cache(data) : cache;
|
||||||
|
|
||||||
for (size_t i = 0; i < data.size(); ++i)
|
|
||||||
{
|
|
||||||
ge_p3_to_cached(&cached_points[i], &data[i].point);
|
|
||||||
}
|
|
||||||
|
|
||||||
rct::key maxscalar = rct::zero();
|
rct::key maxscalar = rct::zero();
|
||||||
for (size_t i = 0; i < data.size(); ++i)
|
for (size_t i = 0; i < data.size(); ++i)
|
||||||
|
{
|
||||||
if (maxscalar < data[i].scalar)
|
if (maxscalar < data[i].scalar)
|
||||||
maxscalar = data[i].scalar;
|
maxscalar = data[i].scalar;
|
||||||
|
}
|
||||||
size_t groups = 0;
|
size_t groups = 0;
|
||||||
while (groups < 256 && pow2(groups) < maxscalar)
|
while (groups < 256 && pow2(groups) < maxscalar)
|
||||||
++groups;
|
++groups;
|
||||||
|
@ -598,7 +636,7 @@ rct::key pippenger(const std::vector<MultiexpData> &data, size_t c)
|
||||||
CHECK_AND_ASSERT_THROW_MES(bucket < (1u<<c), "bucket overflow");
|
CHECK_AND_ASSERT_THROW_MES(bucket < (1u<<c), "bucket overflow");
|
||||||
if (memcmp(&buckets[bucket], &ge_p3_identity, sizeof(ge_p3)))
|
if (memcmp(&buckets[bucket], &ge_p3_identity, sizeof(ge_p3)))
|
||||||
{
|
{
|
||||||
add(buckets[bucket], cached_points[i]);
|
add(buckets[bucket], local_cache->cached[i]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
buckets[bucket] = data[i].point;
|
buckets[bucket] = data[i].point;
|
||||||
|
|
|
@ -54,14 +54,17 @@ struct MultiexpData {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct straus_cached_data;
|
struct straus_cached_data;
|
||||||
|
struct pippenger_cached_data;
|
||||||
|
|
||||||
rct::key bos_coster_heap_conv(std::vector<MultiexpData> data);
|
rct::key bos_coster_heap_conv(std::vector<MultiexpData> data);
|
||||||
rct::key bos_coster_heap_conv_robust(std::vector<MultiexpData> data);
|
rct::key bos_coster_heap_conv_robust(std::vector<MultiexpData> data);
|
||||||
std::shared_ptr<straus_cached_data> straus_init_cache(const std::vector<MultiexpData> &data);
|
std::shared_ptr<straus_cached_data> straus_init_cache(const std::vector<MultiexpData> &data, size_t N =0);
|
||||||
size_t straus_get_cache_size(const std::shared_ptr<straus_cached_data> &cache);
|
size_t straus_get_cache_size(const std::shared_ptr<straus_cached_data> &cache);
|
||||||
rct::key straus(const std::vector<MultiexpData> &data, const std::shared_ptr<straus_cached_data> &cache = NULL, size_t STEP = 0);
|
rct::key straus(const std::vector<MultiexpData> &data, const std::shared_ptr<straus_cached_data> &cache = NULL, size_t STEP = 0);
|
||||||
|
std::shared_ptr<pippenger_cached_data> pippenger_init_cache(const std::vector<MultiexpData> &data, size_t N =0);
|
||||||
|
size_t pippenger_get_cache_size(const std::shared_ptr<pippenger_cached_data> &cache);
|
||||||
size_t get_pippenger_c(size_t N);
|
size_t get_pippenger_c(size_t N);
|
||||||
rct::key pippenger(const std::vector<MultiexpData> &data, size_t c);
|
rct::key pippenger(const std::vector<MultiexpData> &data, const std::shared_ptr<pippenger_cached_data> &cache = NULL, size_t c = 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -281,16 +281,137 @@ int main(int argc, char** argv)
|
||||||
TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2, 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, 4, 2);
|
||||||
TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 8, 2);
|
TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 8, 2);
|
||||||
TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 16, 4);
|
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, 32, 4);
|
||||||
TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 64, 5);
|
TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 64, 4);
|
||||||
TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 128, 6);
|
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, 256, 6);
|
||||||
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, 1024, 8);
|
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, 2048, 8);
|
||||||
TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 4096, 9);
|
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
|
#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, 1);
|
||||||
TEST_PERFORMANCE3(filter, p, test_multiexp, multiexp_pippenger, 2, 2);
|
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, 3);
|
||||||
|
|
|
@ -40,6 +40,7 @@ enum test_multiexp_algorithm
|
||||||
multiexp_straus,
|
multiexp_straus,
|
||||||
multiexp_straus_cached,
|
multiexp_straus_cached,
|
||||||
multiexp_pippenger,
|
multiexp_pippenger,
|
||||||
|
multiexp_pippenger_cached,
|
||||||
};
|
};
|
||||||
|
|
||||||
template<test_multiexp_algorithm algorithm, size_t npoints, size_t c=0>
|
template<test_multiexp_algorithm algorithm, size_t npoints, size_t c=0>
|
||||||
|
@ -61,7 +62,8 @@ public:
|
||||||
rct::key kn = rct::scalarmultKey(point, data[n].scalar);
|
rct::key kn = rct::scalarmultKey(point, data[n].scalar);
|
||||||
res = rct::addKeys(res, kn);
|
res = rct::addKeys(res, kn);
|
||||||
}
|
}
|
||||||
cache = rct::straus_init_cache(data);
|
straus_cache = rct::straus_init_cache(data);
|
||||||
|
pippenger_cache = rct::pippenger_init_cache(data);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,9 +76,11 @@ public:
|
||||||
case multiexp_straus:
|
case multiexp_straus:
|
||||||
return res == straus(data);
|
return res == straus(data);
|
||||||
case multiexp_straus_cached:
|
case multiexp_straus_cached:
|
||||||
return res == straus(data, cache);
|
return res == straus(data, straus_cache);
|
||||||
case multiexp_pippenger:
|
case multiexp_pippenger:
|
||||||
return res == pippenger(data, c);
|
return res == pippenger(data, NULL, c);
|
||||||
|
case multiexp_pippenger_cached:
|
||||||
|
return res == pippenger(data, pippenger_cache, c);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -84,6 +88,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<rct::MultiexpData> data;
|
std::vector<rct::MultiexpData> data;
|
||||||
std::shared_ptr<rct::straus_cached_data> cache;
|
std::shared_ptr<rct::straus_cached_data> straus_cache;
|
||||||
|
std::shared_ptr<rct::pippenger_cached_data> pippenger_cache;
|
||||||
rct::key res;
|
rct::key res;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue