diff --git a/libff/algebra/scalar_multiplication/multiexp.hpp b/libff/algebra/scalar_multiplication/multiexp.hpp index bbbdb040..0e503ed6 100755 --- a/libff/algebra/scalar_multiplication/multiexp.hpp +++ b/libff/algebra/scalar_multiplication/multiexp.hpp @@ -116,6 +116,13 @@ std::vector batch_exp(const size_t scalar_size, const window_table &table, const std::vector &v); +template +std::vector batch_exp(const size_t scalar_size, + const size_t window, + const window_table &table, + const std::vector &v, + size_t num_entries); + template std::vector batch_exp_with_coeff(const size_t scalar_size, const size_t window, diff --git a/libff/algebra/scalar_multiplication/multiexp.tcc b/libff/algebra/scalar_multiplication/multiexp.tcc index 0c85e2bc..b7782119 100755 --- a/libff/algebra/scalar_multiplication/multiexp.tcc +++ b/libff/algebra/scalar_multiplication/multiexp.tcc @@ -620,17 +620,27 @@ std::vector batch_exp(const size_t scalar_size, const size_t window, const window_table &table, const std::vector &v) +{ + return batch_exp(scalar_size, window, table, v, v.size()); +} + +template +std::vector batch_exp(const size_t scalar_size, + const size_t window, + const window_table &table, + const std::vector &v, + size_t num_entries) { if (!inhibit_profiling_info) { print_indent(); } - std::vector res(v.size(), table[0][0]); + std::vector res(num_entries, table[0][0]); #ifdef MULTICORE #pragma omp parallel for #endif - for (size_t i = 0; i < v.size(); ++i) + for (size_t i = 0; i < num_entries; ++i) { res[i] = windowed_exp(scalar_size, window, table, v[i]); diff --git a/libff/algebra/scalar_multiplication/wnaf.hpp b/libff/algebra/scalar_multiplication/wnaf.hpp index 6c65cde2..c6320b62 100755 --- a/libff/algebra/scalar_multiplication/wnaf.hpp +++ b/libff/algebra/scalar_multiplication/wnaf.hpp @@ -18,12 +18,32 @@ namespace libff { +/** + * Find the wNAF representation of the given scalar relative to the given + * window size, reusing the given vector to store it. + */ +template +void update_wnaf(std::vector &naf, const size_t window_size, const bigint &scalar); + /** * Find the wNAF representation of the given scalar relative to the given window size. */ template std::vector find_wnaf(const size_t window_size, const bigint &scalar); +/** + * Compute optimal window size. + */ +template +size_t wnaf_opt_window_size(const size_t scalar_bits); + +/** + * In additive notation, use wNAF exponentiation (with the given window size) + * to compute scalar * base, for a scalar in naf form. + */ +template +T fixed_window_wnaf_exp(const size_t window_size, const T &base, const std::vector &naf); + /** * In additive notation, use wNAF exponentiation (with the given window size) to compute scalar * base. */ diff --git a/libff/algebra/scalar_multiplication/wnaf.tcc b/libff/algebra/scalar_multiplication/wnaf.tcc index 5a8205e7..65b2b880 100755 --- a/libff/algebra/scalar_multiplication/wnaf.tcc +++ b/libff/algebra/scalar_multiplication/wnaf.tcc @@ -19,10 +19,10 @@ namespace libff { template -std::vector find_wnaf(const size_t window_size, const bigint &scalar) +void update_wnaf(std::vector &wnaf, const size_t window_size, const bigint &scalar) { const size_t length = scalar.max_bits(); // upper bound - std::vector res(length+1); + wnaf.resize(length+1); bigint c = scalar; long j = 0; while (!c.is_zero()) @@ -49,19 +49,40 @@ std::vector find_wnaf(const size_t window_size, const bigint &scalar) { u = 0; } - res[j] = u; + wnaf[j] = u; ++j; mpn_rshift(c.data, c.data, n, 1); // c = c/2 } + wnaf.resize(j); +} + +template +std::vector find_wnaf(const size_t window_size, const bigint &scalar) +{ + std::vector res; + update_wnaf(res, window_size, scalar); return res; } -template -T fixed_window_wnaf_exp(const size_t window_size, const T &base, const bigint &scalar) +template +size_t wnaf_opt_window_size(const size_t scalar_bits) +{ + for (long i = T::wnaf_window_table.size() - 1; i >= 0; --i) + { + if (scalar_bits >= T::wnaf_window_table[i]) + { + return i+1; + } + } + + return 0; +} + +template +T fixed_window_wnaf_exp(const size_t window_size, const T &base, const std::vector &naf) { - std::vector naf = find_wnaf(window_size, scalar); std::vector table(1ul<<(window_size-1)); T tmp = base; T dbl = base.dbl(); @@ -98,18 +119,16 @@ T fixed_window_wnaf_exp(const size_t window_size, const T &base, const bigint } template -T opt_window_wnaf_exp(const T &base, const bigint &scalar, const size_t scalar_bits) +T fixed_window_wnaf_exp(const size_t window_size, const T &base, const bigint &scalar) { - size_t best = 0; - for (long i = T::wnaf_window_table.size() - 1; i >= 0; --i) - { - if (scalar_bits >= T::wnaf_window_table[i]) - { - best = i+1; - break; - } - } + std::vector naf = find_wnaf(window_size, scalar); + return fixed_window_wnaf_exp(window_size, base, naf); +} +template +T opt_window_wnaf_exp(const T &base, const bigint &scalar, const size_t scalar_bits) +{ + const size_t best = wnaf_opt_window_size(scalar_bits); if (best > 0) { return fixed_window_wnaf_exp(best, base, scalar);