Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
bool.fuzzer.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
8#pragma clang diagnostic push
9#pragma clang diagnostic ignored "-Wc99-designator"
10// This is a global variable, so that the execution handling class could alter it and signal to the input tester that
11// the input should fail
13
14#define HAVOC_TESTING
15
18
19// Enable this definition, when you want to find out the instructions that caused a failure
20// #define FUZZING_SHOW_INFORMATION 1
21
22#define OPERATION_TYPE_SIZE 1
23
24#define ELEMENT_SIZE (sizeof(fr) + 1)
25#define TWO_IN_ONE_OUT 3
26#define THREE_IN_ONE_OUT 4
27#define SLICE_ARGS_SIZE 6
28
33template <typename Builder> class BoolFuzzBase {
34 private:
37
38 public:
44 public:
46 struct TwoArgs {
47 uint8_t in;
48 uint8_t out;
49 };
50 struct ThreeArgs {
51 uint8_t in1;
52 uint8_t in2;
53 uint8_t out;
54 };
55 struct FourArgs {
56 uint8_t in1;
57 uint8_t in2;
58 uint8_t in3;
59 uint8_t out;
60 };
61
69 // The type of instruction
71 // Instruction arguments
80 template <typename T>
81 inline static Instruction generateRandom(T& rng)
82 requires SimpleRng<T>
83 {
84 // Choose which instruction we are going to generate
85 OPCODE instruction_opcode = static_cast<OPCODE>(rng.next() % (OPCODE::_LAST));
86 uint8_t in1, in2, in3, out;
87 // Depending on instruction
88 switch (instruction_opcode) {
90 case OPCODE::WITNESS:
91 // Return instruction
92 return { .id = instruction_opcode, .arguments.element = static_cast<bool>(rng.next() % 2) };
93 break;
94 case OPCODE::AND:
95 case OPCODE::OR:
96 case OPCODE::XOR:
97 // For two-input-one-output instructions we just randomly pick each argument and generate an instruction
98 // accordingly
99 in1 = static_cast<uint8_t>(rng.next() & 0xff);
100 in2 = static_cast<uint8_t>(rng.next() & 0xff);
101 out = static_cast<uint8_t>(rng.next() & 0xff);
102 return { .id = instruction_opcode, .arguments.threeArgs = { .in1 = in1, .in2 = in2, .out = out } };
103 break;
105 // For three-input-one-output instructions we just randomly pick each argument and generate an
106 // instruction accordingly
107 in1 = static_cast<uint8_t>(rng.next() & 0xff);
108 in2 = static_cast<uint8_t>(rng.next() & 0xff);
109 in3 = static_cast<uint8_t>(rng.next() & 0xff);
110 out = static_cast<uint8_t>(rng.next() & 0xff);
111 return { .id = instruction_opcode,
112 .arguments.fourArgs{ .in1 = in1, .in2 = in2, .in3 = in3, .out = out } };
113 break;
114 case OPCODE::NOT:
116 case OPCODE::SET:
117 in1 = static_cast<uint8_t>(rng.next() & 0xff);
118 out = static_cast<uint8_t>(rng.next() & 0xff);
119 return { .id = instruction_opcode, .arguments.twoArgs = { .in = in1, .out = out } };
121 return { .id = instruction_opcode, .arguments.randomseed = rng.next() };
122 break;
123 default:
124 abort(); // We have missed some instructions, it seems
125 break;
126 }
127 }
128
138 template <typename T>
140 requires SimpleRng<T>
141 {
142 (void)rng;
143 (void)havoc_config;
144#define PUT_RANDOM_BYTE_IF_LUCKY(variable) \
145 if (rng.next() & 1) { \
146 variable = rng.next() & 0xff; \
147 }
148#define PUT_RANDOM_TWO_BYTES_IF_LUCKY(variable) \
149 if (rng.next() & 1) { \
150 variable = rng.next() & 0xffff; \
151 }
152#define PUT_RANDOM_FOUR_BYTES_IF_LUCKY(variable) \
153 if (rng.next() & 1) { \
154 variable = rng.next() & 0xffffffff; \
155 }
156 // Depending on instruction type...
157 switch (instruction.id) {
158 case OPCODE::CONSTANT:
159 case OPCODE::WITNESS:
160 break;
161 case OPCODE::AND:
162 case OPCODE::OR:
163 case OPCODE::XOR:
164 // Randomly sample each of the arguments with 50% probability
165 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.threeArgs.in1)
166 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.threeArgs.in2)
167 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.threeArgs.out)
168 break;
170 // Randomly sample each of the arguments with 50% probability
171 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.fourArgs.in1)
172 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.fourArgs.in2)
173 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.fourArgs.in3)
174 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.fourArgs.out)
175 break;
176 case OPCODE::NOT:
178 case OPCODE::SET:
179 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.twoArgs.in)
180 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.twoArgs.out)
181 break;
183 instruction.arguments.randomseed = rng.next();
184 break;
185 default:
186 abort(); // New instruction encountered
187 break;
188 }
189 // Return mutated instruction
190 return instruction;
191 }
192 };
193 // We use argsizes to both specify the size of data needed to parse the instruction and to signal that the
194 // instruction is enabled (if it is -1,it's disabled )
195 class ArgSizes {
196 public:
197 static constexpr size_t CONSTANT = 1;
198 static constexpr size_t WITNESS = 1;
199 static constexpr size_t AND = 3;
200 static constexpr size_t OR = 3;
201 static constexpr size_t XOR = 3;
202 static constexpr size_t SELECT_IF_EQ = 4;
203 static constexpr size_t NOT = 2;
204 static constexpr size_t ASSERT_EQUAL = 2;
205 static constexpr size_t SET = 2;
206 static constexpr size_t RANDOMSEED = sizeof(uint32_t);
207 };
212 class Parser {
213 public:
221 template <typename Instruction::OPCODE opcode> inline static Instruction parseInstructionArgs(uint8_t* Data)
222 {
223 if constexpr (opcode == Instruction::OPCODE::CONSTANT || opcode == Instruction::OPCODE::WITNESS) {
224 return Instruction{ .id = static_cast<typename Instruction::OPCODE>(opcode),
225 .arguments.element = static_cast<bool>(*Data) };
226 }
227 if constexpr (opcode == Instruction::OPCODE::AND || opcode == Instruction::OPCODE::OR ||
228 opcode == Instruction::OPCODE::XOR) {
229 return { .id = static_cast<typename Instruction::OPCODE>(opcode),
230 .arguments.threeArgs = { .in1 = *Data, .in2 = *(Data + 1), .out = *(Data + 2) } };
231 }
232 if constexpr (opcode == Instruction::OPCODE::NOT || opcode == Instruction::OPCODE::ASSERT_EQUAL ||
233 opcode == Instruction::OPCODE::SET) {
234 return Instruction{ .id = static_cast<typename Instruction::OPCODE>(opcode),
235 .arguments.twoArgs = { .in = *Data, .out = *(Data + 1) } };
236 }
237 if constexpr (opcode == Instruction::OPCODE::SELECT_IF_EQ) {
238
239 return { .id = static_cast<typename Instruction::OPCODE>(opcode),
240 .arguments.fourArgs = {
241 .in1 = *Data, .in2 = *(Data + 1), .in3 = *(Data + 2), .out = *(Data + 3) } };
242 }
243 if constexpr (opcode == Instruction::OPCODE::RANDOMSEED) {
244 uint32_t randomseed;
245 memcpy(&randomseed, Data, sizeof(uint32_t));
246 return Instruction{ .id = static_cast<typename Instruction::OPCODE>(opcode),
247 .arguments.randomseed = randomseed };
248 };
249 }
257 template <typename Instruction::OPCODE instruction_opcode>
258 inline static void writeInstruction(Instruction& instruction, uint8_t* Data)
259 {
260 if constexpr (instruction_opcode == Instruction::OPCODE::CONSTANT ||
261 instruction_opcode == Instruction::OPCODE::WITNESS) {
262 *Data = instruction.id;
263 *(Data + 1) = instruction.arguments.element ? 1 : 0;
264 }
265 if constexpr (instruction_opcode == Instruction::OPCODE::AND ||
266 instruction_opcode == Instruction::OPCODE::OR ||
267 instruction_opcode == Instruction::OPCODE::XOR) {
268 *Data = instruction.id;
269 *(Data + 1) = instruction.arguments.threeArgs.in1;
270 *(Data + 2) = instruction.arguments.threeArgs.in2;
271 *(Data + 3) = instruction.arguments.threeArgs.out;
272 }
273 if constexpr (instruction_opcode == Instruction::OPCODE::NOT ||
274 instruction_opcode == Instruction::OPCODE::ASSERT_EQUAL ||
275 instruction_opcode == Instruction::OPCODE::SET) {
276 *Data = instruction.id;
277 *(Data + 1) = instruction.arguments.twoArgs.in;
278 *(Data + 2) = instruction.arguments.twoArgs.out;
279 }
280 if constexpr (instruction_opcode == Instruction::OPCODE::SELECT_IF_EQ) {
281 *Data = instruction.id;
282 *(Data + 1) = instruction.arguments.fourArgs.in1;
283 *(Data + 2) = instruction.arguments.fourArgs.in2;
284 *(Data + 3) = instruction.arguments.fourArgs.in3;
285 *(Data + 4) = instruction.arguments.fourArgs.out;
286 }
287 if constexpr (instruction_opcode == Instruction::OPCODE::RANDOMSEED) {
288
289 *Data = instruction.id;
290 memcpy(Data + 1, &instruction.arguments.randomseed, sizeof(uint32_t));
291 }
292 }
293 };
299 public:
302
303 ExecutionHandler() = default;
305 : reference_value(r)
306 , b(b)
307 {}
309 : reference_value(b.get_value())
310 , b(b)
311 {}
312
314 {
315 const bool ref_result(this->reference_value & other.reference_value);
316
317 switch (VarianceRNG.next() % 2) {
318 case 0:
319 /* ^ operator */
320 return ExecutionHandler(ref_result, bool_t(this->b & other.b));
321 case 1:
322 /* ^= operator */
323 {
324 bool_t b = this->b;
325 b &= other.b;
326 return ExecutionHandler(ref_result, b);
327 }
328 default:
329 abort();
330 }
331 }
333 {
334 const bool ref_result(this->reference_value | other.reference_value);
335
336 switch (VarianceRNG.next() % 2) {
337 case 0:
338 /* ^ operator */
339 return ExecutionHandler(ref_result, bool_t(this->b | other.b));
340 case 1:
341 /* ^= operator */
342 {
343 bool_t b = this->b;
344 b |= other.b;
345 return ExecutionHandler(ref_result, b);
346 }
347 default:
348 abort();
349 }
350 }
352 {
353 const bool ref_result(this->reference_value ^ other.reference_value);
354
355 switch (VarianceRNG.next() % 2) {
356 case 0:
357 /* ^ operator */
358 return ExecutionHandler(ref_result, bool_t(this->b ^ other.b));
359 case 1:
360 /* ^= operator */
361 {
362 bool_t b = this->b;
363 b ^= other.b;
364 return ExecutionHandler(ref_result, b);
365 }
366 default:
367 abort();
368 }
369 }
370
371 ExecutionHandler not_() const { return ExecutionHandler(!this->reference_value, bool_t(!this->b)); }
373 {
374 /* TODO */
375 return;
376
377 if (this->b.is_constant() && other.b.is_constant()) {
378 return;
379 }
380 if (!this->b.is_constant() && !other.b.is_constant()) {
381 return;
382 }
383 if (this->reference_value != other.reference_value) {
384 circuit_should_fail = true;
385 }
386 this->b.assert_equal(other.b);
387 }
389 {
390 return ExecutionHandler(other1.reference_value == other2.reference_value ? other1.reference_value
391 : this->reference_value,
392 (other1.b == other2.b).get_value() ? other1.b : this->b);
393 }
394
396 {
397 (void)builder;
398 switch (VarianceRNG.next() % 2) {
399 case 0:
400 return ExecutionHandler(this->reference_value, bool_t(this->reference_value));
401 case 1:
402 return ExecutionHandler(this->reference_value, bool_t(this->b));
403 default:
404 abort();
405 }
406 }
407
416 static inline size_t execute_CONSTANT(Builder* builder,
419 {
420 (void)builder;
421 stack.push_back(bool_t(builder, instruction.arguments.element));
422 return 0;
423 }
432 static inline size_t execute_WITNESS(Builder* builder,
435 {
436
437 stack.push_back(
438 ExecutionHandler(instruction.arguments.element, witness_t(builder, instruction.arguments.element)));
439 return 0;
440 }
449 static inline size_t execute_AND(Builder* builder,
452 {
453 (void)builder;
454 if (stack.size() == 0) {
455 return 1;
456 }
457 size_t first_index = instruction.arguments.threeArgs.in1 % stack.size();
458 size_t second_index = instruction.arguments.threeArgs.in2 % stack.size();
459 size_t output_index = instruction.arguments.threeArgs.out;
460
461 ExecutionHandler result;
462 result = stack[first_index] & stack[second_index];
463 // If the output index is larger than the number of elements in stack, append
464 if (output_index >= stack.size()) {
465 stack.push_back(result);
466 } else {
467 stack[output_index] = result;
468 }
469 return 0;
470 };
479 static inline size_t execute_OR(Builder* builder,
482 {
483 (void)builder;
484 if (stack.size() == 0) {
485 return 1;
486 }
487 size_t first_index = instruction.arguments.threeArgs.in1 % stack.size();
488 size_t second_index = instruction.arguments.threeArgs.in2 % stack.size();
489 size_t output_index = instruction.arguments.threeArgs.out;
490
491 ExecutionHandler result;
492 result = stack[first_index] | stack[second_index];
493 // If the output index is larger than the number of elements in stack, append
494 if (output_index >= stack.size()) {
495 stack.push_back(result);
496 } else {
497 stack[output_index] = result;
498 }
499 return 0;
500 };
509 static inline size_t execute_XOR(Builder* builder,
512 {
513 (void)builder;
514 if (stack.size() == 0) {
515 return 1;
516 }
517 size_t first_index = instruction.arguments.threeArgs.in1 % stack.size();
518 size_t second_index = instruction.arguments.threeArgs.in2 % stack.size();
519 size_t output_index = instruction.arguments.threeArgs.out;
520
521 ExecutionHandler result;
522 result = stack[first_index] ^ stack[second_index];
523 // If the output index is larger than the number of elements in stack, append
524 if (output_index >= stack.size()) {
525 stack.push_back(result);
526 } else {
527 stack[output_index] = result;
528 }
529 return 0;
530 };
539 static inline size_t execute_NOT(Builder* builder,
542 {
543 (void)builder;
544 if (stack.size() == 0) {
545 return 1;
546 }
547 size_t first_index = instruction.arguments.twoArgs.in % stack.size();
548 size_t output_index = instruction.arguments.twoArgs.out;
549
550 ExecutionHandler result;
551 result = stack[first_index].not_();
552 // If the output index is larger than the number of elements in stack, append
553 if (output_index >= stack.size()) {
554 stack.push_back(result);
555 } else {
556 stack[output_index] = result;
557 }
558 return 0;
559 };
568 static inline size_t execute_SELECT_IF_EQ(Builder* builder,
571 {
572 (void)builder;
573 if (stack.size() == 0) {
574 return 1;
575 }
576 size_t first_index = instruction.arguments.fourArgs.in1 % stack.size();
577 size_t second_index = instruction.arguments.fourArgs.in2 % stack.size();
578 size_t third_index = instruction.arguments.fourArgs.in3 % stack.size();
579 size_t output_index = instruction.arguments.fourArgs.out % stack.size();
580
581 ExecutionHandler result;
582 result = stack[first_index].select_if_eq(stack[second_index], stack[third_index]);
583 // If the output index is larger than the number of elements in stack, append
584 if (output_index >= stack.size()) {
585 stack.push_back(result);
586 } else {
587 stack[output_index] = result;
588 }
589 return 0;
590 };
599 static inline size_t execute_ASSERT_EQUAL(Builder* builder,
602 {
603 (void)builder;
604 if (stack.size() == 0) {
605 return 1;
606 }
607 size_t first_index = instruction.arguments.twoArgs.in % stack.size();
608 size_t second_index = instruction.arguments.twoArgs.out % stack.size();
609
610 stack[first_index].assert_equal(stack[second_index]);
611 return 0;
612 };
621 static inline size_t execute_SET(Builder* builder,
624 {
625 (void)builder;
626 if (stack.size() == 0) {
627 return 1;
628 }
629 size_t first_index = instruction.arguments.twoArgs.in % stack.size();
630 size_t output_index = instruction.arguments.twoArgs.out;
631 ExecutionHandler result;
632 result = stack[first_index].set(builder);
633 // If the output index is larger than the number of elements in stack, append
634 if (output_index >= stack.size()) {
635 stack.push_back(result);
636 } else {
637 stack[output_index] = result;
638 }
639 return 0;
640 };
649 static inline size_t execute_RANDOMSEED(Builder* builder,
652 {
653 (void)builder;
654 (void)stack;
655
656 VarianceRNG.reseed(instruction.arguments.randomseed);
657 return 0;
658 };
659 };
660
672 {
673 (void)builder;
674 for (size_t i = 0; i < stack.size(); i++) {
675 auto element = stack[i];
676 if (element.b.get_value() != element.reference_value) {
677 printf("Other: %d", element.b.get_value());
678 printf("Reference value: %d\n", element.reference_value);
679 return false;
680 }
681 }
682 return true;
683 }
684};
685
686#ifdef HAVOC_TESTING
687
688extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv)
689{
690 (void)argc;
691 (void)argv;
692 // These are the settings, optimized for the safeuint class (under them, fuzzer reaches maximum expected coverage in
693 // 40 seconds)
694 fuzzer_havoc_settings = HavocSettings{
695 .GEN_LLVM_POST_MUTATION_PROB = 30, // Out of 200
696 .GEN_MUTATION_COUNT_LOG = 5, // Fully checked
697 .GEN_STRUCTURAL_MUTATION_PROBABILITY = 300, // Fully checked
698 .GEN_VALUE_MUTATION_PROBABILITY = 700, // Fully checked
699 .ST_MUT_DELETION_PROBABILITY = 100, // Fully checked
700 .ST_MUT_DUPLICATION_PROBABILITY = 80, // Fully checked
701 .ST_MUT_INSERTION_PROBABILITY = 120, // Fully checked
702 .ST_MUT_MAXIMUM_DELETION_LOG = 6, // Fully checked
703 .ST_MUT_MAXIMUM_DUPLICATION_LOG = 2, // Fully checked
704 .ST_MUT_SWAP_PROBABILITY = 50, // Fully checked
705 .VAL_MUT_LLVM_MUTATE_PROBABILITY = 250, // Fully checked
706 .VAL_MUT_MONTGOMERY_PROBABILITY = 130, // Fully checked
707 .VAL_MUT_NON_MONTGOMERY_PROBABILITY = 50, // Fully checked
708 .VAL_MUT_SMALL_ADDITION_PROBABILITY = 110, // Fully checked
709 .VAL_MUT_SPECIAL_VALUE_PROBABILITY = 130 // Fully checked
710
711 };
716 /*
717 std::random_device rd;
718 std::uniform_int_distribution<uint64_t> dist(0, ~(uint64_t)(0));
719 srandom(static_cast<unsigned int>(dist(rd)));
720
721 fuzzer_havoc_settings =
722 HavocSettings{ .GEN_MUTATION_COUNT_LOG = static_cast<size_t>((random() % 8) + 1),
723 .GEN_STRUCTURAL_MUTATION_PROBABILITY = static_cast<size_t>(random() % 100),
724 .GEN_VALUE_MUTATION_PROBABILITY = static_cast<size_t>(random() % 100),
725 .ST_MUT_DELETION_PROBABILITY = static_cast<size_t>(random() % 100),
726 .ST_MUT_DUPLICATION_PROBABILITY = static_cast<size_t>(random() % 100),
727 .ST_MUT_INSERTION_PROBABILITY = static_cast<size_t>((random() % 99) + 1),
728 .ST_MUT_MAXIMUM_DELETION_LOG = static_cast<size_t>((random() % 8) + 1),
729 .ST_MUT_MAXIMUM_DUPLICATION_LOG = static_cast<size_t>((random() % 8) + 1),
730 .ST_MUT_SWAP_PROBABILITY = static_cast<size_t>(random() % 100),
731 .VAL_MUT_LLVM_MUTATE_PROBABILITY = static_cast<size_t>(random() % 100),
732 .VAL_MUT_MONTGOMERY_PROBABILITY = static_cast<size_t>(random() % 100),
733 .VAL_MUT_NON_MONTGOMERY_PROBABILITY = static_cast<size_t>(random() % 100),
734 .VAL_MUT_SMALL_ADDITION_PROBABILITY = static_cast<size_t>(random() % 100),
735 .VAL_MUT_SPECIAL_VALUE_PROBABILITY = static_cast<size_t>(random() % 100)
736
737 };
738 while (fuzzer_havoc_settings.GEN_STRUCTURAL_MUTATION_PROBABILITY == 0 &&
739 fuzzer_havoc_settings.GEN_VALUE_MUTATION_PROBABILITY == 0) {
740 fuzzer_havoc_settings.GEN_STRUCTURAL_MUTATION_PROBABILITY = static_cast<size_t>(random() % 8);
741 fuzzer_havoc_settings.GEN_VALUE_MUTATION_PROBABILITY = static_cast<size_t>(random() % 8);
742 }
743 */
744
745 // fuzzer_havoc_settings.GEN_LLVM_POST_MUTATION_PROB = static_cast<size_t>(((random() % (20 - 1)) + 1) * 10);
750 /*
751 std::cerr << "CUSTOM MUTATOR SETTINGS:" << std::endl
752 << "################################################################" << std::endl
753 << "GEN_LLVM_POST_MUTATION_PROB: " << fuzzer_havoc_settings.GEN_LLVM_POST_MUTATION_PROB << std::endl
754 << "GEN_MUTATION_COUNT_LOG: " << fuzzer_havoc_settings.GEN_MUTATION_COUNT_LOG << std::endl
755 << "GEN_STRUCTURAL_MUTATION_PROBABILITY: " << fuzzer_havoc_settings.GEN_STRUCTURAL_MUTATION_PROBABILITY
756 << std::endl
757 << "GEN_VALUE_MUTATION_PROBABILITY: " << fuzzer_havoc_settings.GEN_VALUE_MUTATION_PROBABILITY << std::endl
758 << "ST_MUT_DELETION_PROBABILITY: " << fuzzer_havoc_settings.ST_MUT_DELETION_PROBABILITY << std::endl
759 << "ST_MUT_DUPLICATION_PROBABILITY: " << fuzzer_havoc_settings.ST_MUT_DUPLICATION_PROBABILITY << std::endl
760 << "ST_MUT_INSERTION_PROBABILITY: " << fuzzer_havoc_settings.ST_MUT_INSERTION_PROBABILITY << std::endl
761 << "ST_MUT_MAXIMUM_DELETION_LOG: " << fuzzer_havoc_settings.ST_MUT_MAXIMUM_DELETION_LOG << std::endl
762 << "ST_MUT_MAXIMUM_DUPLICATION_LOG: " << fuzzer_havoc_settings.ST_MUT_MAXIMUM_DUPLICATION_LOG << std::endl
763 << "ST_MUT_SWAP_PROBABILITY: " << fuzzer_havoc_settings.ST_MUT_SWAP_PROBABILITY << std::endl
764 << "VAL_MUT_LLVM_MUTATE_PROBABILITY: " << fuzzer_havoc_settings.VAL_MUT_LLVM_MUTATE_PROBABILITY
765 << std::endl
766 << "VAL_MUT_MONTGOMERY_PROBABILITY: " << fuzzer_havoc_settings.VAL_MUT_MONTGOMERY_PROBABILITY << std::endl
767 << "VAL_MUT_NON_MONTGOMERY_PROBABILITY: " << fuzzer_havoc_settings.VAL_MUT_NON_MONTGOMERY_PROBABILITY
768 << std::endl
769 << "VAL_MUT_SMALL_ADDITION_PROBABILITY: " << fuzzer_havoc_settings.VAL_MUT_SMALL_ADDITION_PROBABILITY
770 << std::endl
771 << "VAL_MUT_SMALL_MULTIPLICATION_PROBABILITY: "
772 << fuzzer_havoc_settings.VAL_MUT_SMALL_MULTIPLICATION_PROBABILITY << std::endl
773 << "VAL_MUT_SPECIAL_VALUE_PROBABILITY: " << fuzzer_havoc_settings.VAL_MUT_SPECIAL_VALUE_PROBABILITY
774 << std::endl;
775 */
776 std::vector<size_t> structural_mutation_distribution;
777 std::vector<size_t> value_mutation_distribution;
778 size_t temp = 0;
779 temp += fuzzer_havoc_settings.ST_MUT_DELETION_PROBABILITY;
780 structural_mutation_distribution.push_back(temp);
781 temp += fuzzer_havoc_settings.ST_MUT_DUPLICATION_PROBABILITY;
782 structural_mutation_distribution.push_back(temp);
783 temp += fuzzer_havoc_settings.ST_MUT_INSERTION_PROBABILITY;
784 structural_mutation_distribution.push_back(temp);
785 temp += fuzzer_havoc_settings.ST_MUT_SWAP_PROBABILITY;
786 structural_mutation_distribution.push_back(temp);
787 fuzzer_havoc_settings.structural_mutation_distribution = structural_mutation_distribution;
788
789 temp = 0;
790 temp += fuzzer_havoc_settings.VAL_MUT_LLVM_MUTATE_PROBABILITY;
791 value_mutation_distribution.push_back(temp);
792 temp += fuzzer_havoc_settings.VAL_MUT_SMALL_ADDITION_PROBABILITY;
793 value_mutation_distribution.push_back(temp);
794
795 temp += fuzzer_havoc_settings.VAL_MUT_SPECIAL_VALUE_PROBABILITY;
796 value_mutation_distribution.push_back(temp);
797 fuzzer_havoc_settings.value_mutation_distribution = value_mutation_distribution;
798 return 0;
799}
800#endif
801
806extern "C" size_t LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size)
807{
808 RunWithBuilders<BoolFuzzBase, FuzzerCircuitTypes>(Data, Size, VarianceRNG);
809 return 0;
810}
811
812#pragma clang diagnostic pop
FastRandom VarianceRNG(0)
bool circuit_should_fail
FastRandom VarianceRNG(0)
bool circuit_should_fail
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)
static constexpr size_t XOR
static constexpr size_t WITNESS
static constexpr size_t OR
static constexpr size_t ASSERT_EQUAL
static constexpr size_t CONSTANT
static constexpr size_t SET
static constexpr size_t NOT
static constexpr size_t AND
static constexpr size_t SELECT_IF_EQ
static constexpr size_t RANDOMSEED
This class implements the execution of safeuint with an oracle to detect discrepancies.
static size_t execute_SET(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SET instruction.
static size_t execute_CONSTANT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the constant instruction (push constant bool_t to the stack)
ExecutionHandler(bool r, bool_t b)
static size_t execute_XOR(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the xor operator instruction.
static size_t execute_SELECT_IF_EQ(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SELECT_IF_EQ instruction.
static size_t execute_OR(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the or operator instruction.
static size_t execute_RANDOMSEED(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the RANDOMSEED instruction.
static size_t execute_AND(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the and operator instruction.
ExecutionHandler operator|(const ExecutionHandler &other) const
static size_t execute_NOT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the NOT instruction.
void assert_equal(ExecutionHandler &other) const
static size_t execute_WITNESS(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the witness instruction (push witness bool_t to the stack)
ExecutionHandler not_() const
ExecutionHandler operator&(const ExecutionHandler &other) const
ExecutionHandler operator^(const ExecutionHandler &other) const
ExecutionHandler select_if_eq(ExecutionHandler &other1, ExecutionHandler &other2)
static size_t execute_ASSERT_EQUAL(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the ASSERT_EQUAL instruction.
ExecutionHandler set(Builder *builder)
A class representing a single fuzzing instruction.
static Instruction generateRandom(T &rng)
Generate a random instruction.
static Instruction mutateInstruction(Instruction instruction, T &rng, HavocSettings &havoc_config)
Mutate a single instruction.
ArgumentContents arguments
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 ByteArray fuzzing instructions, execution, etc.
bb::stdlib::witness_t< Builder > witness_t
static bool postProcess(Builder *builder, std::vector< BoolFuzzBase::ExecutionHandler > &stack)
Check that the resulting values are equal to expected.
bb::stdlib::bool_t< Builder > bool_t
std::vector< ExecutionHandler > ExecutionState
Class for quickly deterministically creating new random values. We don't care about distribution much...
Definition fuzzer.hpp:63
void reseed(uint32_t seed)
Definition fuzzer.hpp:75
uint32_t next()
Definition fuzzer.hpp:68
Implements boolean logic in-circuit.
Definition bool.hpp:59
bool is_constant() const
Definition bool.hpp:111
void assert_equal(const bool_t &rhs, std::string const &msg="bool_t::assert_equal") const
Implements copy constraint for bool_t elements.
Definition bool.cpp:396
Concept for a simple PRNG which returns a uint32_t when next is called.
Definition fuzzer.hpp:125
AluTraceBuilder builder
Definition alu.test.cpp:123
FF b
Instruction instruction
Instruction
Enumeration of VM instructions that can be executed.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
size_t GEN_LLVM_POST_MUTATION_PROB
Definition fuzzer.hpp:28