Skip to content

Commit

Permalink
Initial commit fuzzing
Browse files Browse the repository at this point in the history
  • Loading branch information
ckormanyos committed Sep 26, 2024
1 parent 095856c commit f04bf9a
Show file tree
Hide file tree
Showing 6 changed files with 339 additions and 2 deletions.
49 changes: 49 additions & 0 deletions .github/workflows/wide_integer_fuzzing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# ------------------------------------------------------------------------------
# Copyright Christopher Kormanyos 2024.
# 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)
# ------------------------------------------------------------------------------

name: wide_integer_fuzzing
on:
push:
branches:
- '**'
pull_request:
schedule:
- cron: '15 2 * * *' # run at 2:15 AM UTC
jobs:
clang-fuzzing:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
tcase: [ add, div ]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: '0'
- name: update-tools
run: sudo apt install llvm lld
- name: clone-submods-bootstrap-headers-boost-develop
run: |
git clone -b develop --depth 1 https://github.com/boostorg/boost.git ../boost-root
cd ../boost-root
git submodule update --init tools
git submodule update --init libs/config
git submodule update --init libs/multiprecision
./bootstrap.sh
./b2 headers
- name: gcc-clang-native
run: |
grep BOOST_VERSION ../boost-root/boost/version.hpp
echo "compile and instrument fuzzing test"
clang++ -v
clang++ -g -O2 -fsanitize=fuzzer,address,undefined -I. -I../boost-root test/fuzzing/test_fuzzing_${{ matrix.tcase }}.cpp -o test_fuzzing_${{ matrix.tcase }}
echo "ls test_fuzzing_${{ matrix.tcase }}"
ls -la test_fuzzing_${{ matrix.tcase }}
./test_fuzzing_${{ matrix.tcase }} -max_total_time=180
127 changes: 127 additions & 0 deletions test/fuzzing/test_fuzzing_add.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright Christopher Kormanyos 2024.
// 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)
//

// cd /mnt/c/Users/ckorm/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer
// clang++ -g -O2 -fsanitize=fuzzer,address,undefined -I. -I/mnt/c/boost/boost_1_85_0 test/fuzzing/test_fuzzing_add.cpp -o test_fuzzing_add
// ./test_fuzzing_add -max_total_time=180

#include <math/wide_integer/uintwide_t.h>

#include <boost/multiprecision/cpp_int.hpp>

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <vector>

namespace fuzzing
{
using boost_uint_backend_type =
boost::multiprecision::cpp_int_backend<static_cast<unsigned>(UINT32_C(256)),
static_cast<unsigned>(UINT32_C(256)),
boost::multiprecision::unsigned_magnitude>;

using boost_uint_type = boost::multiprecision::number<boost_uint_backend_type,
boost::multiprecision::et_off>;

using local_uint_type = ::math::wide_integer::uint256_t;

auto eval_add(const std::uint8_t* data, std::size_t size) -> bool;
}

auto fuzzing::eval_add(const std::uint8_t* data, std::size_t size) -> bool
{
const std::size_t
max_size
{
static_cast<std::size_t>
(
std::numeric_limits<fuzzing::local_uint_type>::digits / 8
)
};

bool result_is_ok { true };

if((size > std::size_t { UINT8_C(1) }) && (size <= std::size_t { max_size * 2U }))
{
local_uint_type a_local { };
local_uint_type b_local { };

boost_uint_type a_boost { };
boost_uint_type b_boost { };

// Import data into their respective uintwide_t a and b values.
import_bits
(
a_local,
data,
data + std::size_t { size / 2U },
8U
);

import_bits
(
b_local,
data + std::size_t { size / 2U },
data + size,
8U
);

// Import data into their respective boost-based a and b values.
import_bits
(
a_boost,
data,
data + std::size_t { size / 2U },
8U
);

import_bits
(
b_boost,
data + std::size_t { size / 2U },
data + size,
8U
);

local_uint_type result_local { a_local + b_local };
boost_uint_type result_boost { a_boost + b_boost };

std::vector<std::uint8_t> result_data_local(max_size, UINT8_C(0));
std::vector<std::uint8_t> result_data_boost(result_data_local.size(), UINT8_C(0));

export_bits(result_local, result_data_local.data(), 8U);
export_bits(result_boost, result_data_boost.data(), 8U);

// Verify that both uintwide_t as well as boost obtain the same result.
const bool result_add_is_ok =
std::equal
(
result_data_local.cbegin(),
result_data_local.cend(),
result_data_boost.cbegin(),
result_data_boost.cend()
);

result_is_ok = (result_add_is_ok && result_is_ok);
}

// Assert the correct result.
assert(result_is_ok);

return result_is_ok;
}

