mirror of
https://github.com/wownero/wownero.git
synced 2026-10-17 07:31:35 +02:00
ringct: fuzz and harden Bulletproof verification
This commit is contained in:
@@ -837,6 +837,7 @@ bool bulletproof_VERIFY(const std::vector<const Bulletproof*> &proofs)
|
||||
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() <= maxM, false, "V has too many elements");
|
||||
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");
|
||||
|
||||
|
||||
@@ -827,6 +827,7 @@ try_again:
|
||||
CHECK_AND_ASSERT_MES(is_reduced(proof.d1), 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() <= maxM, false, "V has too many elements");
|
||||
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");
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -256,11 +256,8 @@ set_property(TARGET levin_fuzz_tests
|
||||
monero_add_minimal_executable(bulletproof_fuzz_tests bulletproof.cpp fuzzer.cpp)
|
||||
target_link_libraries(bulletproof_fuzz_tests
|
||||
PRIVATE
|
||||
common
|
||||
epee
|
||||
${Boost_THREAD_LIBRARY}
|
||||
${Boost_REGEX_LIBRARY}
|
||||
${Boost_PROGRAM_OPTIONS_LIBRARY}
|
||||
ringct
|
||||
serialization
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${EXTRA_LIBRARIES}
|
||||
$ENV{LIB_FUZZING_ENGINE})
|
||||
|
||||
@@ -27,17 +27,39 @@
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "include_base_utils.h"
|
||||
#include "file_io_utils.h"
|
||||
#include "cryptonote_basic/blobdatatype.h"
|
||||
#include "cryptonote_basic/cryptonote_basic.h"
|
||||
#include "cryptonote_basic/cryptonote_format_utils.h"
|
||||
#include "fuzzer.h"
|
||||
#include "ringct/bulletproofs.h"
|
||||
#include "serialization/binary_utils.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct fuzz_input
|
||||
{
|
||||
rct::keyV commitments;
|
||||
rct::Bulletproof proof;
|
||||
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
FIELD(commitments)
|
||||
FIELD(proof)
|
||||
END_SERIALIZE()
|
||||
};
|
||||
}
|
||||
|
||||
BEGIN_INIT_SIMPLE_FUZZER()
|
||||
END_INIT_SIMPLE_FUZZER()
|
||||
|
||||
BEGIN_SIMPLE_FUZZER()
|
||||
binary_archive<false> ba{{buf, len}};
|
||||
rct::Bulletproof proof{};
|
||||
::serialization::serialize(ba, proof);
|
||||
if (len > 4096)
|
||||
return 0;
|
||||
|
||||
fuzz_input input;
|
||||
const std::string blob{reinterpret_cast<const char*>(buf), len};
|
||||
if (!serialization::parse_binary(blob, input))
|
||||
return 0;
|
||||
|
||||
input.proof.V = std::move(input.commitments);
|
||||
rct::bulletproof_VERIFY(input.proof);
|
||||
END_SIMPLE_FUZZER()
|
||||
|
||||
@@ -77,6 +77,20 @@ TEST(bulletproofs, valid_multi_random)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(bulletproofs, invalid_too_many_outputs)
|
||||
{
|
||||
std::vector<uint64_t> amounts(16, 0);
|
||||
rct::keyV gamma(16);
|
||||
for (rct::key &mask: gamma)
|
||||
mask = rct::skGen();
|
||||
rct::Bulletproof proof = bulletproof_PROVE(amounts, gamma);
|
||||
ASSERT_TRUE(rct::bulletproof_VERIFY(proof));
|
||||
proof.V.push_back(proof.V.back());
|
||||
proof.L.push_back(proof.L.back());
|
||||
proof.R.push_back(proof.R.back());
|
||||
ASSERT_FALSE(rct::bulletproof_VERIFY(proof));
|
||||
}
|
||||
|
||||
TEST(bulletproofs, multi_splitting)
|
||||
{
|
||||
rct::ctkeyV sc, pc;
|
||||
|
||||
@@ -77,6 +77,20 @@ TEST(bulletproofs_plus, valid_multi_random)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(bulletproofs_plus, invalid_too_many_outputs)
|
||||
{
|
||||
std::vector<uint64_t> amounts(16, 0);
|
||||
rct::keyV gamma(16);
|
||||
for (rct::key &mask: gamma)
|
||||
mask = rct::skGen();
|
||||
rct::BulletproofPlus proof = bulletproof_plus_PROVE(amounts, gamma);
|
||||
ASSERT_TRUE(rct::bulletproof_plus_VERIFY(proof));
|
||||
proof.V.push_back(proof.V.back());
|
||||
proof.L.push_back(proof.L.back());
|
||||
proof.R.push_back(proof.R.back());
|
||||
ASSERT_FALSE(rct::bulletproof_plus_VERIFY(proof));
|
||||
}
|
||||
|
||||
TEST(bulletproofs_plus, valid_aggregated)
|
||||
{
|
||||
static const size_t N_PROOFS = 8;
|
||||
|
||||
Reference in New Issue
Block a user