store outPk/8 in the tx for speed

It avoids dividing by 8 when deserializing a tx, which is a slow
operation, and multiplies by 8 when verifying and extracing the
amount, which is much faster as well as less frequent
This commit is contained in:
moneromooo-monero 2021-02-14 17:45:04 +00:00 committed by wowario
parent e44b32c30c
commit 34884a4b00
5 changed files with 31 additions and 7 deletions

View file

@ -248,8 +248,15 @@ void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair
} }
else else
{ {
rct::key commitment;
if (tx.version > 1)
{
commitment = tx.rct_signatures.outPk[i].mask;
if (rct::is_rct_bulletproof_plus(tx.rct_signatures.type))
commitment = rct::scalarmult8(commitment);
}
amount_output_indices[i] = add_output(tx_hash, tx.vout[i], i, tx.unlock_time, amount_output_indices[i] = add_output(tx_hash, tx.vout[i], i, tx.unlock_time,
tx.version > 1 ? &tx.rct_signatures.outPk[i].mask : NULL); tx.version > 1 ? &commitment : NULL);
} }
} }
add_tx_amount_output_indices(tx_id, amount_output_indices); add_tx_amount_output_indices(tx_id, amount_output_indices);

View file

@ -187,7 +187,7 @@ namespace cryptonote
CHECK_AND_ASSERT_MES(n_amounts == rv.outPk.size(), false, "Internal error filling out V"); CHECK_AND_ASSERT_MES(n_amounts == rv.outPk.size(), false, "Internal error filling out V");
rv.p.bulletproofs_plus[0].V.resize(n_amounts); rv.p.bulletproofs_plus[0].V.resize(n_amounts);
for (size_t i = 0; i < n_amounts; ++i) for (size_t i = 0; i < n_amounts; ++i)
rv.p.bulletproofs_plus[0].V[i] = rct::scalarmultKey(rv.outPk[i].mask, rct::INV_EIGHT); rv.p.bulletproofs_plus[0].V[i] = rv.outPk[i].mask;
} }
const bool bulletproof = rct::is_rct_bulletproof(rv.type); const bool bulletproof = rct::is_rct_bulletproof(rv.type);
if (rct::is_rct_new_bulletproof(rv.type)) if (rct::is_rct_new_bulletproof(rv.type))

View file