// The fuzzing entry point.
extern "C"
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
const bool result_one_add_is_ok { fuzzing::eval_add(data, size) };

return (result_one_add_is_ok ? 0 : -1);
}
136 changes: 136 additions & 0 deletions test/fuzzing/test_fuzzing_div.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright Christopher Kormanyos 2024.
// 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)
//

// cd /mnt/c/Users/ckorm/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer
// clang++ -g -O2 -fsanitize=fuzzer,address,undefined -I. -I/mnt/c/boost/boost_1_85_0 test/fuzzing/test_fuzzing_div.cpp -o test_fuzzing_div
// ./test_fuzzing_div -max_total_time=180

#include <math/wide_integer/uintwide_t.h>

#include <boost/multiprecision/cpp_int.hpp>

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <vector>

namespace fuzzing
{
using boost_uint_backend_type =
boost::multiprecision::cpp_int_backend<static_cast<unsigned>(UINT32_C(256)),
static_cast<unsigned>(UINT32_C(256)),
boost::multiprecision::unsigned_magnitude>;

using boost_uint_type = boost::multiprecision::number<boost_uint_backend_type,
boost::multiprecision::et_off>;

using local_uint_type = ::math::wide_integer::uint256_t;

auto eval_div(const std::uint8_t* data, std::size_t size) -> bool;
}

auto fuzzing::eval_div(const std::uint8_t* data, std::size_t size) -> bool
{
const std::size_t
max_size
{
static_cast<std::size_t>
(
std::numeric_limits<fuzzing::local_uint_type>::digits / 8
)
};

bool result_is_ok { true };

if((size > std::size_t { UINT8_C(1) }) && (size <= std::size_t { max_size * 2U }))
{
local_uint_type a_local { };
local_uint_type b_local { };

boost_uint_type a_boost { };
boost_uint_type b_boost { };

// Import data into their respective uintwide_t a and b values.
import_bits
(
a_local,
data,
data + std::size_t { size / 2U },
8U
);

import_bits
(
b_local,
data + std::size_t { size / 2U },
data + size,
8U
);

// Import data into their respective boost-based a and b values.
import_bits
(
a_boost,
data,
data + std::size_t { size / 2U },
8U
);

import_bits
(
b_boost,
data + std::size_t { size / 2U },
data + size,
8U
);

if(a_local < b_local)
{
std::swap(a_local, b_local);
std::swap(a_boost, b_boost);
}

if(b_local != 0U)
{
local_uint_type result_local { a_local / b_local };
boost_uint_type result_boost { a_boost / b_boost };

std::vector<std::uint8_t> result_data_local(max_size, UINT8_C(0));
std::vector<std::uint8_t> result_data_boost(result_data_local.size(), UINT8_C(0));

export_bits(result_local, result_data_local.data(), 8U);
export_bits(result_boost, result_data_boost.data(), 8U);

// Verify that both uintwide_t as well as boost obtain the same result.
const bool result_div_is_ok =
std::equal
(
result_data_local.cbegin(),
result_data_local.cend(),
result_data_boost.cbegin(),
result_data_boost.cend()
);

result_is_ok = (result_div_is_ok && result_is_ok);
}
}

// Assert the correct result.
assert(result_is_ok);

return result_is_ok;
}

// The fuzzing entry point.
extern "C"
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
const bool result_one_div_is_ok { fuzzing::eval_div(data, size) };

return (result_one_div_is_ok ? 0 : -1);
}
4 changes: 2 additions & 2 deletions test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
///////////////////////////////////////////////////////////////////

// On Windows subsystem for LINUX
// cd /mnt/c/Users/User/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer
// cd /mnt/c/Users/ckorm/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer

// When using local Boost-develop branch, use specific include paths.
// -I/mnt/c/boost/modular_boost/boost/libs/config/include -I/mnt/c/boost/modular_boost/boost/libs/multiprecision/include
Expand All @@ -23,7 +23,7 @@
// make prepare -f make_gcov_01_generic.gmk MY_ALL_COV=0 MY_BOOST_ROOT=/mnt/c/boost/boost_1_85_0 MY_CC=g++
// make gcov -f make_gcov_01_generic.gmk --jobs=8 MY_ALL_COV=0 MY_BOOST_ROOT=/mnt/c/boost/boost_1_85_0 MY_CC=g++

