1#include "barretenberg/numeric/random/engine.hpp"
2#include "barretenberg/stdlib/primitives/bit_array/bit_array.hpp"
3#pragma clang diagnostic push
4#pragma clang diagnostic ignored "-Wc99-designator"
6#define MAX_ARRAY_SIZE 128
10bool circuit_should_fail =
false;
14#include "barretenberg/common/fuzzer.hpp"
20#define OPERATION_TYPE_SIZE 1
22#define ELEMENT_SIZE (sizeof(fr) + 1)
23#define TWO_IN_ONE_OUT 3
24#define THREE_IN_ONE_OUT 4
25#define SLICE_ARGS_SIZE 6
35 template <
size_t NumBytes,
size_t NumWords>
36 static std::vector<uint8_t> to_vector(std::array<proof_system::plonk::stdlib::uint32<Builder>, NumWords>& a32)
39 std::vector<uint8_t> v(NumBytes);
40 for (
size_t i = 0; i < a32.size(); i++) {
41 const uint32_t u32 = htonl(
static_cast<uint32_t
>(a32[i].get_value()));
42 memcpy(v.data() + (i * 4), &u32, 4);
48 template <
size_t NumWords>
49 static std::vector<uint8_t> vector_via_populate_uint32_array(
bit_array_t& bit_array,
const size_t offset = 0)
52 static_assert(NumWords != 0);
54 constexpr size_t NumBits = NumWords * 32;
55 constexpr size_t NumBytes = NumWords * 4;
57 if (offset > bit_array.size() || (bit_array.size() - offset) % 32 != 0) {
62 }
else if (bit_array.size() - offset == NumBits) {
63 std::array<proof_system::plonk::stdlib::uint32<Builder>, NumWords> a32;
64 bit_array.template populate_uint32_array<NumWords>(offset, a32);
65 return to_vector<NumBytes, NumWords>(a32);
68 return vector_via_populate_uint32_array<NumWords - 1>(bit_array, offset);
72 template <>
static std::vector<uint8_t> vector_via_populate_uint32_array<0>(
bit_array_t&,
const size_t)
77 template <
size_t NumBytes>
78 static std::vector<uint8_t> bit_array_to_a32(
bit_array_t& bit_array,
const bool cast_or_populate)
81 static_assert(NumBytes != 0);
84 static_assert(NumBytes % 4 == 0);
86 constexpr size_t NumWords = NumBytes / 4;
87 constexpr size_t NumBits = NumBytes * 8;
89 if (bit_array.size() % 32 != 0) {
94 }
else if (bit_array.size() == NumBits) {
95 std::array<proof_system::plonk::stdlib::uint32<Builder>, NumWords> a32;
98 if (cast_or_populate) {
99 a32 =
static_cast<decltype(a32)
>(bit_array);
101 bit_array.template populate_uint32_array<NumWords>(0, a32);
104 return to_vector<NumBytes, NumWords>(a32);
107 return bit_array_to_a32<NumBytes - 4>(bit_array, cast_or_populate);
111 template <> std::vector<uint8_t> bit_array_to_a32<0>(
bit_array_t&,
const bool) {
return {}; }
113 template <
class From,
class To>
static To from_to(
const From& in,
const std::optional<size_t> size = std::nullopt)
115 return To(in.data(), in.data() + (size ? *size : in.size()));
125 enum OPCODE { CONSTANT, GET_BIT, SET_BIT, SLICE, SET, RANDOMSEED, _LAST };
128 std::array<uint8_t, MAX_ARRAY_SIZE> data;
131 uint16_t real_size(
void)
const {
return std::min(size,
static_cast<uint16_t
>(MAX_ARRAY_SIZE)); }
132 std::string as_string(
void)
const {
return from_to<decltype(data), std::string>(data, real_size()); }
173 template <
typename T>
178 OPCODE instruction_opcode =
static_cast<OPCODE
>(rng.next() % (OPCODE::_LAST));
179 uint8_t in1, out, value;
183 switch (instruction_opcode) {
184 case OPCODE::CONSTANT:
187 std::array<uint8_t, MAX_ARRAY_SIZE> data;
188 for (
size_t i = 0; i < MAX_ARRAY_SIZE; i++) {
189 data[i] = rng.next() & 0xFF;
192 const uint16_t size = rng.next() & 0xFFFF;
193 return { .id = instruction_opcode, .arguments.element = { .data = data, .size = size } };
196 case OPCODE::GET_BIT:
197 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
198 out =
static_cast<uint8_t
>(rng.next() & 0xff);
199 bit =
static_cast<uint32_t
>(rng.next() & 0xffffffff);
200 return { .id = instruction_opcode, .arguments.getBitArgs = { .in = in1, .out = out, .bit = bit } };
201 case OPCODE::SET_BIT:
202 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
203 bit =
static_cast<uint32_t
>(rng.next() & 0xffffffff);
204 value =
static_cast<uint8_t
>(rng.next() & 0xff);
205 return { .id = instruction_opcode, .arguments.setBitArgs = { .in = in1, .bit = bit, .value = value } };
207 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
208 out =
static_cast<uint8_t
>(rng.next() & 0xff);
209 offset =
static_cast<uint16_t
>(rng.next() & 0xffff);
210 return { .id = instruction_opcode, .arguments.sliceArgs = { .in = in1, .out = out, .offset = offset } };
212 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
213 out =
static_cast<uint8_t
>(rng.next() & 0xff);
214 return { .id = instruction_opcode, .arguments.twoArgs = { .in = in1, .out = out } };
215 case OPCODE::RANDOMSEED:
216 return { .id = instruction_opcode, .arguments.randomseed = rng.next() };
233 template <
typename T>
239#define PUT_RANDOM_BYTE_IF_LUCKY(variable) \
240 if (rng.next() & 1) { \
241 variable = rng.next() & 0xff; \
243#define PUT_RANDOM_TWO_BYTES_IF_LUCKY(variable) \
244 if (rng.next() & 1) { \
245 variable = rng.next() & 0xffff; \
247#define PUT_RANDOM_FOUR_BYTES_IF_LUCKY(variable) \
248 if (rng.next() & 1) { \
249 variable = rng.next() & 0xffffffff; \
252 switch (instruction.id) {
253 case OPCODE::CONSTANT:
255 case OPCODE::GET_BIT:
256 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.getBitArgs.in)
257 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.getBitArgs.out)
258 PUT_RANDOM_FOUR_BYTES_IF_LUCKY(instruction.arguments.getBitArgs.bit)
260 case OPCODE::SET_BIT:
261 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.setBitArgs.in)
262 PUT_RANDOM_FOUR_BYTES_IF_LUCKY(instruction.arguments.setBitArgs.bit)
263 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.setBitArgs.value)
266 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.sliceArgs.in)
267 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.sliceArgs.out)
268 PUT_RANDOM_TWO_BYTES_IF_LUCKY(instruction.arguments.sliceArgs.offset)
271 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.twoArgs.in)
272 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.twoArgs.out)
274 case OPCODE::RANDOMSEED:
275 instruction.arguments.randomseed = rng.next();
289 static constexpr size_t CONSTANT = MAX_ARRAY_SIZE +
sizeof(uint16_t);
290 static constexpr size_t GET_BIT = 6;
291 static constexpr size_t SET_BIT = 6;
292 static constexpr size_t SLICE = 4;
293 static constexpr size_t SET = 2;
294 static constexpr size_t RANDOMSEED =
sizeof(uint32_t);
311 if constexpr (opcode == Instruction::OPCODE::CONSTANT) {
312 std::array<uint8_t, MAX_ARRAY_SIZE> data;
313 std::copy_n(Data, data.size(), data.begin());
316 memcpy(&size, Data + MAX_ARRAY_SIZE,
sizeof(uint16_t));
318 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
319 .arguments.element = { .data = data, .size = size } };
321 if constexpr (opcode == Instruction::OPCODE::GET_BIT) {
322 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
323 .arguments.getBitArgs = {
324 .in = *Data, .out = *(Data + 1), .bit = *((uint32_t*)(Data + 2)) } };
326 if constexpr (opcode == Instruction::OPCODE::SET_BIT) {
327 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
328 .arguments.setBitArgs = {
329 .in = *Data, .bit = *((uint32_t*)(Data + 1)), .value = *(Data + 5) } };
331 if constexpr (opcode == Instruction::OPCODE::SLICE) {
332 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
333 .arguments.sliceArgs = {
334 .in = *Data, .out = *(Data + 1), .offset = *((uint16_t*)(Data + 2)) } };
336 if constexpr (opcode == Instruction::OPCODE::SET) {
337 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
338 .arguments.twoArgs = { .in = *Data, .out = *(Data + 1) } };
340 if constexpr (opcode == Instruction::OPCODE::RANDOMSEED) {
342 memcpy(&randomseed, Data,
sizeof(uint32_t));
343 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
344 .arguments.randomseed = randomseed };
354 template <
typename Instruction::OPCODE instruction_opcode>
357 if constexpr (instruction_opcode == Instruction::OPCODE::CONSTANT) {
358 *Data = instruction.id;
359 memcpy(Data + 1, instruction.arguments.element.data.data(), MAX_ARRAY_SIZE);
360 memcpy(Data + 1 + MAX_ARRAY_SIZE, &instruction.arguments.element.size,
sizeof(uint16_t));
362 if constexpr (instruction_opcode == Instruction::OPCODE::GET_BIT) {
363 *Data = instruction.id;
364 *(Data + 1) = instruction.arguments.getBitArgs.in;
365 *(Data + 2) = instruction.arguments.getBitArgs.out;
366 *((uint32_t*)(Data + 3)) = instruction.arguments.getBitArgs.bit;
368 if constexpr (instruction_opcode == Instruction::OPCODE::SET_BIT) {
369 *Data = instruction.id;
370 *(Data + 1) = instruction.arguments.setBitArgs.in;
371 *((uint32_t*)(Data + 2)) = instruction.arguments.setBitArgs.bit;
372 *(Data + 6) = instruction.arguments.setBitArgs.value;
374 if constexpr (instruction_opcode == Instruction::OPCODE::SLICE) {
375 *Data = instruction.id;
376 *(Data + 1) = instruction.arguments.sliceArgs.in;
377 *(Data + 2) = instruction.arguments.sliceArgs.out;
378 *((uint16_t*)(Data + 3)) = instruction.arguments.sliceArgs.offset;
380 if constexpr (instruction_opcode == Instruction::OPCODE::SET) {
381 *Data = instruction.id;
382 *(Data + 1) = instruction.arguments.twoArgs.in;
383 *(Data + 2) = instruction.arguments.twoArgs.out;
385 if constexpr (instruction_opcode == Instruction::OPCODE::RANDOMSEED) {
387 *Data = instruction.id;
388 memcpy(Data + 1, &instruction.arguments.randomseed,
sizeof(uint32_t));
398 std::vector<uint8_t> reference_value;
400 bit_array_t bit_array{
nullptr, std::vector<uint8_t>{} };
402 static bool get_bit(
const std::vector<uint8_t>& v,
size_t bit,
const bool rev =
true)
404 const size_t pos = rev ? v.size() - 1 - (bit / 8) : (bit / 8);
405 bit = rev ? bit % 8 : 7 - (bit % 8);
406 return static_cast<bool>(v[
410 static void set_bit(std::vector<uint8_t>& v,
size_t bit,
const bool value,
const bool rev =
true)
412 const size_t pos = rev ? v.size() - 1 - (bit / 8) : (bit / 8);
413 bit = rev ? bit % 8 : 7 - (bit % 8);
425 static std::vector<uint8_t> get_value(
bit_array_t& bit_array)
427 const uint8_t which = VarianceRNG.next() % 4;
431 return from_to<std::string, std::vector<uint8_t>>(bit_array.get_witness_as_string());
433 const auto bits = bit_array.get_bits();
434 std::vector<uint8_t> ret((bits.size() + 7) / 8, 0);
435 for (
size_t i = 0; i < bits.size(); i++) {
436 set_bit(ret, i, bits[i].get_value());
441 return static_cast<byte_array_t>(bit_array).get_value();
443 return bit_array_to_a32<MAX_ARRAY_SIZE>(bit_array,
static_cast<bool>(VarianceRNG.next() % 2));
444 static_assert(MAX_ARRAY_SIZE % 32 == 0);
445 if (bit_array.size() == MAX_ARRAY_SIZE / 32) {
446 std::array<uint32_t, MAX_ARRAY_SIZE> a32;
448 static_cast<std::array<proof_system::plonk::stdlib::uint32<Builder>, MAX_ARRAY_SIZE
>>(
450 for (
size_t i = 0; i < a32_.size(); i++) {
451 a32[i] =
static_cast<uint32_t
>(a32_[i].get_value());
453 return from_to<std::array<uint32_t, MAX_ARRAY_SIZE>, std::vector<uint8_t>>(a32);
455 return static_cast<byte_array_t>(bit_array).get_value();
461 static std::vector<uint8_t> v32_to_v8(
const std::vector<uint32_t>& v)
463 return from_to<std::vector<uint32_t>, std::vector<uint8_t>>(v);
465 static const std::vector<uint8_t>& bool_to_vector(
const bool& b)
467 static const std::vector<uint8_t> false_{ 0 };
468 static const std::vector<uint8_t> true_{ 1 };
469 return b ? true_ : false_;
481 : reference_value(get_value(s))
487 if (bit >= this->reference_value.size() * 8) {
490 const bool is_set_ref = get_bit(this->reference_value, bit);
491 const bool is_set_ba = this->bit_array[bit].get_value();
497 void set_bit(
const size_t bit,
const bool value)
499 if (bit < this->reference_value.size() * 8) {
500 set_bit(this->reference_value, bit, value);
501 this->bit_array[bit] = value;
507 static_assert(MAX_ARRAY_SIZE % 4 == 0);
508 const auto v_ba = vector_via_populate_uint32_array<MAX_ARRAY_SIZE / 4>(this->bit_array, offset);
510 std::vector<uint8_t> v_ref;
512 const auto& ref = this->reference_value;
513 const size_t ref_num_bits = ref.size() * 8;
514 const size_t out_num_bits = ref_num_bits - offset;
515 const size_t out_num_bytes = out_num_bits / 8;
516 if (offset > ref_num_bits || out_num_bits % 32 != 0) {
519 v_ref.resize(out_num_bytes);
520 for (
size_t i = 0; i < out_num_bits; i++) {
521 set_bit(v_ref, i, get_bit(ref, i + offset,
false),
false);
531 const uint8_t which = VarianceRNG.next() % 6;
533 const auto& ref = this->reference_value;
550 if (this->bit_array.size() % 32 != 0) {
553 const auto v = this->bit_array.to_uint32_vector();
555 if (v.size() == 1 &&
static_cast<bool>(VarianceRNG.next() % 2)) {
569 const size_t gibberish_size = VarianceRNG.next() % (MAX_ARRAY_SIZE * 2);
570 std::vector<uint8_t> gibberish(gibberish_size);
571 for (
size_t i = 0; i < gibberish_size; i++) {
572 gibberish[i] =
static_cast<uint8_t
>(VarianceRNG.next() % 0xFF);
577 ba = this->bit_array;
595 std::vector<ExecutionHandler>& stack,
599 stack.push_back(
bit_array_t(builder, instruction.arguments.element.as_string()));
611 std::vector<ExecutionHandler>& stack,
615 if (stack.size() == 0) {
618 size_t first_index = instruction.arguments.getBitArgs.in % stack.size();
619 size_t output_index = instruction.arguments.getBitArgs.out;
620 const uint32_t bit = instruction.arguments.getBitArgs.bit;
622 result = stack[first_index].get_bit(builder, bit);
624 if (output_index >= stack.size()) {
625 stack.push_back(result);
627 stack[output_index] = result;
640 std::vector<ExecutionHandler>& stack,
644 if (stack.size() == 0) {
647 size_t first_index = instruction.arguments.setBitArgs.in % stack.size();
648 const uint32_t bit = instruction.arguments.setBitArgs.bit;
649 const bool value =
static_cast<bool>(instruction.arguments.setBitArgs.value % 2);
650 stack[first_index].set_bit(bit, value);
662 std::vector<ExecutionHandler>& stack,
666 if (stack.size() == 0) {
669 size_t first_index = instruction.arguments.sliceArgs.in % stack.size();
670 size_t output_index = instruction.arguments.sliceArgs.out;
671 const uint16_t offset = instruction.arguments.sliceArgs.offset;
673 result = stack[first_index].slice(builder, offset);
675 if (output_index >= stack.size()) {
676 stack.push_back(result);
678 stack[output_index] = result;
691 std::vector<ExecutionHandler>& stack,
695 if (stack.size() == 0) {
698 size_t first_index = instruction.arguments.twoArgs.in % stack.size();
699 size_t output_index = instruction.arguments.twoArgs.out;
701 result = stack[first_index].set(builder);
703 if (output_index >= stack.size()) {
704 stack.push_back(result);
706 stack[output_index] = result;
719 std::vector<ExecutionHandler>& stack,
725 VarianceRNG.reseed(instruction.arguments.randomseed);
730 typedef std::vector<ExecutionHandler> ExecutionState;
740 inline static bool postProcess(
Builder* builder, std::vector<BitArrayFuzzBase::ExecutionHandler>& stack)
743 for (
size_t i = 0; i < stack.size(); i++) {
744 auto element = stack[i];
745 const auto other = from_to<std::string, std::vector<uint8_t>>(element.bit_array.get_witness_as_string());
746 if (other != element.reference_value) {
747 printf(
"Other (as bytes):\n");
748 for (
size_t i = 0; i < other.size(); i++) {
749 printf(
"%02X ", other[i]);
752 printf(
"Reference value (as bytes):\n");
753 for (
size_t i = 0; i < element.reference_value.size(); i++) {
754 printf(
"%02X ", element.reference_value[i]);
766extern "C" int LLVMFuzzerInitialize(
int* argc,
char*** argv)
773 .GEN_LLVM_POST_MUTATION_PROB = 30,
774 .GEN_MUTATION_COUNT_LOG = 5,
775 .GEN_STRUCTURAL_MUTATION_PROBABILITY = 300,
776 .GEN_VALUE_MUTATION_PROBABILITY = 700,
777 .ST_MUT_DELETION_PROBABILITY = 100,
778 .ST_MUT_DUPLICATION_PROBABILITY = 80,
779 .ST_MUT_INSERTION_PROBABILITY = 120,
780 .ST_MUT_MAXIMUM_DELETION_LOG = 6,
781 .ST_MUT_MAXIMUM_DUPLICATION_LOG = 2,
782 .ST_MUT_SWAP_PROBABILITY = 50,
783 .VAL_MUT_LLVM_MUTATE_PROBABILITY = 250,
784 .VAL_MUT_MONTGOMERY_PROBABILITY = 130,
785 .VAL_MUT_NON_MONTGOMERY_PROBABILITY = 50,
786 .VAL_MUT_SMALL_ADDITION_PROBABILITY = 110,
787 .VAL_MUT_SPECIAL_VALUE_PROBABILITY = 130
854 std::vector<size_t> structural_mutation_distribution;
855 std::vector<size_t> value_mutation_distribution;
857 temp += fuzzer_havoc_settings.ST_MUT_DELETION_PROBABILITY;
858 structural_mutation_distribution.push_back(temp);
859 temp += fuzzer_havoc_settings.ST_MUT_DUPLICATION_PROBABILITY;
860 structural_mutation_distribution.push_back(temp);
861 temp += fuzzer_havoc_settings.ST_MUT_INSERTION_PROBABILITY;
862 structural_mutation_distribution.push_back(temp);
863 temp += fuzzer_havoc_settings.ST_MUT_SWAP_PROBABILITY;
864 structural_mutation_distribution.push_back(temp);
865 fuzzer_havoc_settings.structural_mutation_distribution = structural_mutation_distribution;
868 temp += fuzzer_havoc_settings.VAL_MUT_LLVM_MUTATE_PROBABILITY;
869 value_mutation_distribution.push_back(temp);
870 temp += fuzzer_havoc_settings.VAL_MUT_SMALL_ADDITION_PROBABILITY;
871 value_mutation_distribution.push_back(temp);
873 temp += fuzzer_havoc_settings.VAL_MUT_SPECIAL_VALUE_PROBABILITY;
874 value_mutation_distribution.push_back(temp);
875 fuzzer_havoc_settings.value_mutation_distribution = value_mutation_distribution;
879#ifndef DISABLE_CUSTOM_MUTATORS
884extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* Data,
size_t Size,
size_t MaxSize,
unsigned int Seed)
889 if ((fast_random.next() % 200) < fuzzer_havoc_settings.GEN_LLVM_POST_MUTATION_PROB) {
890 size_occupied = LLVMFuzzerMutate(Data, size_occupied, MaxSize);
892 return size_occupied;
899extern "C" size_t LLVMFuzzerCustomCrossOver(
const uint8_t* Data1,
901 const uint8_t* Data2,
921extern "C" size_t LLVMFuzzerTestOneInput(
const uint8_t* Data,
size_t Size)
923 RunWithBuilders<BitArrayFuzzBase, FuzzerCircuitTypes>(Data, Size, VarianceRNG);
927#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: bit_array.fuzzer.hpp:287
This class implements the execution of safeuint with an oracle to detect discrepancies.
Definition: bit_array.fuzzer.hpp:396
static size_t execute_SET(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SET instruction.
Definition: bit_array.fuzzer.hpp:690
static size_t execute_GET_BIT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the GET_BIT instruction.
Definition: bit_array.fuzzer.hpp:610
static size_t execute_RANDOMSEED(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the RANDOMSEED instruction.
Definition: bit_array.fuzzer.hpp:718
static size_t execute_SET_BIT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SET_BIT instruction.
Definition: bit_array.fuzzer.hpp:639
static size_t execute_SLICE(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SLICE instruction.
Definition: bit_array.fuzzer.hpp:661
static size_t execute_CONSTANT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the constant instruction (push constant safeuint to the stack)
Definition: bit_array.fuzzer.hpp:594
A class representing a single fuzzing instruction.
Definition: bit_array.fuzzer.hpp:123
static Instruction generateRandom(T &rng)
Generate a random instruction.
Definition: bit_array.fuzzer.hpp:174
static Instruction mutateInstruction(Instruction instruction, T &rng, HavocSettings &havoc_config)
Mutate a single instruction.
Definition: bit_array.fuzzer.hpp:234
Parser class handles the parsing and writing the instructions back to data buffer.
Definition: bit_array.fuzzer.hpp:300
static void writeInstruction(Instruction &instruction, uint8_t *Data)
Write a single instruction to buffer.
Definition: bit_array.fuzzer.hpp:355
static Instruction parseInstructionArgs(uint8_t *Data)
Parse a single instruction from data.
Definition: bit_array.fuzzer.hpp:309
The class parametrizing ByteArray fuzzing instructions, execution, etc.
Definition: bit_array.fuzzer.hpp:31
static bool postProcess(Builder *builder, std::vector< BitArrayFuzzBase::ExecutionHandler > &stack)
Check that the resulting values are equal to expected.
Definition: bit_array.fuzzer.hpp:740
Class for quickly deterministically creating new random values. We don't care about distribution much...
Definition: fuzzer.hpp:64
Definition: standard_circuit_builder.hpp:12
Definition: bit_array.hpp:9
Definition: byte_array.hpp:9
Concept for a simple PRNG which returns a uint32_t when next is called.
Definition: fuzzer.hpp:91
Definition: bit_array.fuzzer.hpp:126
Definition: bit_array.fuzzer.hpp:134
Definition: bit_array.fuzzer.hpp:139
Definition: bit_array.fuzzer.hpp:144
Definition: bit_array.fuzzer.hpp:149
Definition: fuzzer.hpp:27
Definition: bit_array.fuzzer.hpp:154