diff options
author | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2019-01-18 19:51:29 +0000 |
---|---|---|
committer | moneromooo-monero <moneromooo-monero@users.noreply.github.com> | 2019-01-19 00:18:34 +0000 |
commit | 1bc5f9fa4b4b9b7a488c1766023e73f31503a889 (patch) | |
tree | e94abf03993e6361f219edab08391cd26ef2a582 /src | |
parent | Merge pull request #5008 (diff) | |
download | monero-1bc5f9fa4b4b9b7a488c1766023e73f31503a889.tar.xz |
bulletproofs: speed up vector_power_sum
found by sarang
Diffstat (limited to 'src')
-rw-r--r-- | src/ringct/bulletproofs.cc | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/src/ringct/bulletproofs.cc b/src/ringct/bulletproofs.cc index d485fb748..b5fd626dc 100644 --- a/src/ringct/bulletproofs.cc +++ b/src/ringct/bulletproofs.cc @@ -202,20 +202,36 @@ static rct::keyV vector_powers(const rct::key &x, size_t n) } /* Given a scalar, return the sum of its powers from 0 to n-1 */ -static rct::key vector_power_sum(const rct::key &x, size_t n) +static rct::key vector_power_sum(rct::key x, size_t n) { if (n == 0) return rct::zero(); rct::key res = rct::identity(); if (n == 1) return res; - rct::key prev = x; - for (size_t i = 1; i < n; ++i) + + const bool is_power_of_2 = (n & (n - 1)) == 0; + if (is_power_of_2) { - if (i > 1) - sc_mul(prev.bytes, prev.bytes, x.bytes); - sc_add(res.bytes, res.bytes, prev.bytes); + sc_add(res.bytes, res.bytes, x.bytes); + while (n > 2) + { + sc_mul(x.bytes, x.bytes, x.bytes); + sc_muladd(res.bytes, x.bytes, res.bytes, res.bytes); + n /= 2; + } + } + else + { + rct::key prev = x; + for (size_t i = 1; i < n; ++i) + { + if (i > 1) + sc_mul(prev.bytes, prev.bytes, x.bytes); + sc_add(res.bytes, res.bytes, prev.bytes); + } } + return res; } |