aboutsummaryrefslogtreecommitdiff
path: root/src/ringct
diff options
context:
space:
mode:
authorRiccardo Spagni <ric@spagni.net>2019-03-04 21:18:52 +0200
committerRiccardo Spagni <ric@spagni.net>2019-03-04 21:18:53 +0200
commit9d415495bfd43e4072fe71c41a9a0c3076e6635f (patch)
tree116b83574ac3ecdc5ed3b3b1aaa32764bb8c0efa /src/ringct
parentMerge pull request #5081 (diff)
parentbulletproofs: speed up vector_power_sum (diff)
downloadmonero-9d415495bfd43e4072fe71c41a9a0c3076e6635f.tar.xz
Merge pull request #5082
1bc5f9fa bulletproofs: speed up vector_power_sum (moneromooo-monero)
Diffstat (limited to 'src/ringct')
-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;
}