diff --git a/src/ringct/bulletproofs_plus.cc b/src/ringct/bulletproofs_plus.cc index e181b30a9..f53820173 100644 --- a/src/ringct/bulletproofs_plus.cc +++ b/src/ringct/bulletproofs_plus.cc @@ -68,17 +68,16 @@ namespace rct static constexpr size_t maxM = BULLETPROOF_PLUS_MAX_OUTPUTS; // maximum number of outputs to aggregate into a single proof // Cached public generators - static rct::key Hi[maxN*maxM], Gi[maxN*maxM]; static ge_p3 Hi_p3[maxN*maxM], Gi_p3[maxN*maxM]; static std::shared_ptr straus_HiGi_cache; static std::shared_ptr pippenger_HiGi_cache; // Useful scalar constants - static const rct::key ZERO = { {0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 } }; // 0 - static const rct::key ONE = { {0x01, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 } }; // 1 - static const rct::key TWO = { {0x02, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 } }; // 2 - static const rct::key MINUS_ONE = { { 0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 } }; // -1 - static const rct::key MINUS_INV_EIGHT = { { 0x74, 0xa4, 0x19, 0x7a, 0xf0, 0x7d, 0x0b, 0xf7, 0x05, 0xc2, 0xda, 0x25, 0x2b, 0x5c, 0x0b, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a } }; // -(8**(-1)) + static const constexpr rct::key ZERO = { {0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 } }; // 0 + static const constexpr rct::key ONE = { {0x01, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 } }; // 1 + static const constexpr rct::key TWO = { {0x02, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 } }; // 2 + static const constexpr rct::key MINUS_ONE = { { 0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 } }; // -1 + static const constexpr rct::key MINUS_INV_EIGHT = { { 0x74, 0xa4, 0x19, 0x7a, 0xf0, 0x7d, 0x0b, 0xf7, 0x05, 0xc2, 0xda, 0x25, 0x2b, 0x5c, 0x0b, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a } }; // -(8**(-1)) static rct::key TWO_SIXTY_FOUR_MINUS_ONE; // 2**64 - 1 // Initial transcript hash @@ -107,16 +106,15 @@ namespace rct } // Use hashed values to produce indexed public generators - static rct::key get_exponent(const rct::key &base, size_t idx) + static ge_p3 get_exponent(const rct::key &base, size_t idx) { - static const std::string domain_separator(config::HASH_KEY_BULLETPROOF_PLUS_EXPONENT); - std::string hashed = std::string((const char*)base.bytes, sizeof(base)) + domain_separator + tools::get_varint_data(idx); + std::string hashed = std::string((const char*)base.bytes, sizeof(base)) + config::HASH_KEY_BULLETPROOF_PLUS_EXPONENT + tools::get_varint_data(idx); rct::key generator; ge_p3 generator_p3; rct::hash_to_p3(generator_p3, rct::hash2rct(crypto::cn_fast_hash(hashed.data(), hashed.size()))); ge_p3_tobytes(generator.bytes, &generator_p3); CHECK_AND_ASSERT_THROW_MES(!(generator == rct::identity()), "Exponent is point at infinity"); - return generator; + return generator_p3; } // Construct public generators @@ -133,10 +131,8 @@ namespace rct data.reserve(maxN*maxM*2); for (size_t i = 0; i < maxN*maxM; ++i) { - Hi[i] = get_exponent(rct::H, i * 2); - CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&Hi_p3[i], Hi[i].bytes) == 0, "ge_frombytes_vartime failed"); - Gi[i] = get_exponent(rct::H, i * 2 + 1); - CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&Gi_p3[i], Gi[i].bytes) == 0, "ge_frombytes_vartime failed"); + Hi_p3[i] = get_exponent(rct::H, i * 2); + Gi_p3[i] = get_exponent(rct::H, i * 2 + 1); data.push_back({rct::zero(), Gi_p3[i]}); data.push_back({rct::zero(), Hi_p3[i]}); @@ -154,7 +150,7 @@ namespace rct sc_sub(TWO_SIXTY_FOUR_MINUS_ONE.bytes, TWO_SIXTY_FOUR_MINUS_ONE.bytes, ONE.bytes); // Generate the initial Fiat-Shamir transcript hash, which is constant across all proofs - static const std::string domain_separator(config::HASH_KEY_BULLETPROOF_PLUS_TRANSCRIPT); + const std::string domain_separator(config::HASH_KEY_BULLETPROOF_PLUS_TRANSCRIPT); ge_p3 initial_transcript_p3; rct::hash_to_p3(initial_transcript_p3, rct::hash2rct(crypto::cn_fast_hash(domain_separator.data(), domain_separator.size()))); ge_p3_tobytes(initial_transcript.bytes, &initial_transcript_p3); @@ -854,7 +850,8 @@ try_again: max_length = std::max(max_length, proof.L.size()); nV += proof.V.size(); - bp_plus_proof_data_t pd; + proof_data.push_back({}); + bp_plus_proof_data_t &pd = proof_data.back(); // Reconstruct the challenges rct::key transcript = copy(initial_transcript); @@ -891,7 +888,6 @@ try_again: to_invert.push_back(pd.challenges[j]); to_invert.push_back(pd.y); inv_offset += rounds + 1; - proof_data.push_back(pd); } CHECK_AND_ASSERT_MES(max_length < 32, false, "At least one proof is too large"); size_t maxMN = 1u << max_length; @@ -904,7 +900,8 @@ try_again: multiexp_data.reserve(nV + (2 * (max_logM + logN) + 3) * proofs.size() + 2 * maxMN); multiexp_data.resize(2 * maxMN); - const std::vector inverses = invert(to_invert); + const std::vector inverses = invert(std::move(to_invert)); + to_invert.clear(); // Weights and aggregates //