bulletproofs: random minor speedups

This commit is contained in:
moneromooo-monero 2018-08-08 12:14:13 +00:00
parent a49a17618f
commit a621d6c8b4
No known key found for this signature in database
GPG Key ID: 686F07454D6CEFC3
1 changed files with 38 additions and 40 deletions

View File

@ -93,18 +93,6 @@ static bool is_reduced(const rct::key &scalar)
return scalar == reduced; return scalar == reduced;
} }
static void addKeys_acc_p3(ge_p3 *acc_p3, const rct::key &a, const rct::key &point)
{
ge_p3 p3;
CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&p3, point.bytes) == 0, "ge_frombytes_vartime failed");
ge_scalarmult_p3(&p3, a.bytes, &p3);
ge_cached cached;
ge_p3_to_cached(&cached, acc_p3);
ge_p1p1 p1;
ge_add(&p1, &p3, &cached);
ge_p1p1_to_p3(acc_p3, &p1);
}
static void add_acc_p3(ge_p3 *acc_p3, const rct::key &point) static void add_acc_p3(ge_p3 *acc_p3, const rct::key &point)
{ {
ge_p3 p3; ge_p3 p3;
@ -435,10 +423,13 @@ Bulletproof bulletproof_PROVE(const rct::key &sv, const rct::key &gamma)
rct::key V; rct::key V;
rct::keyV aL(N), aR(N); rct::keyV aL(N), aR(N);
rct::key tmp, tmp2;
PERF_TIMER_START_BP(PROVE_v); PERF_TIMER_START_BP(PROVE_v);
rct::addKeys2(V, gamma, sv, rct::H); rct::key gamma8, sv8;
V = rct::scalarmultKey(V, INV_EIGHT); sc_mul(gamma8.bytes, gamma.bytes, INV_EIGHT.bytes);
sc_mul(sv8.bytes, sv.bytes, INV_EIGHT.bytes);
rct::addKeys2(V, gamma8, sv8, rct::H);
PERF_TIMER_STOP(PROVE_v); PERF_TIMER_STOP(PROVE_v);
PERF_TIMER_START_BP(PROVE_aLaR); PERF_TIMER_START_BP(PROVE_aLaR);
@ -515,7 +506,6 @@ try_again:
const auto yN = vector_powers(y, N); const auto yN = vector_powers(y, N);
rct::key ip1y = vector_sum(yN); rct::key ip1y = vector_sum(yN);
rct::key tmp;
sc_muladd(t0.bytes, z.bytes, ip1y.bytes, t0.bytes); sc_muladd(t0.bytes, z.bytes, ip1y.bytes, t0.bytes);
rct::key zsq; rct::key zsq;
@ -563,10 +553,16 @@ try_again:
// PAPER LINES 47-48 // PAPER LINES 47-48
rct::key tau1 = rct::skGen(), tau2 = rct::skGen(); rct::key tau1 = rct::skGen(), tau2 = rct::skGen();
rct::key T1 = rct::addKeys(rct::scalarmultH(t1), rct::scalarmultBase(tau1)); rct::key T1, T2;
T1 = rct::scalarmultKey(T1, INV_EIGHT); ge_p3 p3;
rct::key T2 = rct::addKeys(rct::scalarmultH(t2), rct::scalarmultBase(tau2)); sc_mul(tmp.bytes, t1.bytes, INV_EIGHT.bytes);
T2 = rct::scalarmultKey(T2, INV_EIGHT); sc_mul(tmp2.bytes, tau1.bytes, INV_EIGHT.bytes);
ge_double_scalarmult_base_vartime_p3(&p3, tmp.bytes, &ge_p3_H, tmp2.bytes);
ge_p3_tobytes(T1.bytes, &p3);
sc_mul(tmp.bytes, t2.bytes, INV_EIGHT.bytes);
sc_mul(tmp2.bytes, tau2.bytes, INV_EIGHT.bytes);
ge_double_scalarmult_base_vartime_p3(&p3, tmp.bytes, &ge_p3_H, tmp2.bytes);
ge_p3_tobytes(T2.bytes, &p3);
// PAPER LINES 49-51 // PAPER LINES 49-51
rct::key x = hash_cache_mash(hash_cache, z, T1, T2); rct::key x = hash_cache_mash(hash_cache, z, T1, T2);
@ -671,7 +667,7 @@ try_again:
PERF_TIMER_STOP(PROVE_step4); PERF_TIMER_STOP(PROVE_step4);
// PAPER LINE 58 (with inclusions from PAPER LINE 8 and PAPER LINE 20) // PAPER LINE 58 (with inclusions from PAPER LINE 8 and PAPER LINE 20)
return Bulletproof(V, A, S, T1, T2, taux, mu, L, R, aprime[0], bprime[0], t); return Bulletproof(V, A, S, T1, T2, taux, mu, std::move(L), std::move(R), aprime[0], bprime[0], t);
} }
Bulletproof bulletproof_PROVE(uint64_t v, const rct::key &gamma) Bulletproof bulletproof_PROVE(uint64_t v, const rct::key &gamma)
@ -715,13 +711,15 @@ Bulletproof bulletproof_PROVE(const rct::keyV &sv, const rct::keyV &gamma)
rct::keyV V(sv.size()); rct::keyV V(sv.size());
rct::keyV aL(MN), aR(MN); rct::keyV aL(MN), aR(MN);
rct::key tmp; rct::key tmp, tmp2;
PERF_TIMER_START_BP(PROVE_v); PERF_TIMER_START_BP(PROVE_v);
for (size_t i = 0; i < sv.size(); ++i) for (size_t i = 0; i < sv.size(); ++i)
{ {
rct::addKeys2(V[i], gamma[i], sv[i], rct::H); rct::key gamma8, sv8;
V[i] = rct::scalarmultKey(V[i], INV_EIGHT); sc_mul(gamma8.bytes, gamma[i].bytes, INV_EIGHT.bytes);
sc_mul(sv8.bytes, sv[i].bytes, INV_EIGHT.bytes);
rct::addKeys2(V[i], gamma8, sv8, rct::H);
} }
PERF_TIMER_STOP(PROVE_v); PERF_TIMER_STOP(PROVE_v);
@ -843,10 +841,16 @@ try_again:
// PAPER LINES 47-48 // PAPER LINES 47-48
rct::key tau1 = rct::skGen(), tau2 = rct::skGen(); rct::key tau1 = rct::skGen(), tau2 = rct::skGen();
rct::key T1 = rct::addKeys(rct::scalarmultH(t1), rct::scalarmultBase(tau1)); rct::key T1, T2;
T1 = rct::scalarmultKey(T1, INV_EIGHT); ge_p3 p3;
rct::key T2 = rct::addKeys(rct::scalarmultH(t2), rct::scalarmultBase(tau2)); sc_mul(tmp.bytes, t1.bytes, INV_EIGHT.bytes);
T2 = rct::scalarmultKey(T2, INV_EIGHT); sc_mul(tmp2.bytes, tau1.bytes, INV_EIGHT.bytes);
ge_double_scalarmult_base_vartime_p3(&p3, tmp.bytes, &ge_p3_H, tmp2.bytes);
ge_p3_tobytes(T1.bytes, &p3);
sc_mul(tmp.bytes, t2.bytes, INV_EIGHT.bytes);
sc_mul(tmp2.bytes, tau2.bytes, INV_EIGHT.bytes);
ge_double_scalarmult_base_vartime_p3(&p3, tmp.bytes, &ge_p3_H, tmp2.bytes);
ge_p3_tobytes(T2.bytes, &p3);
// PAPER LINES 49-51 // PAPER LINES 49-51
rct::key x = hash_cache_mash(hash_cache, z, T1, T2); rct::key x = hash_cache_mash(hash_cache, z, T1, T2);
@ -972,7 +976,7 @@ try_again:
PERF_TIMER_STOP(PROVE_step4); PERF_TIMER_STOP(PROVE_step4);
// PAPER LINE 58 (with inclusions from PAPER LINE 8 and PAPER LINE 20) // PAPER LINE 58 (with inclusions from PAPER LINE 8 and PAPER LINE 20)
return Bulletproof(V, A, S, T1, T2, taux, mu, L, R, aprime[0], bprime[0], t); return Bulletproof(std::move(V), A, S, T1, T2, taux, mu, std::move(L), std::move(R), aprime[0], bprime[0], t);
} }
Bulletproof bulletproof_PROVE(const std::vector<uint64_t> &v, const rct::keyV &gamma) Bulletproof bulletproof_PROVE(const std::vector<uint64_t> &v, const rct::keyV &gamma)
@ -1034,10 +1038,10 @@ bool bulletproof_VERIFY(const std::vector<const Bulletproof*> &proofs)
// setup weighted aggregates // setup weighted aggregates
rct::key Z0 = rct::identity(); rct::key Z0 = rct::identity();
rct::key z1 = rct::zero(); rct::key z1 = rct::zero();
rct::key Z2 = rct::identity(); rct::key &Z2 = Z0;
rct::key z3 = rct::zero(); rct::key z3 = rct::zero();
rct::keyV z4(maxMN, rct::zero()), z5(maxMN, rct::zero()); rct::keyV z4(maxMN, rct::zero()), z5(maxMN, rct::zero());
rct::key Y2 = rct::identity(), Y3 = rct::identity(), Y4 = rct::identity(); rct::key Y2 = rct::identity(), &Y3 = Y2, &Y4 = Y2;
rct::key y0 = rct::zero(), y1 = rct::zero(); rct::key y0 = rct::zero(), y1 = rct::zero();
for (const Bulletproof *p: proofs) for (const Bulletproof *p: proofs)
{ {
@ -1224,11 +1228,8 @@ bool bulletproof_VERIFY(const std::vector<const Bulletproof*> &proofs)
// now check all proofs at once // now check all proofs at once
PERF_TIMER_START_BP(VERIFY_step2_check); PERF_TIMER_START_BP(VERIFY_step2_check);
ge_p3 check1; ge_p3 check1;
ge_scalarmult_base(&check1, y0.bytes); ge_double_scalarmult_base_vartime_p3(&check1, y1.bytes, &ge_p3_H, y0.bytes);
addKeys_acc_p3(&check1, y1, rct::H);
sub_acc_p3(&check1, Y2); sub_acc_p3(&check1, Y2);
sub_acc_p3(&check1, Y3);
sub_acc_p3(&check1, Y4);
if (!ge_p3_is_point_at_infinity(&check1)) if (!ge_p3_is_point_at_infinity(&check1))
{ {
MERROR("Verification failure at step 1"); MERROR("Verification failure at step 1");
@ -1238,18 +1239,15 @@ bool bulletproof_VERIFY(const std::vector<const Bulletproof*> &proofs)
sc_sub(tmp.bytes, rct::zero().bytes, z1.bytes); sc_sub(tmp.bytes, rct::zero().bytes, z1.bytes);
ge_double_scalarmult_base_vartime_p3(&check2, z3.bytes, &ge_p3_H, tmp.bytes); ge_double_scalarmult_base_vartime_p3(&check2, z3.bytes, &ge_p3_H, tmp.bytes);
add_acc_p3(&check2, Z0); add_acc_p3(&check2, Z0);
add_acc_p3(&check2, Z2);
std::vector<MultiexpData> multiexp_data; std::vector<MultiexpData> multiexp_data;
multiexp_data.reserve(2 * maxMN); multiexp_data.reserve(2 * maxMN);
for (size_t i = 0; i < maxMN; ++i) for (size_t i = 0; i < maxMN; ++i)
{ {
sc_sub(tmp.bytes, rct::zero().bytes, z4[i].bytes); multiexp_data.emplace_back(z4[i], Gi_p3[i]);
multiexp_data.emplace_back(tmp, Gi_p3[i]); multiexp_data.emplace_back(z5[i], Hi_p3[i]);
sc_sub(tmp.bytes, rct::zero().bytes, z5[i].bytes);
multiexp_data.emplace_back(tmp, Hi_p3[i]);
} }
add_acc_p3(&check2, multiexp(multiexp_data, true)); sub_acc_p3(&check2, multiexp(multiexp_data, true));
PERF_TIMER_STOP(VERIFY_step2_check); PERF_TIMER_STOP(VERIFY_step2_check);
if (!ge_p3_is_point_at_infinity(&check2)) if (!ge_p3_is_point_at_infinity(&check2))