mirror of
https://github.com/monero-project/monero.git
synced 2024-12-23 12:09:54 +00:00
bulletproofs: a few fixes from the Kudelski review
- fix integer overflow in n_bulletproof_amounts - check input scalars are in range - remove use of environment variable to tweak straus performance - do not use implementation defined signed shift for signum
This commit is contained in:
parent
c429176248
commit
869b3bf824
4 changed files with 23 additions and 15 deletions
|
@ -3707,9 +3707,8 @@ void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b,
|
||||||
s[31] = s11 >> 17;
|
s[31] = s11 >> 17;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assumes that a != INT64_MIN */
|
|
||||||
static int64_t signum(int64_t a) {
|
static int64_t signum(int64_t a) {
|
||||||
return (a >> 63) - ((-a) >> 63);
|
return a > 0 ? 1 : a < 0 ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sc_check(const unsigned char *s) {
|
int sc_check(const unsigned char *s) {
|
||||||
|
|
|
@ -74,14 +74,20 @@ static boost::mutex init_mutex;
|
||||||
|
|
||||||
static inline rct::key multiexp(const std::vector<MultiexpData> &data, bool HiGi)
|
static inline rct::key multiexp(const std::vector<MultiexpData> &data, bool HiGi)
|
||||||
{
|
{
|
||||||
static const size_t STEP = getenv("STRAUS_STEP") ? atoi(getenv("STRAUS_STEP")) : 0;
|
|
||||||
if (HiGi)
|
if (HiGi)
|
||||||
{
|
{
|
||||||
static_assert(128 <= STRAUS_SIZE_LIMIT, "Straus in precalc mode can only be calculated till STRAUS_SIZE_LIMIT");
|
static_assert(128 <= STRAUS_SIZE_LIMIT, "Straus in precalc mode can only be calculated till STRAUS_SIZE_LIMIT");
|
||||||
return data.size() <= 128 ? straus(data, straus_HiGi_cache, STEP) : pippenger(data, pippenger_HiGi_cache, get_pippenger_c(data.size()));
|
return data.size() <= 128 ? straus(data, straus_HiGi_cache, 0) : pippenger(data, pippenger_HiGi_cache, get_pippenger_c(data.size()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return data.size() <= 64 ? straus(data, NULL, STEP) : pippenger(data, NULL, get_pippenger_c(data.size()));
|
return data.size() <= 64 ? straus(data, NULL, 0) : pippenger(data, NULL, get_pippenger_c(data.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_reduced(const rct::key &scalar)
|
||||||
|
{
|
||||||
|
rct::key reduced = scalar;
|
||||||
|
sc_reduce32(reduced.bytes);
|
||||||
|
return scalar == reduced;
|
||||||
}
|
}
|
||||||
|
|
||||||
//addKeys3acc_p3
|
//addKeys3acc_p3
|
||||||
|
@ -659,6 +665,10 @@ Bulletproof bulletproof_PROVE(const rct::keyV &sv, const rct::keyV &gamma)
|
||||||
{
|
{
|
||||||
CHECK_AND_ASSERT_THROW_MES(sv.size() == gamma.size(), "Incompatible sizes of sv and gamma");
|
CHECK_AND_ASSERT_THROW_MES(sv.size() == gamma.size(), "Incompatible sizes of sv and gamma");
|
||||||
CHECK_AND_ASSERT_THROW_MES(!sv.empty(), "sv is empty");
|
CHECK_AND_ASSERT_THROW_MES(!sv.empty(), "sv is empty");
|
||||||
|
for (const rct::key &sve: sv)
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(is_reduced(sve), "Invalid sv input");
|
||||||
|
for (const rct::key &g: gamma)
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(is_reduced(g), "Invalid gamma input");
|
||||||
|
|
||||||
init_exponents();
|
init_exponents();
|
||||||
|
|
||||||
|
@ -935,6 +945,13 @@ bool bulletproof_VERIFY(const std::vector<const Bulletproof*> &proofs)
|
||||||
CHECK_AND_ASSERT_MES(rct::isInMainSubgroup(proof.T1), false, "Input point not in subgroup");
|
CHECK_AND_ASSERT_MES(rct::isInMainSubgroup(proof.T1), false, "Input point not in subgroup");
|
||||||
CHECK_AND_ASSERT_MES(rct::isInMainSubgroup(proof.T2), false, "Input point not in subgroup");
|
CHECK_AND_ASSERT_MES(rct::isInMainSubgroup(proof.T2), false, "Input point not in subgroup");
|
||||||
|
|
||||||
|
// check scalar range
|
||||||
|
CHECK_AND_ASSERT_MES(is_reduced(proof.taux), false, "Input scalar not in range");
|
||||||
|
CHECK_AND_ASSERT_MES(is_reduced(proof.mu), false, "Input scalar not in range");
|
||||||
|
CHECK_AND_ASSERT_MES(is_reduced(proof.a), false, "Input scalar not in range");
|
||||||
|
CHECK_AND_ASSERT_MES(is_reduced(proof.b), false, "Input scalar not in range");
|
||||||
|
CHECK_AND_ASSERT_MES(is_reduced(proof.t), false, "Input scalar not in range");
|
||||||
|
|
||||||
CHECK_AND_ASSERT_MES(proof.V.size() >= 1, false, "V does not have at least one element");
|
CHECK_AND_ASSERT_MES(proof.V.size() >= 1, false, "V does not have at least 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");
|
||||||
|
|
|
@ -236,6 +236,7 @@ namespace rct {
|
||||||
size_t n_bulletproof_amounts(const Bulletproof &proof)
|
size_t n_bulletproof_amounts(const Bulletproof &proof)
|
||||||
{
|
{
|
||||||
CHECK_AND_ASSERT_MES(proof.L.size() >= 6, 0, "Invalid bulletproof L size");
|
CHECK_AND_ASSERT_MES(proof.L.size() >= 6, 0, "Invalid bulletproof L size");
|
||||||
|
CHECK_AND_ASSERT_MES(proof.L.size() <= 31, 0, "Insane bulletproof L size");
|
||||||
return 1 << (proof.L.size() - 6);
|
return 1 << (proof.L.size() - 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,6 +246,7 @@ namespace rct {
|
||||||
for (const Bulletproof &proof: proofs)
|
for (const Bulletproof &proof: proofs)
|
||||||
{
|
{
|
||||||
size_t n2 = n_bulletproof_amounts(proof);
|
size_t n2 = n_bulletproof_amounts(proof);
|
||||||
|
CHECK_AND_ASSERT_MES(n2 < std::numeric_limits<uint32_t>::max() - n, 0, "Invalid number of bulletproofs");
|
||||||
if (n2 == 0)
|
if (n2 == 0)
|
||||||
return 0;
|
return 0;
|
||||||
n += n2;
|
n += n2;
|
||||||
|
|
|
@ -185,16 +185,6 @@ TEST(bulletproofs, invalid_gamma_0)
|
||||||
ASSERT_FALSE(rct::bulletproof_VERIFY(proof));
|
ASSERT_FALSE(rct::bulletproof_VERIFY(proof));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(bulletproofs, invalid_gamma_ff)
|
|
||||||
{
|
|
||||||
rct::key invalid_amount = rct::zero();
|
|
||||||
invalid_amount[8] = 1;
|
|
||||||
rct::key gamma = rct::zero();
|
|
||||||
memset(&gamma, 0xff, sizeof(gamma));
|
|
||||||
rct::Bulletproof proof = bulletproof_PROVE(invalid_amount, gamma);
|
|
||||||
ASSERT_FALSE(rct::bulletproof_VERIFY(proof));
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char * const torsion_elements[] =
|
static const char * const torsion_elements[] =
|
||||||
{
|
{
|
||||||
"c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa",
|
"c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa",
|
||||||
|
|
Loading…
Reference in a new issue