11#pragma clang diagnostic push
12#pragma clang diagnostic ignored "-Wc99-designator"
27#ifdef FUZZING_SHOW_INFORMATION
28#define PRINT_TWO_ARG_INSTRUCTION(first_index, second_index, vector, operation_name, preposition) \
30 std::cout << operation_name << " " << (vector[first_index].suint.is_constant() ? "constant(" : "witness(") \
31 << vector[first_index].suint.get_value() << ":" << vector[first_index].suint.current_max << ") at " \
32 << first_index << " " << preposition << " " \
33 << (vector[second_index].suint.is_constant() ? "constant(" : "witness(") \
34 << vector[second_index].suint.get_value() << ":" << vector[second_index].suint.current_max \
35 << ") at " << second_index << std::flush; \
38#define PRINT_THREE_ARG_INSTRUCTION( \
39 first_index, second_index, third_index, vector, operation_name, preposition1, preposition2) \
41 std::cout << operation_name << " " << (vector[first_index].suint.is_constant() ? "constant(" : "witness(") \
42 << vector[first_index].suint.get_value() << ":" << vector[first_index].suint.current_max << ") at " \
43 << first_index << " " << preposition1 << " " \
44 << (vector[second_index].suint.is_constant() ? "constant(" : "witness(") \
45 << vector[second_index].suint.get_value() << ":" << vector[second_index].suint.current_max \
46 << ") at " << second_index << " " << preposition2 << " " \
47 << (vector[third_index].suint.is_constant() ? "constant(" : "witness(") \
48 << vector[third_index].suint.get_value() << ":" << vector[third_index].suint.current_max << ") at " \
49 << third_index << std::flush; \
51#define PRINT_TWO_ARG_ONE_VALUE_INSTRUCTION( \
52 first_index, second_index, third_index, vector, operation_name, preposition1, preposition2) \
54 std::cout << operation_name << " " << (vector[first_index].suint.is_constant() ? "constant(" : "witness(") \
55 << vector[first_index].suint.get_value() << ":" << vector[first_index].suint.current_max << ") at " \
56 << first_index << " " << preposition1 << " " \
57 << (vector[second_index].suint.is_constant() ? "constant(" : "witness(") \
58 << vector[second_index].suint.get_value() << ":" << vector[second_index].suint.current_max \
59 << ") at " << second_index << " " << preposition2 << " " << third_index << std::flush; \
62#define PRINT_TWO_ARG_TWO_VALUES_INSTRUCTION( \
63 first_index, second_index, value1, value2, vector, operation_name, preposition1, preposition2, preposition3) \
65 std::cout << operation_name << " " << (vector[first_index].suint.is_constant() ? "constant(" : "witness(") \
66 << vector[first_index].suint.get_value() << ":" << vector[first_index].suint.current_max << ") at " \
67 << first_index << " " << preposition1 << " " \
68 << (vector[second_index].suint.is_constant() ? "constant(" : "witness(") \
69 << vector[second_index].suint.get_value() << ":" << vector[second_index].suint.current_max \
70 << ") at " << second_index << " " << preposition2 << " " << value1 << preposition3 << value2 \
74#define PRINT_SLICE(first_index, lsb, msb, vector) \
76 std::cout << "Slice:" \
77 << " " << (vector[first_index].suint.is_constant() ? "constant(" : "witness(") \
78 << vector[first_index].suint.get_value() << ":" << vector[first_index].suint.current_max << ") at " \
79 << first_index << " " \
80 << "(" << (size_t)lsb << ":" << (size_t)msb << ")" << std::flush; \
83#define PRINT_RESULT(prefix, action, index, value) \
85 std::cout << " result(" << value.suint.get_value() << " : " << value.suint.current_max << ") " << action \
86 << index << std::endl \
92#define PRINT_TWO_ARG_INSTRUCTION(first_index, second_index, vector, operation_name, preposition)
94#define PRINT_TWO_ARG_ONE_VALUE_INSTRUCTION( \
95 first_index, second_index, third_index, vector, operation_name, preposition1, preposition2)
96#define PRINT_TWO_ARG_TWO_VALUES_INSTRUCTION( \
97 first_index, second_index, value1, value2, vector, operation_name, preposition1, preposition2, preposition3)
99#define PRINT_THREE_ARG_INSTRUCTION( \
100 first_index, second_index, third_index, vector, operation_name, preposition1, preposition2)
101#define PRINT_RESULT(prefix, action, index, value)
103#define PRINT_SLICE(first_index, lsb, msb, vector)
106#define OPERATION_TYPE_SIZE 1
108#define ELEMENT_SIZE (sizeof(fr) + 1)
109#define TWO_IN_ONE_OUT 3
110#define THREE_IN_ONE_OUT 4
111#define SLICE_ARGS_SIZE 6
198 template <
typename T>
204 uint8_t in1, in2, in3, lsb, msb, out, out1, out2, out3, mask_size, bit_range;
207 switch (instruction_opcode) {
213 for (
size_t i = 0; i < (
sizeof(
uint256_t) >> 1); i++) {
214 *(((uint16_t*)&temp) + i) =
static_cast<uint16_t
>(rng.next() & 0xffff);
218 mask_size =
static_cast<uint8_t
>(rng.next() & 0xff);
221 bit_range =
static_cast<uint8_t
>(rng.next() & 0xff);
223 return { .id = instruction_opcode,
224 .arguments.element = { .value =
fr(temp & mask), .bit_range = bit_range } };
233 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
234 in2 =
static_cast<uint8_t
>(rng.next() & 0xff);
235 out =
static_cast<uint8_t
>(rng.next() & 0xff);
236 return { .id = instruction_opcode, .arguments.threeArgs = { .in1 = in1, .in2 = in2, .out = out } };
243 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
244 in2 =
static_cast<uint8_t
>(rng.next() & 0xff);
245 in3 =
static_cast<uint8_t
>(rng.next() & 0xff);
246 out =
static_cast<uint8_t
>(rng.next() & 0xff);
247 return { .id = instruction_opcode,
248 .arguments.fourArgs = { .in1 = in1, .in2 = in2, .in3 = in3, .out = out } };
254 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
255 in2 =
static_cast<uint8_t
>(rng.next() & 0xff);
256 in3 =
static_cast<uint8_t
>(rng.next() & 0xff);
257 lsb =
static_cast<uint8_t
>(rng.next() & 0xff);
258 out =
static_cast<uint8_t
>(rng.next() & 0xff);
259 return { .id = instruction_opcode,
260 .arguments.fiveArgs = { .in1 = in1, .in2 = in2, .qbs = in3, .rbs = lsb, .out = out } };
266 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
267 lsb =
static_cast<uint8_t
>(rng.next() & 0xff);
268 msb =
static_cast<uint8_t
>(rng.next() & 0xff);
269 out1 =
static_cast<uint8_t
>(rng.next() & 0xff);
270 out2 =
static_cast<uint8_t
>(rng.next() & 0xff);
271 out3 =
static_cast<uint8_t
>(rng.next() & 0xff);
272 return { .id = instruction_opcode,
273 .arguments.sliceArgs = {
274 .in1 = in1, .lsb = lsb, .msb = msb, .out1 = out1, .out2 = out2, .out3 = out3 } };
277 return { .id = instruction_opcode, .arguments.randomseed = rng.next() };
294 template <
typename T>
301 bool convert_to_montgomery = (rng.next() % (havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY +
302 havoc_config.VAL_MUT_NON_MONTGOMERY_PROBABILITY)) <
303 havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY;
306#define MONT_CONVERSION \
307 if (convert_to_montgomery) { \
308 value_data = uint256_t(e.to_montgomery_form()); \
310 value_data = uint256_t(e); \
313#define INV_MONT_CONVERSION \
314 if (convert_to_montgomery) { \
315 e = fr(value_data).from_montgomery_form(); \
317 e = fr(value_data); \
321 const size_t mutation_type_count = havoc_config.value_mutation_distribution.size();
323 const size_t choice = rng.next() % havoc_config.value_mutation_distribution[mutation_type_count - 1];
324 if (choice < havoc_config.value_mutation_distribution[0]) {
329 }
else if (choice < havoc_config.value_mutation_distribution[1]) {
331 if (convert_to_montgomery) {
332 e = e.to_montgomery_form();
334 if (rng.next() & 1) {
335 e +=
fr(rng.next() & 0xff);
337 e -=
fr(rng.next() & 0xff);
339 if (convert_to_montgomery) {
340 e = e.from_montgomery_form();
344 switch (rng.next() % 8) {
373 if (convert_to_montgomery) {
374 e = e.from_montgomery_form();
389 template <
typename T>
393#define PUT_RANDOM_BYTE_IF_LUCKY(variable) \
394 if (rng.next() & 1) { \
395 variable = rng.next() & 0xff; \
405 if (rng.next() & 1) {
463 static constexpr size_t ADD = 3;
468 static constexpr size_t MADD = 4;
493 .bit_range = *Data } };
498 .arguments.threeArgs = { .in1 = *Data, .in2 = *(Data + 1), .out = *(Data + 2) } };
503 .arguments.fourArgs = {
504 .in1 = *Data, .in2 = *(Data + 1), .in3 = *(Data + 2), .out = *(Data + 3) } };
506 if constexpr (opcode == Instruction::OPCODE::DIVIDE_WITH_CONSTRAINTS) {
507 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
508 .arguments.fiveArgs = { .in1 = *Data,
512 .out = *(Data + 4) } };
514 if constexpr (opcode == Instruction::OPCODE::SLICE) {
515 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
516 .arguments.sliceArgs = { .in1 = *Data,
521 .out3 = *(Data + 5) } };
523 if constexpr (opcode == Instruction::OPCODE::RANDOMSEED) {
525 memcpy(&randomseed, Data,
sizeof(uint32_t));
526 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
527 .arguments.randomseed = randomseed };
537 template <
typename Instruction::OPCODE instruction_opcode>
540 if constexpr (instruction_opcode == Instruction::OPCODE::CONSTANT ||
541 instruction_opcode == Instruction::OPCODE::WITNESS ||
542 instruction_opcode == Instruction::OPCODE::CONSTANT_WITNESS) {
544 *(Data + 1) =
instruction.arguments.element.bit_range;
548 if constexpr (instruction_opcode == Instruction::OPCODE::ADD ||
549 instruction_opcode == Instruction::OPCODE::DIVIDE ||
550 instruction_opcode == Instruction::OPCODE::MULTIPLY ||
551 instruction_opcode == Instruction::OPCODE::SUBTRACT) {
557 if constexpr (instruction_opcode == Instruction::OPCODE::ADD_TWO ||
558 instruction_opcode == Instruction::OPCODE::MADD ||
559 instruction_opcode == Instruction::OPCODE::SUBTRACT_WITH_CONSTRAINT) {
566 if constexpr (instruction_opcode == Instruction::OPCODE::DIVIDE_WITH_CONSTRAINTS) {
574 if constexpr (instruction_opcode == Instruction::OPCODE::SLICE) {
579 *(Data + 4) =
instruction.arguments.sliceArgs.out1;
580 *(Data + 5) =
instruction.arguments.sliceArgs.out2;
581 *(Data + 6) =
instruction.arguments.sliceArgs.out3;
583 if constexpr (instruction_opcode == Instruction::OPCODE::RANDOMSEED) {
586 memcpy(Data + 1, &
instruction.arguments.randomseed,
sizeof(uint32_t));
634 : reference_value(s.get_value())
643 if ((this->reference_value - other.
reference_value) >= (uint512_t(1) << difference_bit_size)) {
647 this->s().subtract(other.
s(), difference_bit_size));
662 auto quotient =
static_cast<uint512_t
>(this->reference_value.lo / other.
reference_value.lo);
663 auto remainder = this->reference_value.
lo - quotient.lo * other.
reference_value.lo;
664 if ((quotient.lo >= (
uint256_t(1) << quotient_bit_size)) ||
665 (remainder >= (
uint256_t(1) << remainder_bit_size))) {
668 return ExecutionHandler(quotient, this->s().divide(other.
s(), quotient_bit_size, remainder_bit_size));
676 this->s() / other.
s());
683 this->s().add_two(other1.
s(), other2.
s()));
690 this->s().madd(other1.
s(), other2.
s()));
695 const auto msb_plus_one = uint32_t(msb) + 1;
696 const auto hi_mask = ((
uint256_t(1) << (256 - uint32_t(msb))) - 1);
697 const auto hi_reference = (this->reference_value.lo >> msb_plus_one) & hi_mask;
699 const auto lo_mask = (
uint256_t(1) << lsb) - 1;
700 const auto lo_reference = this->reference_value.lo & lo_mask;
702 const auto slice_mask = ((
uint256_t(1) << (uint32_t(msb - lsb) + 1)) - 1);
703 const auto slice_reference = (this->reference_value.lo >> lsb) & slice_mask;
705 auto lo_slice_hi_suint_array = this->s().slice(msb, lsb);
725#ifdef FUZZING_SHOW_INFORMATION
744 size_t bit_range =
static_cast<size_t>(
instruction.arguments.element.bit_range);
746 if ((bit_range > suint_t::MAX_BIT_NUM) ||
751 if (bit_range == 0 &&
instruction.arguments.element.value != 0) {
757#ifdef FUZZING_SHOW_INFORMATION
758 std::cout <<
"Pushed witness value " <<
instruction.arguments.element.value <<
" < 2^" << (size_t)bit_range
759 <<
" to position " << stack.size() - 1 <<
std::endl;
776 stack.push_back(suint_t::create_constant_witness(
builder,
instruction.arguments.element.value));
777#ifdef FUZZING_SHOW_INFORMATION
778 std::cout <<
"Pushed constant witness value " <<
instruction.arguments.element.value <<
" to position "
797 if (stack.size() == 0) {
800 size_t first_index =
instruction.arguments.threeArgs.in1 % stack.size();
801 size_t second_index =
instruction.arguments.threeArgs.in2 % stack.size();
802 size_t output_index =
instruction.arguments.threeArgs.out;
807 if ((
static_cast<uint512_t
>(stack[first_index].suint.
current_max) *
808 static_cast<uint512_t
>(stack[second_index].suint.current_max))
815 result = stack[first_index] * stack[second_index];
816 }
catch (std::runtime_error& err) {
817 if (!strncmp(err.what(),
818 "exceeded modulus in safe_uint class",
819 sizeof(
"exceeded modulus in safe_uint class"))) {
825 if (output_index >= stack.size()) {
827 stack.push_back(result);
831 stack[output_index] = result;
848 if (stack.size() == 0) {
851 size_t first_index =
instruction.arguments.threeArgs.in1 % stack.size();
852 size_t second_index =
instruction.arguments.threeArgs.in2 % stack.size();
853 size_t output_index =
instruction.arguments.threeArgs.out;
859 result = stack[first_index] + stack[second_index];
860 }
catch (std::runtime_error& err) {
861 if (!strncmp(err.what(),
862 "exceeded modulus in safe_uint class",
863 sizeof(
"exceeded modulus in safe_uint class"))) {
869 if (output_index >= stack.size()) {
871 stack.push_back(result);
875 stack[output_index] = result;
892 if (stack.size() == 0) {
895 size_t first_index =
instruction.arguments.threeArgs.in1 % stack.size();
896 size_t second_index =
instruction.arguments.threeArgs.in2 % stack.size();
897 size_t output_index =
instruction.arguments.threeArgs.out;
902 if ((
static_cast<uint512_t
>(1 << (stack[first_index].suint.
current_max.
get_msb() + 1)) +
903 static_cast<uint512_t
>(stack[second_index].suint.current_max)) > suint_t::MAX_VALUE) {
908 if (stack[first_index].suint.
is_constant() && stack[second_index].suint.is_constant() &&
909 (
static_cast<uint256_t>(stack[first_index].suint.get_value()) <
910 static_cast<uint256_t>(stack[second_index].suint.get_value()))) {
921 result = stack[first_index] - stack[second_index];
922 }
catch (std::runtime_error& err) {
923 if (!strncmp(err.what(),
924 "exceeded modulus in safe_uint class",
925 sizeof(
"exceeded modulus in safe_uint class"))) {
928 if (!strncmp(err.what(),
929 "maximum value exceeded in safe_uint minus operator",
930 sizeof(
"maximum value exceeded in safe_uint minus operator"))) {
936 if (output_index >= stack.size()) {
938 stack.push_back(result);
942 stack[output_index] = result;
959 if (stack.size() == 0) {
962 size_t first_index =
instruction.arguments.threeArgs.in1 % stack.size();
963 size_t second_index =
instruction.arguments.threeArgs.in2 % stack.size();
964 size_t output_index =
instruction.arguments.threeArgs.out;
974 stack[second_index].suint.current_max)
980 result = stack[first_index] / stack[second_index];
981 }
catch (std::runtime_error& err) {
982 if (!strncmp(err.what(),
983 "exceeded modulus in safe_uint class",
984 sizeof(
"exceeded modulus in safe_uint class"))) {
987 if (!strncmp(err.what(),
988 "maximum value exceeded in safe_uint minus operator",
989 sizeof(
"maximum value exceeded in safe_uint minus operator"))) {
995 if (stack[first_index].suint.
get_value().
is_zero() && stack[second_index].suint.get_value().is_zero()) {
999 if (output_index >= stack.size()) {
1001 stack.push_back(result);
1005 stack[output_index] = result;
1023 if (stack.size() == 0) {
1026 size_t first_index =
instruction.arguments.fourArgs.in1 % stack.size();
1027 size_t second_index =
instruction.arguments.fourArgs.in2 % stack.size();
1028 size_t third_index =
instruction.arguments.fourArgs.in3 % stack.size();
1029 size_t output_index =
instruction.arguments.fourArgs.out;
1032 if ((
static_cast<uint512_t
>(stack[first_index].suint.
current_max) +
1033 static_cast<uint512_t
>(stack[second_index].suint.current_max) +
1034 static_cast<uint512_t
>(stack[third_index].suint.current_max)) >
1035 static_cast<uint512_t
>(suint_t::MAX_VALUE)) {
1040 result = stack[first_index].
add_two(stack[second_index], stack[third_index]);
1041 }
catch (std::runtime_error& err) {
1042 if (!strncmp(err.what(),
1043 "exceeded modulus in safe_uint class",
1044 sizeof(
"exceeded modulus in safe_uint class"))) {
1050 if (output_index >= stack.size()) {
1052 stack.push_back(result);
1056 stack[output_index] = result;
1074 if (stack.size() == 0) {
1077 size_t first_index =
instruction.arguments.fourArgs.in1 % stack.size();
1078 size_t second_index =
instruction.arguments.fourArgs.in2 % stack.size();
1079 size_t third_index =
instruction.arguments.fourArgs.in3 % stack.size();
1080 size_t output_index =
instruction.arguments.fourArgs.out;
1084 if ((
static_cast<uint512_t
>(stack[first_index].suint.
current_max) *
1085 static_cast<uint512_t
>(stack[second_index].suint.current_max) +
1086 static_cast<uint512_t
>(stack[third_index].suint.current_max)) >
1087 static_cast<uint512_t
>(suint_t::MAX_VALUE)) {
1092 result = stack[first_index].
madd(stack[second_index], stack[third_index]);
1093 }
catch (std::runtime_error& err) {
1094 if (!strncmp(err.what(),
1095 "exceeded modulus in safe_uint class",
1096 sizeof(
"exceeded modulus in safe_uint class"))) {
1102 if (output_index >= stack.size()) {
1104 stack.push_back(result);
1108 stack[output_index] = result;
1127 if (stack.size() == 0) {
1130 size_t first_index =
instruction.arguments.fourArgs.in1 % stack.size();
1131 size_t second_index =
instruction.arguments.fourArgs.in2 % stack.size();
1132 size_t difference_bit_size =
instruction.arguments.fourArgs.in3;
1133 size_t output_index =
instruction.arguments.fourArgs.out;
1135 first_index, second_index, difference_bit_size, stack,
"SUBTRACT_WITH_CONSTRAINT:",
"-",
"<= 2**")
1138 if (difference_bit_size > suint_t::MAX_BIT_NUM) {
1142 if (stack[first_index].suint.
is_constant() && stack[second_index].suint.is_constant()) {
1147 result = stack[first_index].
subtract(stack[second_index], difference_bit_size);
1148 }
catch (std::runtime_error& err) {
1149 if (!strncmp(err.what(),
1150 "maximum value exceeded in safe_uint subtract",
1151 sizeof(
"maximum value exceeded in safe_uint subtract"))) {
1157 if (output_index >= stack.size()) {
1159 stack.push_back(result);
1163 stack[output_index] = result;
1182 if (stack.size() == 0) {
1185 size_t first_index =
instruction.arguments.fiveArgs.in1 % stack.size();
1186 size_t second_index =
instruction.arguments.fiveArgs.in2 % stack.size();
1187 size_t quotient_bit_size =
instruction.arguments.fiveArgs.qbs;
1190 if (quotient_bit_size + stack[second_index].suint.
current_max.
get_msb() + 1 >= 256) {
1194 size_t remainder_bit_size =
instruction.arguments.fiveArgs.rbs;
1195 size_t output_index =
instruction.arguments.fiveArgs.out;
1201 "DIVIDE_WITH_CONSTRAINTS:",
1207 if ((quotient_bit_size > suint_t::MAX_BIT_NUM) || (remainder_bit_size > suint_t::MAX_BIT_NUM)) {
1216 result = stack[first_index].
divide(stack[second_index], quotient_bit_size, remainder_bit_size);
1217 }
catch (std::runtime_error& err) {
1218 if (!strncmp(err.what(),
1219 "exceeded modulus in safe_uint class",
1220 sizeof(
"exceeded modulus in safe_uint class"))) {
1223 if (!strncmp(err.what(),
1224 "maximum value exceeded in safe_uint minus operator",
1225 sizeof(
"maximum value exceeded in safe_uint minus operator"))) {
1231 if (output_index >= stack.size()) {
1233 stack.push_back(result);
1237 stack[output_index] = result;
1255 if (stack.size() == 0) {
1258 size_t first_index =
instruction.arguments.sliceArgs.in1 % stack.size();
1259 uint8_t lsb =
instruction.arguments.sliceArgs.lsb;
1260 uint8_t msb =
instruction.arguments.sliceArgs.msb;
1261 size_t second_index =
instruction.arguments.sliceArgs.out1;
1262 size_t third_index =
instruction.arguments.sliceArgs.out2;
1263 size_t output_index =
instruction.arguments.sliceArgs.out3;
1266 if ((lsb > msb) || (msb > 252) ||
1272 auto slices = stack[first_index].slice(lsb, msb);
1276 for (
auto& x : what_where) {
1277 auto suints_count = stack.size();
1278 if (x.second >= suints_count) {
1280 PRINT_RESULT(
"\t",
"pushed to ", stack.size(), x.first)
1281 stack.push_back(x.first);
1285 stack[x.second] = x.first;
1324 .GEN_MUTATION_COUNT_LOG = 5,
1325 .GEN_STRUCTURAL_MUTATION_PROBABILITY = 300,
1326 .GEN_VALUE_MUTATION_PROBABILITY = 700,
1327 .ST_MUT_DELETION_PROBABILITY = 100,
1328 .ST_MUT_DUPLICATION_PROBABILITY = 80,
1329 .ST_MUT_INSERTION_PROBABILITY = 120,
1330 .ST_MUT_MAXIMUM_DELETION_LOG = 6,
1331 .ST_MUT_MAXIMUM_DUPLICATION_LOG = 2,
1332 .ST_MUT_SWAP_PROBABILITY = 50,
1333 .VAL_MUT_LLVM_MUTATE_PROBABILITY = 250,
1334 .VAL_MUT_MONTGOMERY_PROBABILITY = 130,
1335 .VAL_MUT_NON_MONTGOMERY_PROBABILITY = 50,
1336 .VAL_MUT_SMALL_ADDITION_PROBABILITY = 110,
1337 .VAL_MUT_SPECIAL_VALUE_PROBABILITY = 130
1404 std::vector<size_t> structural_mutation_distribution;
1405 std::vector<size_t> value_mutation_distribution;
1407 temp += fuzzer_havoc_settings.ST_MUT_DELETION_PROBABILITY;
1408 structural_mutation_distribution.push_back(temp);
1409 temp += fuzzer_havoc_settings.ST_MUT_DUPLICATION_PROBABILITY;
1410 structural_mutation_distribution.push_back(temp);
1411 temp += fuzzer_havoc_settings.ST_MUT_INSERTION_PROBABILITY;
1412 structural_mutation_distribution.push_back(temp);
1413 temp += fuzzer_havoc_settings.ST_MUT_SWAP_PROBABILITY;
1414 structural_mutation_distribution.push_back(temp);
1415 fuzzer_havoc_settings.structural_mutation_distribution = structural_mutation_distribution;
1418 temp += fuzzer_havoc_settings.VAL_MUT_LLVM_MUTATE_PROBABILITY;
1419 value_mutation_distribution.push_back(temp);
1420 temp += fuzzer_havoc_settings.VAL_MUT_SMALL_ADDITION_PROBABILITY;
1421 value_mutation_distribution.push_back(temp);
1423 temp += fuzzer_havoc_settings.VAL_MUT_SPECIAL_VALUE_PROBABILITY;
1424 value_mutation_distribution.push_back(temp);
1425 fuzzer_havoc_settings.value_mutation_distribution = value_mutation_distribution;
1436 RunWithBuilders<SafeUintFuzzBase, FuzzerCircuitTypes>(Data, Size,
VarianceRNG);
1440#pragma clang diagnostic pop
#define PRINT_THREE_ARG_INSTRUCTION( first_index, second_index, third_index, vector, operation_name, preposition1, preposition2)
#define PRINT_TWO_ARG_INSTRUCTION(first_index, second_index, vector, operation_name, preposition)
#define PRINT_SLICE(first_index, lsb, msb, vector)
FastRandom VarianceRNG(0)
#define PRINT_TWO_ARG_TWO_VALUES_INSTRUCTION( first_index, second_index, value1, value2, vector, operation_name, preposition1, preposition2, preposition3)
#define PRINT_RESULT(prefix, action, index, value)
#define PRINT_TWO_ARG_ONE_VALUE_INSTRUCTION( first_index, second_index, third_index, vector, operation_name, preposition1, preposition2)
Class for quickly deterministically creating new random values. We don't care about distribution much...
void reseed(uint32_t seed)
static constexpr size_t MADD
static constexpr size_t SLICE
static constexpr size_t ADD
static constexpr size_t DIVIDE
static constexpr size_t CONSTANT_WITNESS
static constexpr size_t RANDOMSEED
static constexpr size_t SUBTRACT
static constexpr size_t WITNESS
static constexpr size_t CONSTANT
static constexpr size_t SUBTRACT_WITH_CONSTRAINT
static constexpr size_t MULTIPLY
static constexpr size_t DIVIDE_WITH_CONSTRAINTS
static constexpr size_t ADD_TWO
This class implements the execution of safeuint with an oracle to detect discrepancies.
static size_t execute_SUBTRACT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the subtraction operator instruction.
ExecutionHandler subtract(const ExecutionHandler &other, size_t difference_bit_size)
ExecutionHandler operator+(const ExecutionHandler &other)
ExecutionHandler operator*(const ExecutionHandler &other)
static size_t execute_MULTIPLY(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the multiply instruction.
ExecutionHandler(uint512_t r, suint_t s)
static size_t execute_SLICE(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the slice instruction.
static size_t execute_SUBTRACT_WITH_CONSTRAINT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SUBTRACT_WITH_CONSTRAINT instruction.
static size_t execute_MADD(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the MADD instruction.
ExecutionHandler add_two(const ExecutionHandler &other1, const ExecutionHandler &other2)
ExecutionHandler divide(const ExecutionHandler &other, size_t quotient_bit_size, size_t remainder_bit_size)
uint512_t reference_value
static size_t execute_CONSTANT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the constant instruction (push constant safeuint to the stack)
ExecutionHandler operator/(const ExecutionHandler &other)
static size_t execute_DIVIDE_WITH_CONSTRAINTS(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
static size_t execute_DIVIDE(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the division operator instruction.
ExecutionHandler(suint_t s)
std::array< ExecutionHandler, 3 > slice(uint8_t lsb, uint8_t msb)
ExecutionHandler operator-(const ExecutionHandler &other)
static size_t execute_ADD_TWO(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the ADD_TWO instruction.
ExecutionHandler()=default
static size_t execute_RANDOMSEED(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the RANDOMSEED instruction.
ExecutionHandler(uint512_t &r, suint_t &s)
static size_t execute_CONSTANT_WITNESS(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the constant_witness instruction (push a safeuint witness equal to the constant to the stack)
ExecutionHandler madd(const ExecutionHandler &other1, const ExecutionHandler &other2)
static size_t execute_WITNESS(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the witness instruction (push witness safeuit to the stack)
static size_t execute_ADD(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the addition operator instruction.
A class representing a single fuzzing instruction.
ArgumentContents arguments
static Instruction generateRandom(T &rng)
Generate a random instruction.
static Instruction mutateInstruction(Instruction instruction, T &rng, HavocSettings &havoc_config)
Mutate a single instruction.
@ DIVIDE_WITH_CONSTRAINTS
@ SUBTRACT_WITH_CONSTRAINT
static fr mutateFieldElement(fr e, T &rng, HavocSettings &havoc_config)
Mutate the value of a field element.
Parser class handles the parsing and writing the instructions back to data buffer.
static void writeInstruction(Instruction &instruction, uint8_t *Data)
Write a single instruction to buffer.
static Instruction parseInstructionArgs(uint8_t *Data)
Parse a single instruction from data.
The class parametrizing SafeUint fuzzing instructions, execution, etc.
std::vector< ExecutionHandler > ExecutionState
constexpr uint64_t get_msb() const
Implements boolean logic in-circuit.
Concept for a simple PRNG which returns a uint32_t when next is called.
size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize)
stdlib::witness_t< Builder > witness_t
constexpr size_t MAX_NO_WRAP_INTEGER_BIT_LENGTH
Instruction
Enumeration of VM instructions that can be executed.
field< Bn254FrParams > fr
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
#define INV_MONT_CONVERSION
FastRandom VarianceRNG(0)
int LLVMFuzzerInitialize(int *argc, char ***argv)
size_t LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
Fuzzer entry function.
#define PUT_RANDOM_BYTE_IF_LUCKY(variable)
size_t GEN_LLVM_POST_MUTATION_PROB
static constexpr field get_root_of_unity(size_t subgroup_size) noexcept
static constexpr field one()
static constexpr uint256_t modulus
static field serialize_from_buffer(const uint8_t *buffer)
static void serialize_to_buffer(const field &value, uint8_t *buffer)
constexpr std::pair< bool, field > sqrt() const noexcept
Compute square root of the field element.
BB_INLINE constexpr bool is_zero() const noexcept
static constexpr field zero()