aboutsummaryrefslogtreecommitdiff
path: root/src/ringct/bulletproofs.cc
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2019-01-18 19:51:29 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2019-01-19 00:18:34 +0000
commit1bc5f9fa4b4b9b7a488c1766023e73f31503a889 (patch)
treee94abf03993e6361f219edab08391cd26ef2a582 /src/ringct/bulletproofs.cc
parentMerge pull request #5008 (diff)
downloadmonero-1bc5f9fa4b4b9b7a488c1766023e73f31503a889.tar.xz
bulletproofs: speed up vector_power_sum
found by sarang
Diffstat (limited to 'src/ringct/bulletproofs.cc')
-rw-r--r--src/ringct/bulletproofs.cc28
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;
}