// cd /mnt/c/Users/User/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer
// cd /mnt/c/Users/ckorm/Documents/Ks/PC_Software/NumericalPrograms/ExtendedNumberTypes/wide_integer
// PATH=/home/chris/coverity/cov-analysis-linux64-2023.6.2/bin:$PATH
// cov-build --dir cov-int g++ -finline-functions -march=native -mtune=native -O3 -Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -std=c++14 -DWIDE_INTEGER_HAS_LIMB_TYPE_UINT64 -DWIDE_INTEGER_HAS_MUL_8_BY_8_UNROLL -I. -I/mnt/c/boost/boost_1_85_0 -pthread -lpthread test/test.cpp test/test_uintwide_t_boost_backend.cpp test/test_uintwide_t_edge_cases.cpp test/test_uintwide_t_examples.cpp test/test_uintwide_t_float_convert.cpp test/test_uintwide_t_int_convert.cpp test/test_uintwide_t_n_base.cpp test/test_uintwide_t_n_binary_ops_base.cpp examples/example000a_builtin_convert.cpp test/test_uintwide_t_spot_values.cpp examples/example000_numeric_limits.cpp examples/example001_mul_div.cpp examples/example001a_div_mod.cpp examples/example002_shl_shr.cpp examples/example003_sqrt.cpp examples/example003a_cbrt.cpp examples/example004_rootk_pow.cpp examples/example005_powm.cpp examples/example005a_pow_factors_of_p99.cpp examples/example006_gcd.cpp examples/example007_random_generator.cpp examples/example008_miller_rabin_prime.cpp examples/example008a_miller_rabin_prime.cpp examples/example009_timed_mul.cpp examples/example009a_timed_mul_4_by_4.cpp examples/example009b_timed_mul_8_by_8.cpp examples/example010_uint48_t.cpp examples/example011_uint24_t.cpp examples/example012_rsa_crypto.cpp examples/example013_ecdsa_sign_verify.cpp examples/example014_pi_spigot_wide.cpp -o wide_integer.exe
// tar caf wide-integer.bz2 cov-int
Expand Down
13 changes: 13 additions & 0 deletions wide_integer_vs2022.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,18 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="test\coverity.c" />
<ClCompile Include="test\fuzzing\test_fuzzing_add.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="test\fuzzing\test_fuzzing_div.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="test\test.cpp" />
<ClCompile Include="test\test_uintwide_t_boost_backend.cpp" />
<ClCompile Include="test\test_uintwide_t_boost_backend_via_test_arithmetic.cpp">
Expand Down Expand Up @@ -262,6 +274,7 @@
<None Include=".github\workflows\CodeQL.yml" />
<None Include=".github\workflows\wide_integer.yml" />
<None Include=".github\workflows\wide_integer_codecov.yml" />
<None Include=".github\workflows\wide_integer_fuzzing.yml" />
<None Include=".github\workflows\wide_integer_sonar.yml" />
<None Include=".tidy\make\make_tidy_01_generic.gmk" />
<None Include=".tidy\make\make_tidy_02_files.gmk" />
Expand Down
12 changes: 12 additions & 0 deletions wide_integer_vs2022.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
<Filter Include="Source Files\util\utility">
<UniqueIdentifier>{d0da75c7-dd48-4e37-b1ee-283464e3ce9d}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\test\fuzzing">
<UniqueIdentifier>{597ab5f0-b045-443a-8da2-1b929052b42f}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="boost\multiprecision\uintwide_t_backend.hpp">
Expand Down Expand Up @@ -222,6 +225,12 @@
<ClCompile Include="examples\example014_pi_spigot_wide.cpp">
<Filter>Source Files\examples</Filter>
</ClCompile>
<ClCompile Include="test\fuzzing\test_fuzzing_add.cpp">
<Filter>Source Files\test\fuzzing</Filter>
</ClCompile>
<ClCompile Include="test\fuzzing\test_fuzzing_div.cpp">
<Filter>Source Files\test\fuzzing</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include=".github\workflows\wide_integer.yml">
Expand Down Expand Up @@ -266,6 +275,9 @@
<None Include=".github\workflows\CodeQL.yml">
<Filter>.github\workflows</Filter>
</None>
<None Include=".github\workflows\wide_integer_fuzzing.yml">
<Filter>.github\workflows</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Text Include="examples\CMakeLists.txt">
Expand Down

0 comments on commit f04bf9a

Please sign in to comment.