Skip to content

Commit

Permalink
Fixed comparison of numbers of different bit length.
Browse files Browse the repository at this point in the history
  • Loading branch information
martun committed Jul 16, 2024
1 parent 4e3ea86 commit 93edae7
Show file tree
Hide file tree
Showing 14 changed files with 115 additions and 2,420 deletions.
2 changes: 0 additions & 2 deletions libs/algebra/test/curves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@
#include <nil/crypto3/algebra/fields/fp2.hpp>
#include <nil/crypto3/algebra/fields/fp3.hpp>

#include <nil/crypto3/algebra/random_element.hpp>

#include <nil/crypto3/multiprecision/cpp_int_modular.hpp>

using namespace nil::crypto3::algebra;
Expand Down
1 change: 0 additions & 1 deletion libs/algebra/test/fields.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
#include <nil/crypto3/algebra/fields/secp/secp_k1/scalar_field.hpp>
#include <nil/crypto3/algebra/fields/secp/secp_r1/base_field.hpp>
#include <nil/crypto3/algebra/fields/secp/secp_r1/scalar_field.hpp>
#include <nil/crypto3/algebra/random_element.hpp>

#include <nil/crypto3/algebra/fields/curve25519/base_field.hpp>
#include <nil/crypto3/algebra/fields/curve25519/scalar_field.hpp>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ namespace boost {
const cpp_int_modular_backend<Bits2>& b) noexcept {
for (int i = b.size() - 1; i > a.size() - 1 ; --i) {
if (b.limbs()[i] != 0)
return false;
return true;
}
for (int i = a.size() - 1; i > b.size() - 1 ; --i) {
if (a.limbs()[i] != 0)
return true;
return false;
}
for (int i = std::min(a.size() - 1, b.size() - 1); i >= 0; --i) {
if (a.limbs()[i] != b.limbs()[i])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ namespace boost {
struct is_backend<boost::multiprecision::backends::modular_adaptor<Backend, StorageType>> {
static BOOST_MP_CXX14_CONSTEXPR bool value = true;
};

// If boost wants to convert one cpp_int_modular_backend to another for comparison, make it convert the
// shorter one to the longer by adding zeros, not cut the longer one.
template <unsigned Bits1, unsigned Bits2>
struct is_first_backend_imp<true, boost::multiprecision::backends::cpp_int_modular_backend<Bits1>,
boost::multiprecision::backends::cpp_int_modular_backend<Bits2>>
: public std::integral_constant < bool, Bits1 >= Bits2> {};

} // namespace detail
} // multiprecision
} // namespace boost
Expand Down
30 changes: 1 addition & 29 deletions libs/multiprecision/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,13 @@
# http://www.boost.org/LICENSE_1_0.txt
#---------------------------------------------------------------------------#

#add_custom_target(${CURRENT_PROJECT_NAME}_test_suite_arithmetic_tests)
#add_custom_target(${CURRENT_PROJECT_NAME}_test_suite_functions_and_limits)
#add_custom_target(${CURRENT_PROJECT_NAME}_test_suite_conversions)
#add_custom_target(${CURRENT_PROJECT_NAME}_test_suite_cpp_int_tests)
add_custom_target(${CURRENT_PROJECT_NAME}_test_suite_modular_cpp_int_tests)
#add_custom_target(${CURRENT_PROJECT_NAME}_test_suite_misc)
#add_custom_target(${CURRENT_PROJECT_NAME}_test_suite_specfun)
#add_custom_target(${CURRENT_PROJECT_NAME}_test_suite_concepts)
#add_custom_target(${CURRENT_PROJECT_NAME}_test_suite_examples)
#add_custom_target(${CURRENT_PROJECT_NAME}_test_suite_compile_fail)

cm_test_link_libraries(
${CMAKE_WORKSPACE_NAME}_${CURRENT_PROJECT_NAME}
Boost::unit_test_framework
)

