1#include "barretenberg/numeric/random/engine.hpp"
2#include "barretenberg/stdlib/primitives/byte_array/byte_array.hpp"
3#include "barretenberg/stdlib/primitives/safe_uint/safe_uint.hpp"
4#pragma clang diagnostic push
5#pragma clang diagnostic ignored "-Wc99-designator"
7#define MAX_ARRAY_SIZE 128
11bool circuit_should_fail =
false;
15#include "barretenberg/common/fuzzer.hpp"
21#define OPERATION_TYPE_SIZE 1
23#define ELEMENT_SIZE (sizeof(fr) + 1)
24#define TWO_IN_ONE_OUT 3
25#define THREE_IN_ONE_OUT 4
26#define SLICE_ARGS_SIZE 6
38 template <
class From,
class To>
static To from_to(
const From& in,
const std::optional<size_t> size = std::nullopt)
40 return To(in.data(), in.data() + (size ? *size : in.size()));
50 enum OPCODE { CONSTANT, REVERSE, SLICE, GET_BIT, SET_BIT, ADD, SET, RANDOMSEED, _LAST };
53 std::array<uint8_t, MAX_ARRAY_SIZE> data;
56 uint16_t real_size(
void)
const {
return std::min(size,
static_cast<uint16_t
>(MAX_ARRAY_SIZE)); }
57 std::vector<uint8_t> as_vector(
void)
const
59 return from_to<
decltype(data), std::vector<uint8_t>>(data, real_size());
61 std::string as_string(
void)
const {
return from_to<decltype(data), std::string>(data, real_size()); }
109 template <
typename T>
114 OPCODE instruction_opcode =
static_cast<OPCODE
>(rng.next() % (OPCODE::_LAST));
115 uint8_t in1, in2, out, value;
116 uint16_t offset, length;
119 switch (instruction_opcode) {
120 case OPCODE::CONSTANT:
123 std::array<uint8_t, MAX_ARRAY_SIZE> data;
124 for (
size_t i = 0; i < MAX_ARRAY_SIZE; i++) {
125 data[i] = rng.next() & 0xFF;
128 const uint16_t size = rng.next() & 0xFFFF;
129 return { .id = instruction_opcode, .arguments.element = { .data = data, .size = size } };
132 case OPCODE::REVERSE:
134 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
135 out =
static_cast<uint8_t
>(rng.next() & 0xff);
136 return { .id = instruction_opcode, .arguments.twoArgs = { .in = in1, .out = out } };
139 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
140 out =
static_cast<uint8_t
>(rng.next() & 0xff);
141 offset =
static_cast<uint16_t
>(rng.next() & 0xffff);
142 length =
static_cast<uint16_t
>(rng.next() & 0xffff);
143 return { .id = instruction_opcode,
144 .arguments.sliceArgs = { .in = in1, .out = out, .offset = offset, .length = length } };
145 case OPCODE::GET_BIT:
146 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
147 out =
static_cast<uint8_t
>(rng.next() & 0xff);
148 bit =
static_cast<uint32_t
>(rng.next() & 0xffffffff);
149 return { .id = instruction_opcode, .arguments.getBitArgs = { .in = in1, .out = out, .bit = bit } };
153 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
154 in2 =
static_cast<uint8_t
>(rng.next() & 0xff);
155 out =
static_cast<uint8_t
>(rng.next() & 0xff);
156 return { .id = instruction_opcode, .arguments.threeArgs = { .in1 = in1, .in2 = in2, .out = out } };
157 case OPCODE::SET_BIT:
158 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
159 bit =
static_cast<uint32_t
>(rng.next() & 0xffffffff);
160 value =
static_cast<uint8_t
>(rng.next() & 0xff);
161 return { .id = instruction_opcode, .arguments.setBitArgs = { .in = in1, .bit = bit, .value = value } };
162 case OPCODE::RANDOMSEED:
163 return { .id = instruction_opcode, .arguments.randomseed = rng.next() };
180 template <
typename T>
186#define PUT_RANDOM_BYTE_IF_LUCKY(variable) \
187 if (rng.next() & 1) { \
188 variable = rng.next() & 0xff; \
190#define PUT_RANDOM_TWO_BYTES_IF_LUCKY(variable) \
191 if (rng.next() & 1) { \
192 variable = rng.next() & 0xffff; \
194#define PUT_RANDOM_FOUR_BYTES_IF_LUCKY(variable) \
195 if (rng.next() & 1) { \
196 variable = rng.next() & 0xffffffff; \
199 switch (instruction.id) {
200 case OPCODE::CONSTANT:
202 case OPCODE::REVERSE:
204 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.twoArgs.in)
205 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.twoArgs.out)
208 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.sliceArgs.in)
209 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.sliceArgs.out)
210 PUT_RANDOM_TWO_BYTES_IF_LUCKY(instruction.arguments.sliceArgs.offset)
211 PUT_RANDOM_TWO_BYTES_IF_LUCKY(instruction.arguments.sliceArgs.length)
213 case OPCODE::GET_BIT:
214 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.getBitArgs.in)
215 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.getBitArgs.out)
216 PUT_RANDOM_FOUR_BYTES_IF_LUCKY(instruction.arguments.getBitArgs.bit)
218 case OPCODE::SET_BIT:
219 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.setBitArgs.in)
220 PUT_RANDOM_FOUR_BYTES_IF_LUCKY(instruction.arguments.setBitArgs.bit)
221 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.setBitArgs.value)
225 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.threeArgs.in1)
226 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.threeArgs.in2)
227 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.threeArgs.out)
229 case OPCODE::RANDOMSEED:
230 instruction.arguments.randomseed = rng.next();
244 static constexpr size_t CONSTANT = MAX_ARRAY_SIZE +
sizeof(uint16_t);
245 static constexpr size_t REVERSE = 2;
246 static constexpr size_t SLICE = 6;
247 static constexpr size_t GET_BIT = 6;
248 static constexpr size_t SET_BIT = 6;
249 static constexpr size_t ADD = 3;
250 static constexpr size_t SET = 2;
251 static constexpr size_t RANDOMSEED =
sizeof(uint32_t);
268 if constexpr (opcode == Instruction::OPCODE::CONSTANT) {
269 std::array<uint8_t, MAX_ARRAY_SIZE> data;
270 std::copy_n(Data, data.size(), data.begin());
273 memcpy(&size, Data + MAX_ARRAY_SIZE,
sizeof(uint16_t));
275 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
276 .arguments.element = { .data = data, .size = size } };
278 if constexpr (opcode == Instruction::OPCODE::REVERSE || opcode == Instruction::OPCODE::SET) {
279 return { .id =
static_cast<typename Instruction::OPCODE
>(opcode),
280 .arguments.twoArgs = { .in = *Data, .out = *(Data + 1) } };
282 if constexpr (opcode == Instruction::OPCODE::SLICE) {
283 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
284 .arguments.sliceArgs = { .in = *Data,
286 .offset = *((uint16_t*)(Data + 2)),
287 .length = *((uint16_t*)(Data + 4)) } };
289 if constexpr (opcode == Instruction::OPCODE::ADD) {
290 return { .id =
static_cast<typename Instruction::OPCODE
>(opcode),
291 .arguments.threeArgs = { .in1 = *Data, .in2 = *(Data + 1), .out = *(Data + 2) } };
293 if constexpr (opcode == Instruction::OPCODE::GET_BIT) {
294 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
295 .arguments.getBitArgs = {
296 .in = *Data, .out = *(Data + 1), .bit = *((uint32_t*)(Data + 2)) } };
298 if constexpr (opcode == Instruction::OPCODE::SET_BIT) {
299 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
300 .arguments.setBitArgs = {
301 .in = *Data, .bit = *((uint32_t*)(Data + 1)), .value = *(Data + 5) } };
303 if constexpr (opcode == Instruction::OPCODE::RANDOMSEED) {
305 memcpy(&randomseed, Data,
sizeof(uint32_t));
306 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
307 .arguments.randomseed = randomseed };
317 template <
typename Instruction::OPCODE instruction_opcode>
320 if constexpr (instruction_opcode == Instruction::OPCODE::CONSTANT) {
321 *Data = instruction.id;
322 memcpy(Data, instruction.arguments.element.data.data(), MAX_ARRAY_SIZE);
323 memcpy(Data + MAX_ARRAY_SIZE, &instruction.arguments.element.size,
sizeof(uint16_t));
325 if constexpr (instruction_opcode == Instruction::OPCODE::REVERSE ||
326 instruction_opcode == Instruction::OPCODE::SET) {
327 *Data = instruction.id;
328 *(Data + 1) = instruction.arguments.twoArgs.in;
329 *(Data + 2) = instruction.arguments.twoArgs.out;
331 if constexpr (instruction_opcode == Instruction::OPCODE::SLICE) {
332 *Data = instruction.id;
333 *(Data + 1) = instruction.arguments.sliceArgs.in;
334 *(Data + 2) = instruction.arguments.sliceArgs.out;
335 *((uint16_t*)(Data + 3)) = instruction.arguments.sliceArgs.offset;
336 *((uint16_t*)(Data + 5)) = instruction.arguments.sliceArgs.length;
338 if constexpr (instruction_opcode == Instruction::OPCODE::GET_BIT) {
339 *Data = instruction.id;
340 *(Data + 1) = instruction.arguments.getBitArgs.in;
341 *(Data + 2) = instruction.arguments.getBitArgs.out;
342 *((uint32_t*)(Data + 3)) = instruction.arguments.getBitArgs.bit;
344 if constexpr (instruction_opcode == Instruction::OPCODE::SET_BIT) {
345 *Data = instruction.id;
346 *(Data + 1) = instruction.arguments.setBitArgs.in;
347 *((uint32_t*)(Data + 2)) = instruction.arguments.setBitArgs.bit;
348 *(Data + 6) = instruction.arguments.setBitArgs.value;
350 if constexpr (instruction_opcode == Instruction::OPCODE::ADD) {
351 *Data = instruction.id;
352 *(Data + 1) = instruction.arguments.threeArgs.in1;
353 *(Data + 2) = instruction.arguments.threeArgs.in2;
354 *(Data + 3) = instruction.arguments.threeArgs.out;
356 if constexpr (instruction_opcode == Instruction::OPCODE::RANDOMSEED) {
358 *Data = instruction.id;
359 memcpy(Data + 1, &instruction.arguments.randomseed,
sizeof(uint32_t));
369 std::vector<uint8_t> reference_value;
371 byte_array_t byte_array{
nullptr, std::vector<uint8_t>{} };
373 static std::vector<uint8_t> get_value(
const byte_array_t& byte_array)
379 if (
static_cast<bool>(VarianceRNG.next() % 2)) {
380 return byte_array.get_value();
382 return from_to<std::string, std::vector<uint8_t>>(byte_array.get_string());
385 static const std::vector<uint8_t>& bool_to_vector(
const bool& b)
387 static const std::vector<uint8_t> false_{ 0 };
388 static const std::vector<uint8_t> true_{ 1 };
389 return b ? true_ : false_;
391 std::optional<field_t> to_field_t(std::optional<size_t> max_msb = std::nullopt)
const
393 const auto& ref = this->reference_value;
395 if (ref.size() > 32) {
398 }
else if (ref.size() == 32) {
399 uint64_t u0, u1, u2, u3;
400 memcpy(&u3, ref.data(), 8);
401 memcpy(&u2, ref.data() + 8, 8);
402 memcpy(&u1, ref.data() + 16, 8);
403 memcpy(&u0, ref.data() + 24, 8);
404 const uint256_t u256{ htonll(u0), htonll(u1), htonll(u2), htonll(u3) };
405 if (max_msb != std::nullopt && u256.get_msb() >= max_msb) {
408 if (u256 >= field_t::modulus) {
413 return static_cast<field_t>(this->byte_array);
425 : reference_value(get_value(s))
431 auto reversed = this->reference_value;
432 std::reverse(reversed.begin(), reversed.end());
438 if (offset > this->reference_value.size()) {
443 }
else if (offset + length > this->reference_value.size()) {
448 std::vector<uint8_t>(this->reference_value.data() + offset,
449 this->reference_value.data() + this->reference_value.size()),
450 this->byte_array.slice(offset));
452 return ExecutionHandler(std::vector<uint8_t>(this->reference_value.data() + offset,
453 this->reference_value.data() + offset + length),
454 this->byte_array.slice(offset, length));
459 if (bit >= this->reference_value.size() * 8) {
462 const bool is_set_ref = this->reference_value[
463 this->reference_value.size() - 1 - (bit / 8)] &
465 const bool is_set_ba = this->byte_array.
get_bit(bit).get_value();
471 void set_bit(
const size_t bit,
const bool value)
473 if (bit < this->reference_value.size() * 8) {
475 this->reference_value[
476 this->reference_value.size() - 1 - (bit / 8)] |=
479 this->reference_value[
480 this->reference_value.size() - 1 - (bit / 8)] &=
483 this->byte_array.
set_bit(bit, value);
488 if (this->reference_value.size() + other.reference_value.size() > (MAX_ARRAY_SIZE * 3)) {
491 const auto other_ref = other.reference_value;
492 this->reference_value.insert(this->reference_value.end(), other_ref.begin(), other_ref.end());
495 this->byte_array.write(other.byte_array));
501 const auto& ref = this->reference_value;
503 switch (VarianceRNG.next() % 8) {
520 const auto field = to_field_t();
522 if (field == std::nullopt) {
526 const size_t num_bytes = ref.size() + (VarianceRNG.next() % (32 - ref.size() + 1));
530 const size_t excess_bytes = num_bytes - ref.size();
533 std::vector<uint8_t> new_ref(excess_bytes, 0);
534 new_ref.insert(new_ref.end(), ref.begin(), ref.end());
546 const size_t gibberish_size = VarianceRNG.next() % (MAX_ARRAY_SIZE * 2);
547 std::vector<uint8_t> gibberish(gibberish_size);
548 for (
size_t i = 0; i < gibberish_size; i++) {
549 gibberish[i] =
static_cast<uint8_t
>(VarianceRNG.next() % 0xFF);
554 ba = this->byte_array;
559 static_assert(suint_t::MAX_BIT_NUM > 0);
560 const auto field = to_field_t(
562 suint_t::MAX_BIT_NUM - 1);
564 if (field == std::nullopt) {
588 std::vector<ExecutionHandler>& stack,
592 if (
static_cast<bool>(VarianceRNG.next() % 2)) {
593 stack.push_back(
byte_array_t(builder, instruction.arguments.element.as_vector()));
595 stack.push_back(
byte_array_t(builder, instruction.arguments.element.as_string()));
608 std::vector<ExecutionHandler>& stack,
612 if (stack.size() == 0) {
615 size_t first_index = instruction.arguments.twoArgs.in % stack.size();
616 size_t output_index = instruction.arguments.twoArgs.out;
619 result = stack[first_index].reverse();
621 if (output_index >= stack.size()) {
622 stack.push_back(result);
624 stack[output_index] = result;
638 std::vector<ExecutionHandler>& stack,
642 if (stack.size() == 0) {
645 size_t first_index = instruction.arguments.sliceArgs.in % stack.size();
646 size_t output_index = instruction.arguments.sliceArgs.out;
647 const uint16_t offset = instruction.arguments.sliceArgs.offset;
648 const uint16_t length = instruction.arguments.sliceArgs.length;
650 result = stack[first_index].slice(offset, length);
652 if (output_index >= stack.size()) {
653 stack.push_back(result);
655 stack[output_index] = result;
668 std::vector<ExecutionHandler>& stack,
672 if (stack.size() == 0) {
675 size_t first_index = instruction.arguments.getBitArgs.in % stack.size();
676 size_t output_index = instruction.arguments.getBitArgs.out;
677 const uint32_t bit = instruction.arguments.getBitArgs.bit;
679 result = stack[first_index].get_bit(builder, bit);
681 if (output_index >= stack.size()) {
682 stack.push_back(result);
684 stack[output_index] = result;
697 std::vector<ExecutionHandler>& stack,
701 if (stack.size() == 0) {
704 size_t first_index = instruction.arguments.setBitArgs.in % stack.size();
705 const uint32_t bit = instruction.arguments.setBitArgs.bit;
706 const bool value =
static_cast<bool>(instruction.arguments.setBitArgs.value % 2);
707 stack[first_index].set_bit(bit, value);
719 std::vector<ExecutionHandler>& stack,
723 if (stack.size() == 0) {
726 size_t first_index = instruction.arguments.threeArgs.in1 % stack.size();
727 size_t second_index = instruction.arguments.threeArgs.in2 % stack.size();
728 size_t output_index = instruction.arguments.threeArgs.out;
731 result = stack[first_index] + stack[second_index];
733 if (output_index >= stack.size()) {
734 stack.push_back(result);
736 stack[output_index] = result;
749 std::vector<ExecutionHandler>& stack,
753 if (stack.size() == 0) {
756 size_t first_index = instruction.arguments.twoArgs.in % stack.size();
757 size_t output_index = instruction.arguments.twoArgs.out;
759 result = stack[first_index].set(builder);
761 if (output_index >= stack.size()) {
762 stack.push_back(result);
764 stack[output_index] = result;
777 std::vector<ExecutionHandler>& stack,
783 VarianceRNG.reseed(instruction.arguments.randomseed);
788 typedef std::vector<ExecutionHandler> ExecutionState;
798 inline static bool postProcess(
Builder* builder, std::vector<ByteArrayFuzzBase::ExecutionHandler>& stack)
801 for (
size_t i = 0; i < stack.size(); i++) {
802 auto element = stack[i];
803 if (element.byte_array.get_value() != element.reference_value) {
813extern "C" int LLVMFuzzerInitialize(
int* argc,
char*** argv)
820 .GEN_LLVM_POST_MUTATION_PROB = 30,
821 .GEN_MUTATION_COUNT_LOG = 5,
822 .GEN_STRUCTURAL_MUTATION_PROBABILITY = 300,
823 .GEN_VALUE_MUTATION_PROBABILITY = 700,
824 .ST_MUT_DELETION_PROBABILITY = 100,
825 .ST_MUT_DUPLICATION_PROBABILITY = 80,
826 .ST_MUT_INSERTION_PROBABILITY = 120,
827 .ST_MUT_MAXIMUM_DELETION_LOG = 6,
828 .ST_MUT_MAXIMUM_DUPLICATION_LOG = 2,
829 .ST_MUT_SWAP_PROBABILITY = 50,
830 .VAL_MUT_LLVM_MUTATE_PROBABILITY = 250,
831 .VAL_MUT_MONTGOMERY_PROBABILITY = 130,
832 .VAL_MUT_NON_MONTGOMERY_PROBABILITY = 50,
833 .VAL_MUT_SMALL_ADDITION_PROBABILITY = 110,
834 .VAL_MUT_SPECIAL_VALUE_PROBABILITY = 130
901 std::vector<size_t> structural_mutation_distribution;
902 std::vector<size_t> value_mutation_distribution;
904 temp += fuzzer_havoc_settings.ST_MUT_DELETION_PROBABILITY;
905 structural_mutation_distribution.push_back(temp);
906 temp += fuzzer_havoc_settings.ST_MUT_DUPLICATION_PROBABILITY;
907 structural_mutation_distribution.push_back(temp);
908 temp += fuzzer_havoc_settings.ST_MUT_INSERTION_PROBABILITY;
909 structural_mutation_distribution.push_back(temp);
910 temp += fuzzer_havoc_settings.ST_MUT_SWAP_PROBABILITY;
911 structural_mutation_distribution.push_back(temp);
912 fuzzer_havoc_settings.structural_mutation_distribution = structural_mutation_distribution;
915 temp += fuzzer_havoc_settings.VAL_MUT_LLVM_MUTATE_PROBABILITY;
916 value_mutation_distribution.push_back(temp);
917 temp += fuzzer_havoc_settings.VAL_MUT_SMALL_ADDITION_PROBABILITY;
918 value_mutation_distribution.push_back(temp);
920 temp += fuzzer_havoc_settings.VAL_MUT_SPECIAL_VALUE_PROBABILITY;
921 value_mutation_distribution.push_back(temp);
922 fuzzer_havoc_settings.value_mutation_distribution = value_mutation_distribution;
926#ifndef DISABLE_CUSTOM_MUTATORS
931extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* Data,
size_t Size,
size_t MaxSize,
unsigned int Seed)
936 if ((fast_random.next() % 200) < fuzzer_havoc_settings.GEN_LLVM_POST_MUTATION_PROB) {
937 size_occupied = LLVMFuzzerMutate(Data, size_occupied, MaxSize);
939 return size_occupied;
946extern "C" size_t LLVMFuzzerCustomCrossOver(
const uint8_t* Data1,
948 const uint8_t* Data2,
968extern "C" size_t LLVMFuzzerTestOneInput(
const uint8_t* Data,
size_t Size)
970 RunWithBuilders<ByteArrayFuzzBase, FuzzerCircuitTypes>(Data, Size, VarianceRNG);
974#pragma clang diagnostic pop
static size_t writeInstructionsToBuffer(std::vector< typename T::Instruction > &instructions, uint8_t *Data, size_t MaxSize)
Write instructions into the buffer until there are no instructions left or there is no more space.
Definition: fuzzer.hpp:561
static std::vector< typename T::Instruction > parseDataIntoInstructions(const uint8_t *Data, size_t Size)
Parses a given data buffer into a vector of instructions for testing the arithmetic.
Definition: fuzzer.hpp:520
static size_t MutateInstructionBuffer(uint8_t *Data, size_t Size, size_t MaxSize, FastRandom &rng)
Interpret the data buffer as a series of arithmetic instructions and mutate it accordingly.
Definition: fuzzer.hpp:670
static std::vector< typename T::Instruction > crossoverInstructionVector(const std::vector< typename T::Instruction > &vecA, const std::vector< typename T::Instruction > &vecB, FastRandom &rng)
Splice two instruction vectors into one randomly.
Definition: fuzzer.hpp:458
Definition: byte_array.fuzzer.hpp:242
This class implements the execution of safeuint with an oracle to detect discrepancies.
Definition: byte_array.fuzzer.hpp:367
static size_t execute_CONSTANT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the constant instruction (push constant safeuint to the stack)
Definition: byte_array.fuzzer.hpp:587
static size_t execute_SLICE(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the slice instruction.
Definition: byte_array.fuzzer.hpp:637
static size_t execute_SET(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SET instruction.
Definition: byte_array.fuzzer.hpp:748
static size_t execute_ADD(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the ADD (append) instruction.
Definition: byte_array.fuzzer.hpp:718
static size_t execute_RANDOMSEED(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the RANDOMSEED instruction.
Definition: byte_array.fuzzer.hpp:776
static size_t execute_GET_BIT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the GET_BIT instruction.
Definition: byte_array.fuzzer.hpp:667
static size_t execute_SET_BIT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SET_BIT instruction.
Definition: byte_array.fuzzer.hpp:696
static size_t execute_REVERSE(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the REVERSE instruction.
Definition: byte_array.fuzzer.hpp:607
A class representing a single fuzzing instruction.
Definition: byte_array.fuzzer.hpp:48
static Instruction generateRandom(T &rng)
Generate a random instruction.
Definition: byte_array.fuzzer.hpp:110
static Instruction mutateInstruction(Instruction instruction, T &rng, HavocSettings &havoc_config)
Mutate a single instruction.
Definition: byte_array.fuzzer.hpp:181
Parser class handles the parsing and writing the instructions back to data buffer.
Definition: byte_array.fuzzer.hpp:257
static void writeInstruction(Instruction &instruction, uint8_t *Data)
Write a single instruction to buffer.
Definition: byte_array.fuzzer.hpp:318
static Instruction parseInstructionArgs(uint8_t *Data)
Parse a single instruction from data.
Definition: byte_array.fuzzer.hpp:266
The class parametrizing ByteArray fuzzing instructions, execution, etc.
Definition: byte_array.fuzzer.hpp:32
static bool postProcess(Builder *builder, std::vector< ByteArrayFuzzBase::ExecutionHandler > &stack)
Check that the resulting values are equal to expected.
Definition: byte_array.fuzzer.hpp:798
Class for quickly deterministically creating new random values. We don't care about distribution much...
Definition: fuzzer.hpp:64
Definition: uint256.hpp:25
Definition: standard_circuit_builder.hpp:12
Definition: byte_array.hpp:9
bool_t< Builder > get_bit(size_t index) const
Extract a bit from the byte array.
Definition: byte_array.cpp:298
void set_bit(size_t index, bool_t< Builder > const &value)
Set a bit in the byte array.
Definition: byte_array.cpp:320
byte_array reverse() const
Reverse the bytes in the byte array.
Definition: byte_array.cpp:264
Definition: safe_uint.hpp:17
Concept for a simple PRNG which returns a uint32_t when next is called.
Definition: fuzzer.hpp:91
Definition: byte_array.fuzzer.hpp:51
Definition: byte_array.fuzzer.hpp:78
Definition: byte_array.fuzzer.hpp:83
Definition: byte_array.fuzzer.hpp:72
Definition: byte_array.fuzzer.hpp:67
Definition: byte_array.fuzzer.hpp:63
Definition: fuzzer.hpp:27
Definition: byte_array.fuzzer.hpp:89