@ -1276,7 +1276,7 @@ namespace rct {
rv.p.bulletproofs_plus.clear(); rv.p.bulletproofs_plus.clear();
if (bulletproof_or_plus) if (bulletproof_or_plus)
{ {
const bool plus = rv.type == RCTTypeBulletproofPlus; const bool plus = is_rct_bulletproof_plus(rv.type);
size_t n_amounts = outamounts.size(); size_t n_amounts = outamounts.size();
size_t amounts_proved = 0; size_t amounts_proved = 0;
if (rct_config.range_proof_type == RangeProofPaddedBulletproof) if (rct_config.range_proof_type == RangeProofPaddedBulletproof)
@ -1306,7 +1306,10 @@ namespace rct {
} }
for (i = 0; i < outamounts.size(); ++i) for (i = 0; i < outamounts.size(); ++i)
{ {
rv.outPk[i].mask = rct::scalarmult8(C[i]); if (plus)
rv.outPk[i].mask = C[i];
else
rv.outPk[i].mask = rct::scalarmult8(C[i]);
outSk[i].mask = masks[i]; outSk[i].mask = masks[i];
} }
} }
@ -1344,7 +1347,10 @@ namespace rct {
} }
for (i = 0; i < batch_size; ++i) for (i = 0; i < batch_size; ++i)
{ {
rv.outPk[i + amounts_proved].mask = rct::scalarmult8(C[i]); if (plus)
rv.outPk[i + amounts_proved].mask = C[i];
else
rv.outPk[i + amounts_proved].mask = rct::scalarmult8(C[i]);
outSk[i + amounts_proved].mask = masks[i]; outSk[i + amounts_proved].mask = masks[i];
} }
amounts_proved += batch_size; amounts_proved += batch_size;
@ -1665,7 +1671,10 @@ namespace rct {
rct::keyV masks(rv.outPk.size()); rct::keyV masks(rv.outPk.size());
for (size_t i = 0; i < rv.outPk.size(); i++) { for (size_t i = 0; i < rv.outPk.size(); i++) {
masks[i] = rv.outPk[i].mask; if (bulletproof_plus)
masks[i] = rct::scalarmult8(rv.outPk[i].mask);
else
masks[i] = rv.outPk[i].mask;
} }
key sumOutpks = addKeys(masks); key sumOutpks = addKeys(masks);
DP(sumOutpks); DP(sumOutpks);
@ -1823,6 +1832,8 @@ namespace rct {
mask = ecdh_info.mask; mask = ecdh_info.mask;
key amount = ecdh_info.amount; key amount = ecdh_info.amount;
key C = rv.outPk[i].mask; key C = rv.outPk[i].mask;
if (is_rct_bulletproof_plus(rv.type))
C = scalarmult8(C);
DP("C"); DP("C");
DP(C); DP(C);
key Ctmp; key Ctmp;
@ -1853,6 +1864,8 @@ namespace rct {
mask = ecdh_info.mask; mask = ecdh_info.mask;
key amount = ecdh_info.amount; key amount = ecdh_info.amount;
key C = rv.outPk[i].mask; key C = rv.outPk[i].mask;
if (is_rct_bulletproof_plus(rv.type))
C = scalarmult8(C);
DP("C"); DP("C");
DP(C); DP(C);
key Ctmp; key Ctmp;

View file

@ -11495,7 +11495,9 @@ void wallet2::check_tx_key_helper(const cryptonote::transaction &tx, const crypt
crypto::derivation_to_scalar(found_derivation, n, scalar1); crypto::derivation_to_scalar(found_derivation, n, scalar1);
rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n]; rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n];
rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1), tx.rct_signatures.type == rct::RCTTypeBulletproof2 || tx.rct_signatures.type == rct::RCTTypeCLSAG || tx.rct_signatures.type == rct::RCTTypeBulletproofPlus); rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1), tx.rct_signatures.type == rct::RCTTypeBulletproof2 || tx.rct_signatures.type == rct::RCTTypeCLSAG || tx.rct_signatures.type == rct::RCTTypeBulletproofPlus);
const rct::key C = tx.rct_signatures.outPk[n].mask; rct::key C = tx.rct_signatures.outPk[n].mask;
if (rct::is_rct_bulletproof_plus(tx.rct_signatures.type))
C = rct::scalarmult8(C);
rct::key Ctmp; rct::key Ctmp;
THROW_WALLET_EXCEPTION_IF(sc_check(ecdh_info.mask.bytes) != 0, error::wallet_internal_error, "Bad ECDH input mask"); THROW_WALLET_EXCEPTION_IF(sc_check(ecdh_info.mask.bytes) != 0, error::wallet_internal_error, "Bad ECDH input mask");
THROW_WALLET_EXCEPTION_IF(sc_check(ecdh_info.amount.bytes) != 0, error::wallet_internal_error, "Bad ECDH input amount"); THROW_WALLET_EXCEPTION_IF(sc_check(ecdh_info.amount.bytes) != 0, error::wallet_internal_error, "Bad ECDH input amount");

View file

@ -460,6 +460,8 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry
rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n]; rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n];
rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1), tx.rct_signatures.type == rct::RCTTypeBulletproof2 || tx.rct_signatures.type == rct::RCTTypeCLSAG || tx.rct_signatures.type == rct::RCTTypeBulletproofPlus); rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1), tx.rct_signatures.type == rct::RCTTypeBulletproof2 || tx.rct_signatures.type == rct::RCTTypeCLSAG || tx.rct_signatures.type == rct::RCTTypeBulletproofPlus);
rct::key C = tx.rct_signatures.outPk[n].mask; rct::key C = tx.rct_signatures.outPk[n].mask;
if (rct::is_rct_bulletproof_plus(tx.rct_signatures.type))
C = rct::scalarmult8(C);
rct::addKeys2(Ctmp, ecdh_info.mask, ecdh_info.amount, rct::H); rct::addKeys2(Ctmp, ecdh_info.mask, ecdh_info.amount, rct::H);
CHECK_AND_ASSERT_MES(rct::equalKeys(C, Ctmp), false, "Failed to decode amount"); CHECK_AND_ASSERT_MES(rct::equalKeys(C, Ctmp), false, "Failed to decode amount");
amount += rct::h2d(ecdh_info.amount); amount += rct::h2d(ecdh_info.amount);