bulletproofs: more robust challenge computation

Changes from sarang, from a recommendation by an anonymous reviewer
This commit is contained in:
moneromooo-monero 2017-12-18 21:58:45 +00:00
parent ed67e5c001
commit 3f1a3fac00
No known key found for this signature in database
GPG Key ID: 686F07454D6CEFC3

View File

@ -297,6 +297,39 @@ static rct::keyV slice(const rct::keyV &a, size_t start, size_t stop)
return res; return res;
} }
static rct::key hash_cache_mash(rct::key &hash_cache, const rct::key &mash0, const rct::key &mash1)
{
rct::keyV data;
data.reserve(3);
data.push_back(hash_cache);
data.push_back(mash0);
data.push_back(mash1);
return hash_cache = rct::hash_to_scalar(data);
}
static rct::key hash_cache_mash(rct::key &hash_cache, const rct::key &mash0, const rct::key &mash1, const rct::key &mash2)
{
rct::keyV data;
data.reserve(4);
data.push_back(hash_cache);
data.push_back(mash0);
data.push_back(mash1);
data.push_back(mash2);
return hash_cache = rct::hash_to_scalar(data);
}
static rct::key hash_cache_mash(rct::key &hash_cache, const rct::key &mash0, const rct::key &mash1, const rct::key &mash2, const rct::key &mash3)
{
rct::keyV data;
data.reserve(5);
data.push_back(hash_cache);
data.push_back(mash0);
data.push_back(mash1);
data.push_back(mash2);
data.push_back(mash3);
return hash_cache = rct::hash_to_scalar(data);
}
/* Given a value v (0..2^N-1) and a mask gamma, construct a range proof */ /* Given a value v (0..2^N-1) and a mask gamma, construct a range proof */
Bulletproof bulletproof_PROVE(const rct::key &sv, const rct::key &gamma) Bulletproof bulletproof_PROVE(const rct::key &sv, const rct::key &gamma)
{ {
@ -329,6 +362,7 @@ Bulletproof bulletproof_PROVE(const rct::key &sv, const rct::key &gamma)
} }
PERF_TIMER_STOP(PROVE_aLaR); PERF_TIMER_STOP(PROVE_aLaR);
rct::key hash_cache = rct::hash_to_scalar(V);
// DEBUG: Test to ensure this recovers the value // DEBUG: Test to ensure this recovers the value
#ifdef DEBUG_BP #ifdef DEBUG_BP
@ -361,11 +395,8 @@ Bulletproof bulletproof_PROVE(const rct::key &sv, const rct::key &gamma)
rct::addKeys(S, ve, rct::scalarmultBase(rho)); rct::addKeys(S, ve, rct::scalarmultBase(rho));
// PAPER LINES 43-45 // PAPER LINES 43-45
rct::keyV hashed; rct::key y = hash_cache_mash(hash_cache, A, S);
hashed.push_back(A); rct::key z = hash_cache = rct::hash_to_scalar(y);
hashed.push_back(S);
rct::key y = rct::hash_to_scalar(hashed);
rct::key z = rct::hash_to_scalar(y);
// Polynomial construction before PAPER LINE 46 // Polynomial construction before PAPER LINE 46
rct::key t0 = rct::zero(); rct::key t0 = rct::zero();
@ -427,11 +458,7 @@ Bulletproof bulletproof_PROVE(const rct::key &sv, const rct::key &gamma)
rct::key T2 = rct::addKeys(rct::scalarmultKey(rct::H, t2), rct::scalarmultBase(tau2)); rct::key T2 = rct::addKeys(rct::scalarmultKey(rct::H, t2), rct::scalarmultBase(tau2));
// PAPER LINES 49-51 // PAPER LINES 49-51
hashed.clear(); rct::key x = hash_cache_mash(hash_cache, z, T1, T2);
hashed.push_back(z);
hashed.push_back(T1);
hashed.push_back(T2);
rct::key x = rct::hash_to_scalar(hashed);
// PAPER LINES 52-53 // PAPER LINES 52-53
rct::key taux = rct::zero(); rct::key taux = rct::zero();
@ -460,12 +487,7 @@ Bulletproof bulletproof_PROVE(const rct::key &sv, const rct::key &gamma)
#endif #endif
// PAPER LINES 32-33 // PAPER LINES 32-33
hashed.clear(); rct::key x_ip = hash_cache_mash(hash_cache, x, taux, mu, t);
hashed.push_back(x);
hashed.push_back(taux);
hashed.push_back(mu);
hashed.push_back(t);
rct::key x_ip = rct::hash_to_scalar(hashed);
// These are used in the inner product rounds // These are used in the inner product rounds
size_t nprime = N; size_t nprime = N;
@ -509,20 +531,7 @@ Bulletproof bulletproof_PROVE(const rct::key &sv, const rct::key &gamma)
rct::addKeys(R[round], R[round], rct::scalarmultKey(rct::H, tmp)); rct::addKeys(R[round], R[round], rct::scalarmultKey(rct::H, tmp));
// PAPER LINES 21-22 // PAPER LINES 21-22
hashed.clear(); w[round] = hash_cache_mash(hash_cache, L[round], R[round]);
if (round == 0)
{
hashed.push_back(L[0]);
hashed.push_back(R[0]);
w[0] = rct::hash_to_scalar(hashed);
}
else
{
hashed.push_back(w[round - 1]);
hashed.push_back(L[round]);
hashed.push_back(R[round]);
w[round] = rct::hash_to_scalar(hashed);
}
// PAPER LINES 24-25 // PAPER LINES 24-25
const rct::key winv = invert(w[round]); const rct::key winv = invert(w[round]);
@ -563,6 +572,7 @@ bool bulletproof_VERIFY(const Bulletproof &proof)
{ {
init_exponents(); init_exponents();
CHECK_AND_ASSERT_MES(proof.V.size() == 1, false, "V does not have exactly one element");
CHECK_AND_ASSERT_MES(proof.L.size() == proof.R.size(), false, "Mismatched L and R sizes"); CHECK_AND_ASSERT_MES(proof.L.size() == proof.R.size(), false, "Mismatched L and R sizes");
CHECK_AND_ASSERT_MES(proof.L.size() > 0, false, "Empty proof"); CHECK_AND_ASSERT_MES(proof.L.size() > 0, false, "Empty proof");
CHECK_AND_ASSERT_MES(proof.L.size() == 6, false, "Proof is not for 64 bits"); CHECK_AND_ASSERT_MES(proof.L.size() == 6, false, "Proof is not for 64 bits");
@ -573,26 +583,15 @@ bool bulletproof_VERIFY(const Bulletproof &proof)
// Reconstruct the challenges // Reconstruct the challenges
PERF_TIMER_START_BP(VERIFY); PERF_TIMER_START_BP(VERIFY);
PERF_TIMER_START_BP(VERIFY_start); PERF_TIMER_START_BP(VERIFY_start);
rct::keyV hashed; rct::key hash_cache = rct::hash_to_scalar(proof.V[0]);
hashed.push_back(proof.A); rct::key y = hash_cache_mash(hash_cache, proof.A, proof.S);
hashed.push_back(proof.S); rct::key z = hash_cache = rct::hash_to_scalar(y);
rct::key y = rct::hash_to_scalar(hashed); rct::key x = hash_cache_mash(hash_cache, z, proof.T1, proof.T2);
rct::key z = rct::hash_to_scalar(y);
hashed.clear();
hashed.push_back(z);
hashed.push_back(proof.T1);
hashed.push_back(proof.T2);
rct::key x = rct::hash_to_scalar(hashed);
PERF_TIMER_STOP(VERIFY_start); PERF_TIMER_STOP(VERIFY_start);
PERF_TIMER_START_BP(VERIFY_line_60); PERF_TIMER_START_BP(VERIFY_line_60);
// Reconstruct the challenges // Reconstruct the challenges
hashed.clear(); rct::key x_ip = hash_cache_mash(hash_cache, x, proof.taux, proof.mu, proof.t);
hashed.push_back(x);
hashed.push_back(proof.taux);
hashed.push_back(proof.mu);
hashed.push_back(proof.t);
rct::key x_ip = hash_to_scalar(hashed);
PERF_TIMER_STOP(VERIFY_line_60); PERF_TIMER_STOP(VERIFY_line_60);
PERF_TIMER_START_BP(VERIFY_line_61); PERF_TIMER_START_BP(VERIFY_line_61);
@ -647,17 +646,9 @@ bool bulletproof_VERIFY(const Bulletproof &proof)
// PAPER LINES 21-22 // PAPER LINES 21-22
// The inner product challenges are computed per round // The inner product challenges are computed per round
rct::keyV w(rounds); rct::keyV w(rounds);
hashed.clear(); for (size_t i = 0; i < rounds; ++i)
hashed.push_back(proof.L[0]);
hashed.push_back(proof.R[0]);
w[0] = rct::hash_to_scalar(hashed);
for (size_t i = 1; i < rounds; ++i)
{ {
hashed.clear(); w[i] = hash_cache_mash(hash_cache, proof.L[i], proof.R[i]);
hashed.push_back(w[i-1]);
hashed.push_back(proof.L[i]);
hashed.push_back(proof.R[i]);
w[i] = rct::hash_to_scalar(hashed);
} }
PERF_TIMER_STOP(VERIFY_line_21_22); PERF_TIMER_STOP(VERIFY_line_21_22);