# HACK: Workaround broken includes
file(GLOB TEST_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/*.ipp)
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
foreach(HEADER ${TEST_HEADERS})
configure_file(${HEADER} ${CMAKE_CURRENT_BINARY_DIR}/libs/${CURRENT_PROJECT_NAME}/test/${HEADER}
@ONLY)
endforeach()

add_library(${CURRENT_PROJECT_NAME}_test_settings INTERFACE)
target_include_directories(${CURRENT_PROJECT_NAME}_test_settings INTERFACE ${CURRENT_TEST_SOURCES_DIR}/include)
cm_test_link_libraries(${CURRENT_PROJECT_NAME}_test_settings)

if(EIGEN_FOUND)
try_compile(EIGEN_COMPILED ${CMAKE_BINARY_DIR} ${CURRENT_TEST_SOURCES_DIR}/../config/has_eigen.cpp
CMAKE_FLAGS "-DCMAKE_CXX_LINK_EXECUTABLE='echo not linking now...'" "-DINCLUDE_DIRECTORIES=${EIGEN3_INCLUDE_DIRS}")
endif()

# TODO: figure out if it is needed
# add_library(no_eh_support SHARED ${CURRENT_TEST_SOURCES_DIR}/no_eh_test_support.cpp)

macro(define_runtime_multiprecision_test name)
set(test_name "${CURRENT_PROJECT_NAME}_${name}_test")

Expand Down Expand Up @@ -81,6 +52,7 @@ set(RUNTIME_TESTS_NAMES
"inverse"
"jacobi"
"ressol"
"arithmetic_non_matching_bitlength_numbers"
)

set(MODULAR_TESTS_NAMES
Expand Down
102 changes: 102 additions & 0 deletions libs/multiprecision/test/arithmetic_non_matching_bitlength_numbers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2024 Martun Karapetyan <martun@nil.foundation>
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//---------------------------------------------------------------------------//

#define BOOST_TEST_MODULE NON_MATCHING_BITLENGTH_NUMBERS_TESTS

// Suddenly, BOOST_MP_ASSERT is NOT constexpr, and it is used in constexpr functions throughout the boost, resulting to compilation errors on all compilers in debug mode. We need to switch assertions off inside cpp_int to make this code compile in debug mode. So we use this workaround to turn off file 'boost/multiprecision/detail/assert.hpp' which contains definition of BOOST_MP_ASSERT and BOOST_MP_ASSERT_MSG.
#ifndef BOOST_MP_DETAIL_ASSERT_HPP
#define BOOST_MP_DETAIL_ASSERT_HPP
#define BOOST_MP_ASSERT(expr) ((void)0)
#define BOOST_MP_ASSERT_MSG(expr, msg) ((void)0)
#endif

#include <boost/test/unit_test.hpp>

#include <chrono>
#include <iostream>
#include <vector>

#include <boost/random/random_device.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/mersenne_twister.hpp>

// We need cpp_int to compare to it.
#include <boost/multiprecision/cpp_int.hpp>

#include <nil/crypto3/multiprecision/cpp_int_modular.hpp>
#include <nil/crypto3/multiprecision/cpp_int_modular/literals.hpp>
#include <nil/crypto3/multiprecision/cpp_modular.hpp>
#include <nil/crypto3/multiprecision/inverse.hpp>

using namespace boost::multiprecision;

using boost::multiprecision::backends::cpp_int_modular_backend;

// This test case uses normal boost::cpp_int for comparison to our cpp_int_modular_backend.
template<unsigned Bits1, unsigned Bits2>
void value_comparisons_tests(const number<cpp_int_modular_backend<Bits1>>& a,
const number<cpp_int_modular_backend<Bits2>>& b) {

typedef cpp_int_modular_backend<Bits1> Backend1;
typedef cpp_int_modular_backend<Bits2> Backend2;
typedef cpp_int_modular_backend<Bits1 + Bits2> Backend_large;
typedef typename Backend1::cpp_int_type CppIntBackend1;
typedef typename Backend2::cpp_int_type CppIntBackend2;
typedef typename Backend_large::cpp_int_type CppIntBackend_large;

typedef boost::multiprecision::number<CppIntBackend1> cpp_int_number1;
typedef boost::multiprecision::number<CppIntBackend2> cpp_int_number2;
typedef boost::multiprecision::number<CppIntBackend_large> cpp_int_number_large;

// Convert from cpp_int_modular_backend to cpp_int_backend numbers.
cpp_int_number1 a_cppint = a.backend().to_cpp_int();
cpp_int_number2 b_cppint = b.backend().to_cpp_int();

BOOST_ASSERT_MSG((a > b) == (a_cppint > b_cppint), "g error");
BOOST_ASSERT_MSG((a >= b) == (a_cppint >= b_cppint), "ge error");
BOOST_ASSERT_MSG((a == b) == (a_cppint == b_cppint), "e error");
BOOST_ASSERT_MSG((a < b) == (a_cppint < b_cppint), "l error");
BOOST_ASSERT_MSG((a <= b) == (a_cppint <= b_cppint), "le error");
BOOST_ASSERT_MSG((a != b) == (a_cppint != b_cppint), "ne error");
}

template<unsigned Bits1, unsigned Bits2>
void value_comparisons_tests(const std::size_t N) {
using Backend1 = cpp_int_modular_backend<130>;
using Backend2 = cpp_int_modular_backend<260>;
using standard_number1 = boost::multiprecision::number<Backend1>;
using standard_number2 = boost::multiprecision::number<Backend2>;

int seed = 0;
boost::random::mt19937 gen(seed);
boost::random::uniform_int_distribution<standard_number1> d1(0, ~standard_number1(0u));
boost::random::uniform_int_distribution<standard_number2> d2(0, ~standard_number2(0u));

for (std::size_t i = 0; i < N; ++i) {
standard_number1 a = d1(gen);
standard_number2 b = d2(gen);
value_comparisons_tests(a, b);
}
}


BOOST_AUTO_TEST_SUITE(static_tests)

BOOST_AUTO_TEST_CASE(base_test_backend_12_17) {
value_comparisons_tests<12, 17>(1000);
}

BOOST_AUTO_TEST_CASE(base_test_backend_130_260) {
value_comparisons_tests<260, 130>(1000);
}

BOOST_AUTO_TEST_CASE(base_test_backend_128_256) {
value_comparisons_tests<128, 256>(1000);
}

BOOST_AUTO_TEST_SUITE_END()
2 changes: 0 additions & 2 deletions libs/multiprecision/test/modular_adaptor_fixed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
#endif

#include <boost/test/unit_test.hpp>
#include <boost/test/data/test_case.hpp>
#include <boost/test/data/monomorphic.hpp>

#include <chrono>
#include <iostream>
Expand Down
Loading

0 comments on commit 93edae7

Please sign in to comment.