1#include "barretenberg/ecc/curves/bn254/fr.hpp"
2#include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp"
3#include "barretenberg/numeric/random/engine.hpp"
4#include "barretenberg/numeric/uint256/uint256.hpp"
5#include "barretenberg/stdlib/primitives/bool/bool.hpp"
6#include "barretenberg/stdlib/primitives/field/field.hpp"
8#pragma clang diagnostic push
9#pragma clang diagnostic ignored "-Wc99-designator"
13bool circuit_should_fail =
false;
17#include "barretenberg/common/fuzzer.hpp"
24#ifdef SHOW_INFORMATION
25#define PRINT_SINGLE_ARG_INSTRUCTION(first_index, vector, operation_name, preposition) \
27 std::cout << operation_name << " " << (vector[first_index].field.is_constant() ? "constant(" : "witness(") \
28 << vector[first_index].field.get_value() << ") at " << first_index << " " << preposition \
32#define PRINT_TWO_ARG_INSTRUCTION(first_index, second_index, vector, operation_name, preposition) \
34 std::cout << operation_name << " " << (vector[first_index].field.is_constant() ? "constant(" : "witness(") \
35 << vector[first_index].field.get_value() << ") at " << first_index << " " << preposition << " " \
36 << (vector[second_index].field.is_constant() ? "constant(" : "witness(") \
37 << vector[second_index].field.get_value() << ") at " << second_index << std::flush; \
40#define PRINT_THREE_ARG_INSTRUCTION( \
41 first_index, second_index, third_index, vector, operation_name, preposition1, preposition2) \
43 std::cout << operation_name << " " << (vector[first_index].field.is_constant() ? "constant(" : "witness(") \
44 << vector[first_index].field.get_value() << ") at " << first_index << " " << preposition1 << " " \
45 << (vector[second_index].field.is_constant() ? "constant(" : "witness(") \
46 << vector[second_index].field.get_value() << ") at " << second_index << " " << preposition2 << " " \
47 << (vector[third_index].field.is_constant() ? "constant(" : "witness(") \
48 << vector[third_index].field.get_value() << ") at " << third_index << std::flush; \
50#define PRINT_TWO_ARG_ONE_VALUE_INSTRUCTION( \
51 first_index, second_index, third_index, vector, operation_name, preposition1, preposition2) \
53 std::cout << operation_name << " " << (vector[first_index].field.is_constant() ? "constant(" : "witness(") \
54 << vector[first_index].field.get_value() << ") at " << first_index << " " << preposition1 << " " \
55 << (vector[second_index].field.is_constant() ? "constant(" : "witness(") \
56 << vector[second_index].field.get_value() << ") at " << second_index << " " << preposition2 << " " \
57 << third_index << std::flush; \
60#define PRINT_TWO_ARG_TWO_VALUES_INSTRUCTION( \
61 first_index, second_index, value1, value2, vector, operation_name, preposition1, preposition2, preposition3) \
63 std::cout << operation_name << " " << (vector[first_index].field.is_constant() ? "constant(" : "witness(") \
64 << vector[first_index].field.get_value() << ") at " << first_index << " " << preposition1 << " " \
65 << (vector[second_index].field.is_constant() ? "constant(" : "witness(") \
66 << vector[second_index].field.get_value() << ") at " << second_index << " " << preposition2 << " " \
67 << value1 << preposition3 << value2 << std::flush; \
70#define PRINT_SLICE(first_index, lsb, msb, vector) \
72 std::cout << "Slice:" \
73 << " " << (vector[first_index].field.is_constant() ? "constant(" : "witness(") \
74 << vector[first_index].field.get_value() << ") at " << first_index << " " \
75 << "(" << (size_t)lsb << ":" << (size_t)msb << ")" << std::flush; \
78#define PRINT_RESULT(prefix, action, index, value) \
80 std::cout << " result(" << value.field.get_value() << ")" << action << index << std::endl << std::flush; \
85#define PRINT_SINGLE_ARG_INSTRUCTION(first_index, vector, operation_name, preposition)
86#define PRINT_TWO_ARG_INSTRUCTION(first_index, second_index, vector, operation_name, preposition)
88#define PRINT_TWO_ARG_ONE_VALUE_INSTRUCTION( \
89 first_index, second_index, third_index, vector, operation_name, preposition1, preposition2)
90#define PRINT_TWO_ARG_TWO_VALUES_INSTRUCTION( \
91 first_index, second_index, value1, value2, vector, operation_name, preposition1, preposition2, preposition3)
93#define PRINT_THREE_ARG_INSTRUCTION( \
94 first_index, second_index, third_index, vector, operation_name, preposition1, preposition2)
95#define PRINT_RESULT(prefix, action, index, value)
97#define PRINT_SLICE(first_index, lsb, msb, vector)
100#define OPERATION_TYPE_SIZE 1
102#define ELEMENT_SIZE (sizeof(barretenberg::fr) + 1)
103#define TWO_IN_ONE_OUT 3
104#define THREE_IN_ONE_OUT 4
105#define SLICE_ARGS_SIZE 6
107#define MSUB_DIV_MINIMUM_MUL_PAIRS 1
108#define MSUB_DIV_MAXIMUM_MUL_PAIRS 8
109#define MSUB_DIV_MINIMUM_SUBTRACTED_ELEMENTS 0
110#define MSUB_DIV_MAXIMUM_SUBTRACTED_ELEMENTS 8
111#define MULT_MADD_MINIMUM_MUL_PAIRS 1
112#define MULT_MADD_MAXIMUM_MUL_PAIRS 8
113#define MULT_MADD_MINIMUM_ADDED_ELEMENTS 0
114#define MULT_MADD_MAXIMUM_ADDED_ELEMENTS 8
115#define SQR_ADD_MINIMUM_ADDED_ELEMENTS 0
116#define SQR_ADD_MAXIMUM_ADDED_ELEMENTS 8
142#ifndef DISABLE_DIVISION
191 uint8_t output_index;
194 uint8_t divisor_index;
195 uint8_t output_index;
230 template <
typename T>
235 OPCODE instruction_opcode =
static_cast<OPCODE
>(rng.next() % (OPCODE::_LAST));
236 uint8_t in1, in2, in3, lsb, msb, out, out1, out2, out3, mask_size;
240 switch (instruction_opcode) {
241 case OPCODE::CONSTANT:
242 case OPCODE::WITNESS:
243 case OPCODE::CONSTANT_WITNESS:
246 for (
size_t i = 0; i < (
sizeof(
uint256_t) >> 1); i++) {
247 *(((uint16_t*)&temp) + i) =
static_cast<uint16_t
>(rng.next() & 0xffff);
251 mask_size =
static_cast<uint8_t
>(rng.next() & 0xff);
255 return { .id = instruction_opcode, .arguments.element =
Element(temp & mask) };
257 case OPCODE::ASSERT_ZERO:
258 case OPCODE::ASSERT_NOT_ZERO:
259 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
260 return { .id = instruction_opcode, .arguments.singleArg = { .in = in1 } };
263 case OPCODE::ASSERT_EQUAL:
264 case OPCODE::ASSERT_NOT_EQUAL:
267 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
268 out =
static_cast<uint8_t
>(rng.next() & 0xff);
269 return { .id = instruction_opcode, .arguments.twoArgs = { .in = in1, .out = out } };
272 case OPCODE::SUBTRACT:
273 case OPCODE::MULTIPLY:
274#ifndef DISABLE_DIVISION
277 case OPCODE::COND_NEGATE:
280 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
281 in2 =
static_cast<uint8_t
>(rng.next() & 0xff);
282 out =
static_cast<uint8_t
>(rng.next() & 0xff);
283 return { .id = instruction_opcode, .arguments.threeArgs = { .in1 = in1, .in2 = in2, .out = out } };
285 case OPCODE::ADD_TWO:
287 case OPCODE::COND_SELECT:
288 case OPCODE::SELECT_IF_ZERO:
289 case OPCODE::SELECT_IF_EQ:
292 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
293 in2 =
static_cast<uint8_t
>(rng.next() & 0xff);
294 in3 =
static_cast<uint8_t
>(rng.next() & 0xff);
295 out =
static_cast<uint8_t
>(rng.next() & 0xff);
296 return { .id = instruction_opcode,
297 .arguments.fourArgs{ .in1 = in1, .in2 = in2, .in3 = in3, .out = out } };
302 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
303 lsb =
static_cast<uint8_t
>(rng.next() & 0xff);
304 msb =
static_cast<uint8_t
>(rng.next() & 0xff);
305 out1 =
static_cast<uint8_t
>(rng.next() & 0xff);
306 out2 =
static_cast<uint8_t
>(rng.next() & 0xff);
307 out3 =
static_cast<uint8_t
>(rng.next() & 0xff);
308 return { .id = instruction_opcode,
309 .arguments.sliceArgs = {
310 .in1 = in1, .lsb = lsb, .msb = msb, .out1 = out1, .out2 = out2, .out3 = out3 } };
311 case OPCODE::RANDOMSEED:
312 return { .id = instruction_opcode, .arguments.randomseed = rng.next() };
329 template <
typename T>
336 bool convert_to_montgomery = (rng.next() % (havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY +
337 havoc_config.VAL_MUT_NON_MONTGOMERY_PROBABILITY)) <
338 havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY;
341#define MONT_CONVERSION \
342 if (convert_to_montgomery) { \
343 value_data = uint256_t(e.to_montgomery_form()); \
345 value_data = uint256_t(e); \
348#define INV_MONT_CONVERSION \
349 if (convert_to_montgomery) { \
350 e = barretenberg::fr(value_data).from_montgomery_form(); \
352 e = barretenberg::fr(value_data); \
356 const size_t mutation_type_count = havoc_config.value_mutation_distribution.size();
358 const size_t choice = rng.next() % havoc_config.value_mutation_distribution[mutation_type_count - 1];
359 if (choice < havoc_config.value_mutation_distribution[0]) {
364 }
else if (choice < havoc_config.value_mutation_distribution[1]) {
366 if (convert_to_montgomery) {
367 e = e.to_montgomery_form();
369 if (rng.next() & 1) {
374 if (convert_to_montgomery) {
375 e = e.from_montgomery_form();
380 switch (rng.next() % 9) {
382 e = barretenberg::fr::zero();
385 e = barretenberg::fr::one();
388 e = -barretenberg::fr::one();
391 e = barretenberg::fr::one().sqrt().second;
394 e = barretenberg::fr::one().sqrt().second.invert();
397 e = barretenberg::fr::get_root_of_unity(8);
426 template <
typename T>
430#define PUT_RANDOM_BYTE_IF_LUCKY(variable) \
431 if (rng.next() & 1) { \
432 variable = rng.next() & 0xff; \
435 switch (instruction.id) {
436 case OPCODE::CONSTANT:
437 case OPCODE::WITNESS:
438 case OPCODE::CONSTANT_WITNESS:
441 if (rng.next() & 1) {
442 instruction.arguments.element =
446 case OPCODE::ASSERT_ZERO:
447 case OPCODE::ASSERT_NOT_ZERO:
448 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.singleArg.in)
451 case OPCODE::ASSERT_EQUAL:
452 case OPCODE::ASSERT_NOT_EQUAL:
455 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.twoArgs.in)
456 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.twoArgs.out)
459#ifndef DISABLE_DIVISION
462 case OPCODE::MULTIPLY:
463 case OPCODE::SUBTRACT:
464 case OPCODE::COND_NEGATE:
466 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.threeArgs.in1)
467 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.threeArgs.in2)
468 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.threeArgs.out)
470 case OPCODE::ADD_TWO:
472 case OPCODE::COND_SELECT:
473 case OPCODE::SELECT_IF_ZERO:
474 case OPCODE::SELECT_IF_EQ:
476 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.fourArgs.in1)
477 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.fourArgs.in2)
478 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.fourArgs.in3)
479 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.fourArgs.out)
483 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.sliceArgs.in1)
484 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.sliceArgs.lsb)
485 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.sliceArgs.msb)
486 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.sliceArgs.out1)
487 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.sliceArgs.out2)
488 PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.sliceArgs.out3)
490 case OPCODE::RANDOMSEED:
491 instruction.arguments.randomseed = rng.next();
508 static constexpr size_t SQR = 2;
509 static constexpr size_t ASSERT_EQUAL = 2;
510 static constexpr size_t ASSERT_NOT_EQUAL = 2;
511 static constexpr size_t ASSERT_ZERO = 1;
512 static constexpr size_t ASSERT_NOT_ZERO = 1;
513 static constexpr size_t ADD = 3;
514 static constexpr size_t SUBTRACT = 3;
515 static constexpr size_t MULTIPLY = 3;
516 static constexpr size_t ADD_TWO = 4;
517#ifndef DISABLE_DIVISION
518 static constexpr size_t DIVIDE = 3;
520 static constexpr size_t DIVIDE =
static_cast<size_t>(-1);
522 static constexpr size_t MADD = 4;
523 static constexpr size_t SUBTRACT_WITH_CONSTRAINT =
static_cast<size_t>(-1);
524 static constexpr size_t DIVIDE_WITH_CONSTRAINTS =
static_cast<size_t>(-1);
525 static constexpr size_t SLICE = 6;
526 static constexpr size_t RANDOMSEED =
sizeof(uint32_t);
527 static constexpr size_t COND_NEGATE = 3;
528 static constexpr size_t COND_SELECT = 4;
529 static constexpr size_t SELECT_IF_ZERO = 4;
530 static constexpr size_t SELECT_IF_EQ = 4;
531 static constexpr size_t SET = 2;
532 static constexpr size_t INVERT = 2;
542 static constexpr size_t CONSTANT = 1;
543 static constexpr size_t WITNESS = 1;
544 static constexpr size_t CONSTANT_WITNESS = 1;
545 static constexpr size_t ADD = 1;
546 static constexpr size_t SUBTRACT = 1;
547 static constexpr size_t MULTIPLY = 2;
548 static constexpr size_t SQR = 2;
549 static constexpr size_t ASSERT_EQUAL = 2;
550 static constexpr size_t ASSERT_NOT_EQUAL = 2;
551 static constexpr size_t ASSERT_ZERO = 2;
552 static constexpr size_t ASSERT_NOT_ZERO = 2;
553 static constexpr size_t ADD_TWO = 1;
554#ifndef DISABLE_DIVISION
555 static constexpr size_t DIVIDE = 16;
557 static constexpr size_t MADD = 2;
558 static constexpr size_t SUBTRACT_WITH_CONSTRAINT = 0;
559 static constexpr size_t DIVIDE_WITH_CONSTRAINTS = 0;
560 static constexpr size_t SLICE = 1;
561 static constexpr size_t RANDOMSEED = 0;
562 static constexpr size_t COND_NEGATE = 0;
563 static constexpr size_t COND_SELECT = 0;
564 static constexpr size_t SELECT_IF_ZERO = 0;
565 static constexpr size_t SELECT_IF_EQ = 0;
566 static constexpr size_t SET = 0;
567 static constexpr size_t INVERT = 0;
568 static constexpr size_t _LIMIT = 64;
585 if constexpr (opcode == Instruction::OPCODE::CONSTANT || opcode == Instruction::OPCODE::WITNESS ||
586 opcode == Instruction::OPCODE::CONSTANT_WITNESS) {
588 instr.id =
static_cast<typename Instruction::OPCODE
>(opcode);
590 instr.arguments.element = barretenberg::fr::serialize_from_buffer(Data);
593 if constexpr (opcode == Instruction::OPCODE::ASSERT_ZERO ||
594 opcode == Instruction::OPCODE::ASSERT_NOT_ZERO) {
595 return { .id =
static_cast<typename Instruction::OPCODE
>(opcode),
596 .arguments.singleArg = { .in = *Data } };
598 if constexpr (opcode == Instruction::OPCODE::SQR || opcode == Instruction::OPCODE::ASSERT_EQUAL ||
599 opcode == Instruction::OPCODE::ASSERT_NOT_EQUAL || opcode == Instruction::OPCODE::SET ||
600 opcode == Instruction::OPCODE::INVERT) {
601 return { .id =
static_cast<typename Instruction::OPCODE
>(opcode),
602 .arguments.twoArgs = { .in = *Data, .out = *(Data + 1) } };
604 if constexpr (opcode == Instruction::OPCODE::ADD || opcode == Instruction::OPCODE::MULTIPLY ||
605#ifndef DISABLE_DIVISION
606 opcode == Instruction::OPCODE::DIVIDE ||
608 opcode == Instruction::OPCODE::SUBTRACT || opcode == Instruction::OPCODE::COND_NEGATE) {
609 return { .id =
static_cast<typename Instruction::OPCODE
>(opcode),
610 .arguments.threeArgs = { .in1 = *Data, .in2 = *(Data + 1), .out = *(Data + 2) } };
612 if constexpr (opcode == Instruction::OPCODE::MADD || opcode == Instruction::OPCODE::ADD_TWO ||
613 opcode == Instruction::OPCODE::COND_SELECT || opcode == Instruction::OPCODE::SELECT_IF_ZERO ||
614 opcode == Instruction::OPCODE::SELECT_IF_EQ) {
616 return { .id =
static_cast<typename Instruction::OPCODE
>(opcode),
617 .arguments.fourArgs = {
618 .in1 = *Data, .in2 = *(Data + 1), .in3 = *(Data + 2), .out = *(Data + 3) } };
620 if constexpr (opcode == Instruction::OPCODE::SLICE) {
621 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
622 .arguments.sliceArgs = { .in1 = *Data,
627 .out3 = *(Data + 5) } };
629 if constexpr (opcode == Instruction::OPCODE::RANDOMSEED) {
631 memcpy(&randomseed, Data,
sizeof(uint32_t));
632 return Instruction{ .id =
static_cast<typename Instruction::OPCODE
>(opcode),
633 .arguments.randomseed = randomseed };
643 template <
typename Instruction::OPCODE instruction_opcode>
646 if constexpr (instruction_opcode == Instruction::OPCODE::CONSTANT ||
647 instruction_opcode == Instruction::OPCODE::WITNESS ||
648 instruction_opcode == Instruction::OPCODE::CONSTANT_WITNESS) {
649 *Data = instruction.id;
650 memcpy(Data + 1, &instruction.arguments.element.data[0],
sizeof(instruction.arguments.element.data));
653 if constexpr (instruction_opcode == Instruction::OPCODE::ASSERT_ZERO ||
654 instruction_opcode == Instruction::OPCODE::ASSERT_NOT_ZERO) {
655 *Data = instruction.id;
656 *(Data + 1) = instruction.arguments.singleArg.in;
658 if constexpr (instruction_opcode == Instruction::OPCODE::SQR ||
659 instruction_opcode == Instruction::OPCODE::ASSERT_EQUAL ||
660 instruction_opcode == Instruction::OPCODE::ASSERT_NOT_EQUAL ||
661 instruction_opcode == Instruction::OPCODE::SET ||
662 instruction_opcode == Instruction::OPCODE::INVERT) {
663 *Data = instruction.id;
664 *(Data + 1) = instruction.arguments.twoArgs.in;
665 *(Data + 2) = instruction.arguments.twoArgs.out;
667 if constexpr (instruction_opcode == Instruction::OPCODE::ADD ||
668#ifndef DISABLE_DIVISION
669 instruction_opcode == Instruction::OPCODE::DIVIDE ||
671 instruction_opcode == Instruction::OPCODE::MULTIPLY ||
672 instruction_opcode == Instruction::OPCODE::SUBTRACT ||
673 instruction_opcode == Instruction::OPCODE::COND_NEGATE) {
674 *Data = instruction.id;
675 *(Data + 1) = instruction.arguments.threeArgs.in1;
676 *(Data + 2) = instruction.arguments.threeArgs.in2;
677 *(Data + 3) = instruction.arguments.threeArgs.out;
679 if constexpr (instruction_opcode == Instruction::OPCODE::ADD_TWO ||
680 instruction_opcode == Instruction::OPCODE::MADD ||
681 instruction_opcode == Instruction::OPCODE::COND_SELECT ||
682 instruction_opcode == Instruction::OPCODE::SELECT_IF_ZERO ||
683 instruction_opcode == Instruction::OPCODE::SELECT_IF_EQ) {
684 *Data = instruction.id;
685 *(Data + 1) = instruction.arguments.fourArgs.in1;
686 *(Data + 2) = instruction.arguments.fourArgs.in2;
687 *(Data + 3) = instruction.arguments.fourArgs.in3;
688 *(Data + 4) = instruction.arguments.fourArgs.out;
690 if constexpr (instruction_opcode == Instruction::OPCODE::SLICE) {
691 *Data = instruction.id;
692 *(Data + 1) = instruction.arguments.sliceArgs.in1;
693 *(Data + 2) = instruction.arguments.sliceArgs.lsb;
694 *(Data + 3) = instruction.arguments.sliceArgs.msb;
695 *(Data + 4) = instruction.arguments.sliceArgs.out1;
696 *(Data + 5) = instruction.arguments.sliceArgs.out2;
697 *(Data + 6) = instruction.arguments.sliceArgs.out3;
699 if constexpr (instruction_opcode == Instruction::OPCODE::RANDOMSEED) {
701 *Data = instruction.id;
702 memcpy(Data + 1, &instruction.arguments.randomseed,
sizeof(uint32_t));
713 ExecutionHandler construct_via_cast(
const std::optional<uint256_t> max = std::nullopt,
714 const std::optional<T> value = std::nullopt)
const
716 const auto base_u256 =
static_cast<uint256_t>(this->base);
718 if (max != std::nullopt && base_u256 > *max) {
724 if (value == std::nullopt) {
727 new_field.context = this->field.context;
732 const auto& ref = new_field;
735 static bool_t construct_predicate(
Builder* builder,
const bool predicate)
741 const bool predicate_has_ctx =
static_cast<bool>(VarianceRNG.next() % 2);
743 return bool_t(predicate_has_ctx ? builder :
nullptr, predicate);
747 const bool reconstruct =
static_cast<bool>(VarianceRNG.next() % 2);
755 void assert_equal(
field_t f)
const
757 switch (VarianceRNG.next() % 2) {
762 this->f().assert_is_in_set({ f });
787 const auto b = this->base + other.base;
789 switch (VarianceRNG.next() % 3) {
809 const auto b = this->base - other.base;
811 switch (VarianceRNG.next() % 2) {
828 const auto b = this->base * other.base;
830 switch (VarianceRNG.next() % 2) {
848 if (other.f().get_value() == 0) {
849 circuit_should_fail =
true;
852 const auto b = this->base / other.base;
854 switch (VarianceRNG.next() % 2) {
871 switch (VarianceRNG.next() % 2) {
874 this->f().add_two(other1.f(), other2.f()));
886 return ExecutionHandler(this->base * other1.base + other2.base, this->f().madd(other1.f(), { other2.f() }));
888 std::array<ExecutionHandler, 3> slice(uint8_t lsb, uint8_t msb)
890 const auto msb_plus_one = uint32_t(msb) + 1;
891 const auto hi_mask = ((
uint256_t(1) << (256 - uint32_t(msb))) - 1);
892 const auto hi_base = (
uint256_t(this->base) >> msb_plus_one) & hi_mask;
894 const auto lo_mask = (
uint256_t(1) << lsb) - 1;
895 const auto lo_base = (
uint256_t)(this->base) & lo_mask;
897 const auto slice_mask = ((
uint256_t(1) << (uint32_t(msb - lsb) + 1)) - 1);
898 const auto slice_base = (
uint256_t(this->base) >> lsb) & slice_mask;
900 auto lo_slice_hi_suint_array = this->f().
slice(msb, lsb);
901 return std::array<ExecutionHandler, 3>{
ExecutionHandler(lo_base, std::move(lo_slice_hi_suint_array[0])),
907 if (other.f().is_constant()) {
908 if (this->f().is_constant()) {
912 auto to_add =
field_t(this->f().context,
uint256_t(this->base - other.base));
913 this->assert_equal(other.f() + to_add);
916 if (this->f().is_constant()) {
917 auto to_add =
field_t(this->f().context,
uint256_t(this->base - other.base));
918 auto new_el = other.f() + to_add;
919 this->assert_equal(new_el);
922 auto to_add =
field_t(this->f().context,
uint256_t(this->base - other.base));
923 this->assert_equal(other.f() + to_add);
930 if (this->base == other.base) {
933 this->f().assert_not_equal(other.f());
939 if (!this->base.is_zero()) {
940 circuit_should_fail =
true;
942 this->f().assert_is_zero();
944 void assert_not_zero()
946 if (this->base.is_zero()) {
947 circuit_should_fail =
true;
949 this->f().assert_is_not_zero();
955 this->f().conditional_negate(construct_predicate(builder, predicate)));
961 predicate ? other.base : this->base,
962 field_t(builder).conditional_assign(construct_predicate(builder, predicate), other.f(), this->f()));
968 field_t(builder).conditional_assign(other2.f().
is_zero(), other1.f(), this->f()));
974 other1.base == other2.base ? other1.base : this->base,
975 field_t(builder).conditional_assign(other1.f() == other2.f(), other1.f(), this->f()));
982 switch (VarianceRNG.next() % 9) {
984#ifdef SHOW_INFORMATION
985 std::cout <<
"Construct via bit_array" << std::endl;
989#ifdef SHOW_INFORMATION
990 std::cout <<
"Construct via int" << std::endl;
992 return construct_via_cast<int>(std::numeric_limits<int>::max());
994#ifdef SHOW_INFORMATION
995 std::cout <<
"Construct via unsigned int" << std::endl;
997 return construct_via_cast<unsigned int>(std::numeric_limits<unsigned int>::max());
999#ifdef SHOW_INFORMATION
1000 std::cout <<
"Construct via unsigned long" << std::endl;
1002 return construct_via_cast<unsigned long>(std::numeric_limits<unsigned long>::max());
1004#ifdef SHOW_INFORMATION
1005 std::cout <<
"Construct via uint256_t" << std::endl;
1007 return construct_via_cast<uint256_t>();
1009#ifdef SHOW_INFORMATION
1010 std::cout <<
"Construct via fr" << std::endl;
1012 return construct_via_cast<barretenberg::fr>(barretenberg::fr::modulus - 1);
1033 if (
static_cast<uint256_t>(this->base) > 1) {
1036#ifdef SHOW_INFORMATION
1037 std::cout <<
"Construct via bool_t" << std::endl;
1044#ifdef SHOW_INFORMATION
1045 std::cout <<
"Reproduce via accumulate()" << std::endl;
1049#ifdef SHOW_INFORMATION
1050 std::cout <<
"Reproduce via decompose_into_bits()" << std::endl;
1052 const size_t min_num_bits =
static_cast<uint256_t>(this->base).get_msb() + 1;
1053 if (min_num_bits > 256)
1056 const size_t num_bits = min_num_bits + (VarianceRNG.next() % (256 - min_num_bits + 1));
1064 std::vector<barretenberg::fr> frs(bits.size());
1065 for (
size_t i = 0; i < bits.size(); i++) {
1069 switch (VarianceRNG.next() % 2) {
1076 std::vector<field_t> fields;
1077 for (
const auto&
fr : frs) {
1095 if (this->base == 0) {
1111 std::vector<ExecutionHandler>& stack,
1117#ifdef SHOW_INFORMATION
1118 std::cout <<
"Pushed constant value " << instruction.arguments.element <<
" to position "
1119 << stack.size() - 1 << std::endl;
1133 std::vector<ExecutionHandler>& stack,
1141#ifdef SHOW_INFORMATION
1142 std::cout <<
"Pushed witness value " << instruction.arguments.element <<
" to position " << stack.size() - 1
1158 std::vector<ExecutionHandler>& stack,
1162 v.convert_constant_to_fixed_witness(builder);
1163 stack.push_back(
ExecutionHandler(instruction.arguments.element, std::move(v)));
1164#ifdef SHOW_INFORMATION
1165 std::cout <<
"Pushed constant witness value " << instruction.arguments.element <<
" to position "
1166 << stack.size() - 1 << std::endl;
1179 std::vector<ExecutionHandler>& stack,
1184 if (stack.size() == 0) {
1187 size_t first_index = instruction.arguments.threeArgs.in1 % stack.size();
1188 size_t second_index = instruction.arguments.threeArgs.in2 % stack.size();
1189 size_t output_index = instruction.arguments.threeArgs.out;
1191 PRINT_TWO_ARG_INSTRUCTION(first_index, second_index, stack,
"Multiplying",
"*")
1194 result = stack[first_index] * stack[second_index];
1196 if (output_index >= stack.size()) {
1197 PRINT_RESULT(
"",
"pushed to ", stack.size(), result)
1198 stack.push_back(result);
1201 PRINT_RESULT(
"",
"saved to ", output_index, result)
1202 stack[output_index] = result;
1215 std::vector<ExecutionHandler>& stack,
1219 if (stack.size() == 0) {
1222 size_t first_index = instruction.arguments.threeArgs.in1 % stack.size();
1223 size_t second_index = instruction.arguments.threeArgs.in2 % stack.size();
1224 size_t output_index = instruction.arguments.threeArgs.out;
1226 PRINT_TWO_ARG_INSTRUCTION(first_index, second_index, stack,
"Adding",
"+")
1229 result = stack[first_index] + stack[second_index];
1231 if (output_index >= stack.size()) {
1232 PRINT_RESULT(
"",
"pushed to ", stack.size(), result)
1233 stack.push_back(result);
1236 PRINT_RESULT(
"",
"saved to ", output_index, result)
1237 stack[output_index] = result;
1251 std::vector<ExecutionHandler>& stack,
1255 if (stack.size() == 0) {
1258 size_t first_index = instruction.arguments.twoArgs.in % stack.size();
1259 size_t output_index = instruction.arguments.twoArgs.out;
1261 PRINT_SINGLE_ARG_INSTRUCTION(first_index, stack,
"Squaring",
"squared")
1264 result = stack[first_index].sqr();
1266 if (output_index >= stack.size()) {
1267 PRINT_RESULT(
"",
"pushed to ", stack.size(), result)
1268 stack.push_back(result);
1271 PRINT_RESULT(
"",
"saved to ", output_index, result)
1272 stack[output_index] = result;
1286 std::vector<ExecutionHandler>& stack,
1290 if (stack.size() == 0) {
1293 size_t first_index = instruction.arguments.twoArgs.in % stack.size();
1294 size_t second_index = instruction.arguments.twoArgs.out % stack.size();
1296 PRINT_TWO_ARG_INSTRUCTION(first_index, second_index, stack,
"ASSERT_EQUAL",
"== something + ")
1297#ifdef SHOW_INFORMATION
1298 std::cout << std::endl;
1301 stack[first_index].assert_equal(stack[second_index]);
1314 std::vector<ExecutionHandler>& stack,
1318 if (stack.size() == 0) {
1321 size_t first_index = instruction.arguments.twoArgs.in % stack.size();
1322 size_t second_index = instruction.arguments.twoArgs.out % stack.size();
1324 PRINT_TWO_ARG_INSTRUCTION(first_index, second_index, stack,
"ASSERT_NOT_EQUAL",
"!=")
1325#ifdef SHOW_INFORMATION
1326 std::cout << std::endl;
1329 stack[first_index].assert_not_equal(stack[second_index]);
1342 std::vector<ExecutionHandler>& stack,
1346 if (stack.size() == 0) {
1349 size_t index = instruction.arguments.singleArg.in % stack.size();
1352 if (stack[index].f().is_constant() && !stack[index].base.is_zero()) {
1355 PRINT_SINGLE_ARG_INSTRUCTION(index, stack,
"ASSERT_ZERO",
"!")
1356#ifdef SHOW_INFORMATION
1357 std::cout << std::endl;
1360 stack[index].assert_zero();
1373 std::vector<ExecutionHandler>& stack,
1377 if (stack.size() == 0) {
1380 size_t index = instruction.arguments.singleArg.in % stack.size();
1382 if (stack[index].f().is_constant() && stack[index].base.is_zero()) {
1386 PRINT_SINGLE_ARG_INSTRUCTION(index, stack,
"ASSERT_NOT_ZERO",
"!!")
1387#ifdef SHOW_INFORMATION
1388 std::cout << std::endl;
1390 stack[index].assert_not_zero();
1403 std::vector<ExecutionHandler>& stack,
1407 if (stack.size() == 0) {
1410 size_t first_index = instruction.arguments.threeArgs.in1 % stack.size();
1411 size_t second_index = instruction.arguments.threeArgs.in2 % stack.size();
1412 size_t output_index = instruction.arguments.threeArgs.out;
1414 PRINT_TWO_ARG_INSTRUCTION(first_index, second_index, stack,
"Subtracting",
"-")
1417 result = stack[first_index] - stack[second_index];
1419 if (output_index >= stack.size()) {
1420 PRINT_RESULT(
"",
"pushed to ", stack.size(), result)
1421 stack.push_back(result);
1424 PRINT_RESULT(
"",
"saved to ", output_index, result)
1425 stack[output_index] = result;
1438 std::vector<ExecutionHandler>& stack,
1442 if (stack.size() == 0) {
1445 size_t first_index = instruction.arguments.threeArgs.in1 % stack.size();
1446 size_t second_index = instruction.arguments.threeArgs.in2 % stack.size();
1447 size_t output_index = instruction.arguments.threeArgs.out;
1449 PRINT_TWO_ARG_INSTRUCTION(first_index, second_index, stack,
"Dividing",
"/")
1459 result = stack[first_index] / stack[second_index];
1461 if (output_index >= stack.size()) {
1462 PRINT_RESULT(
"",
"pushed to ", stack.size(), result)
1463 stack.push_back(result);
1466 PRINT_RESULT(
"",
"saved to ", output_index, result)
1467 stack[output_index] = result;
1481 std::vector<ExecutionHandler>& stack,
1485 if (stack.size() == 0) {
1488 size_t first_index = instruction.arguments.fourArgs.in1 % stack.size();
1489 size_t second_index = instruction.arguments.fourArgs.in2 % stack.size();
1490 size_t third_index = instruction.arguments.fourArgs.in3 % stack.size();
1491 size_t output_index = instruction.arguments.fourArgs.out;
1492 PRINT_THREE_ARG_INSTRUCTION(first_index, second_index, third_index, stack,
"ADD_TWO:",
"+",
"+")
1495 result = stack[first_index].add_two(stack[second_index], stack[third_index]);
1497 if (output_index >= stack.size()) {
1498 PRINT_RESULT(
"",
"pushed to ", stack.size(), result)
1499 stack.push_back(result);
1502 PRINT_RESULT(
"",
"saved to ", output_index, result)
1503 stack[output_index] = result;
1517 std::vector<ExecutionHandler>& stack,
1521 if (stack.size() == 0) {
1524 size_t first_index = instruction.arguments.fourArgs.in1 % stack.size();
1525 size_t second_index = instruction.arguments.fourArgs.in2 % stack.size();
1526 size_t third_index = instruction.arguments.fourArgs.in3 % stack.size();
1527 size_t output_index = instruction.arguments.fourArgs.out;
1528 PRINT_THREE_ARG_INSTRUCTION(first_index, second_index, third_index, stack,
"MADD:",
"*",
"+")
1531 result = stack[first_index].madd(stack[second_index], stack[third_index]);
1533 if (output_index >= stack.size()) {
1534 PRINT_RESULT(
"",
"pushed to ", stack.size(), result)
1535 stack.push_back(result);
1538 PRINT_RESULT(
"",
"saved to ", output_index, result)
1539 stack[output_index] = result;
1554 std::vector<ExecutionHandler>& stack,
1558 if (stack.size() == 0) {
1561 size_t first_index = instruction.arguments.sliceArgs.in1 % stack.size();
1562 uint8_t lsb = instruction.arguments.sliceArgs.lsb;
1563 uint8_t msb = instruction.arguments.sliceArgs.msb;
1564 size_t second_index = instruction.arguments.sliceArgs.out1;
1565 size_t third_index = instruction.arguments.sliceArgs.out2;
1566 size_t output_index = instruction.arguments.sliceArgs.out3;
1567 PRINT_SLICE(first_index, lsb, msb, stack)
1569 if ((lsb > msb) || (msb > 252) ||
1570 (
static_cast<uint256_t>(stack[first_index].f().get_value()) >=
1571 (
static_cast<uint256_t>(1) << grumpkin::MAX_NO_WRAP_INTEGER_BIT_LENGTH))) {
1574 PRINT_SLICE(first_index, lsb, msb, stack)
1575 auto slices = stack[first_index].slice(lsb, msb);
1576 std::array<std::pair<ExecutionHandler, size_t>, 3> what_where = { std::make_pair(slices[0], second_index),
1577 std::make_pair(slices[1], third_index),
1578 std::make_pair(slices[2], output_index) };
1579 for (
auto& x : what_where) {
1580 auto suints_count = stack.size();
1581 if (x.second >= suints_count) {
1583 PRINT_RESULT(
"\t",
"pushed to ", stack.size(), x.first)
1584 stack.push_back(x.first);
1587 PRINT_RESULT(
"\t",
"saved to ", x.second, x.first)
1588 stack[x.second] = x.first;
1604 std::vector<ExecutionHandler>& stack,
1610 VarianceRNG.reseed(instruction.arguments.randomseed);
1622 std::vector<ExecutionHandler>& stack,
1626 if (stack.size() == 0) {
1629 size_t first_index = instruction.arguments.threeArgs.in1 % stack.size();
1630 size_t output_index = instruction.arguments.threeArgs.out % stack.size();
1631 bool predicate = instruction.arguments.threeArgs.in2 % 2;
1634 result = stack[first_index].conditional_negate(builder, predicate);
1636 if (output_index >= stack.size()) {
1637 PRINT_RESULT(
"",
"pushed to ", stack.size(), result)
1638 stack.push_back(result);
1641 PRINT_RESULT(
"",
"saved to ", output_index, result)
1642 stack[output_index] = result;
1656 std::vector<ExecutionHandler>& stack,
1660 if (stack.size() == 0) {
1663 size_t first_index = instruction.arguments.fourArgs.in1 % stack.size();
1664 size_t second_index = instruction.arguments.fourArgs.in2 % stack.size();
1665 size_t output_index = instruction.arguments.fourArgs.out % stack.size();
1666 bool predicate = instruction.arguments.fourArgs.in3 % 2;
1669 result = stack[first_index].conditional_select(builder, stack[second_index], predicate);
1671 if (output_index >= stack.size()) {
1672 PRINT_RESULT(
"",
"pushed to ", stack.size(), result)
1673 stack.push_back(result);
1676 PRINT_RESULT(
"",
"saved to ", output_index, result)
1677 stack[output_index] = result;
1690 std::vector<ExecutionHandler>& stack,
1694 if (stack.size() == 0) {
1697 size_t first_index = instruction.arguments.fourArgs.in1 % stack.size();
1698 size_t second_index = instruction.arguments.fourArgs.in2 % stack.size();
1699 size_t third_index = instruction.arguments.fourArgs.in3 % stack.size();
1700 size_t output_index = instruction.arguments.fourArgs.out % stack.size();
1703 result = stack[first_index].select_if_zero(builder, stack[second_index], stack[third_index]);
1705 if (output_index >= stack.size()) {
1706 PRINT_RESULT(
"",
"pushed to ", stack.size(), result)
1707 stack.push_back(result);
1710 PRINT_RESULT(
"",
"saved to ", output_index, result)
1711 stack[output_index] = result;
1724 std::vector<ExecutionHandler>& stack,
1728 if (stack.size() == 0) {
1731 size_t first_index = instruction.arguments.fourArgs.in1 % stack.size();
1732 size_t second_index = instruction.arguments.fourArgs.in2 % stack.size();
1733 size_t third_index = instruction.arguments.fourArgs.in3 % stack.size();
1734 size_t output_index = instruction.arguments.fourArgs.out % stack.size();
1737 result = stack[first_index].select_if_eq(builder, stack[second_index], stack[third_index]);
1739 if (output_index >= stack.size()) {
1740 PRINT_RESULT(
"",
"pushed to ", stack.size(), result)
1741 stack.push_back(result);
1744 PRINT_RESULT(
"",
"saved to ", output_index, result)
1745 stack[output_index] = result;
1758 std::vector<ExecutionHandler>& stack,
1762 if (stack.size() == 0) {
1765 size_t first_index = instruction.arguments.twoArgs.in % stack.size();
1766 size_t output_index = instruction.arguments.twoArgs.out;
1768 PRINT_SINGLE_ARG_INSTRUCTION(first_index, stack,
"Instantiating",
"")
1771 result = stack[first_index].set(builder);
1773 if (output_index >= stack.size()) {
1774 PRINT_RESULT(
"",
"pushed to ", stack.size(), result)
1775 stack.push_back(result);
1777 PRINT_RESULT(
"",
"saved to ", output_index, result)
1778 stack[output_index] = result;
1791 std::vector<ExecutionHandler>& stack,
1795 if (stack.size() == 0) {
1798 size_t first_index = instruction.arguments.twoArgs.in % stack.size();
1799 size_t output_index = instruction.arguments.twoArgs.out;
1801 PRINT_SINGLE_ARG_INSTRUCTION(first_index, stack,
"invert",
"")
1804 result = stack[first_index].invert();
1806 if (output_index >= stack.size()) {
1807 PRINT_RESULT(
"",
"pushed to ", stack.size(), result)
1808 stack.push_back(result);
1810 PRINT_RESULT(
"",
"saved to ", output_index, result)
1811 stack[output_index] = result;
1833 for (
size_t i = 0; i < stack.size(); i++) {
1834 auto element = stack[i];
1836 std::cerr <<
"Failed at " << i <<
" with actual value " << element.base <<
" and value in field "
1837 << element.field.get_value() << std::endl;
1847extern "C" int LLVMFuzzerInitialize(
int* argc,
char*** argv)
1854 .GEN_LLVM_POST_MUTATION_PROB = 30,
1855 .GEN_MUTATION_COUNT_LOG = 5,
1856 .GEN_STRUCTURAL_MUTATION_PROBABILITY = 300,
1857 .GEN_VALUE_MUTATION_PROBABILITY = 700,
1858 .ST_MUT_DELETION_PROBABILITY = 100,
1859 .ST_MUT_DUPLICATION_PROBABILITY = 80,
1860 .ST_MUT_INSERTION_PROBABILITY = 120,
1861 .ST_MUT_MAXIMUM_DELETION_LOG = 6,
1862 .ST_MUT_MAXIMUM_DUPLICATION_LOG = 2,
1863 .ST_MUT_SWAP_PROBABILITY = 50,
1864 .VAL_MUT_LLVM_MUTATE_PROBABILITY = 250,
1865 .VAL_MUT_MONTGOMERY_PROBABILITY = 130,
1866 .VAL_MUT_NON_MONTGOMERY_PROBABILITY = 50,
1867 .VAL_MUT_SMALL_ADDITION_PROBABILITY = 110,
1868 .VAL_MUT_SPECIAL_VALUE_PROBABILITY = 130
1941 std::vector<size_t> structural_mutation_distribution;
1942 std::vector<size_t> value_mutation_distribution;
1944 temp += fuzzer_havoc_settings.ST_MUT_DELETION_PROBABILITY;
1945 structural_mutation_distribution.push_back(temp);
1946 temp += fuzzer_havoc_settings.ST_MUT_DUPLICATION_PROBABILITY;
1947 structural_mutation_distribution.push_back(temp);
1948 temp += fuzzer_havoc_settings.ST_MUT_INSERTION_PROBABILITY;
1949 structural_mutation_distribution.push_back(temp);
1950 temp += fuzzer_havoc_settings.ST_MUT_SWAP_PROBABILITY;
1951 structural_mutation_distribution.push_back(temp);
1952 fuzzer_havoc_settings.structural_mutation_distribution = structural_mutation_distribution;
1955 temp += fuzzer_havoc_settings.VAL_MUT_LLVM_MUTATE_PROBABILITY;
1956 value_mutation_distribution.push_back(temp);
1957 temp += fuzzer_havoc_settings.VAL_MUT_SMALL_ADDITION_PROBABILITY;
1958 value_mutation_distribution.push_back(temp);
1960 temp += fuzzer_havoc_settings.VAL_MUT_SPECIAL_VALUE_PROBABILITY;
1961 value_mutation_distribution.push_back(temp);
1962 fuzzer_havoc_settings.value_mutation_distribution = value_mutation_distribution;
1966#ifndef DISABLE_CUSTOM_MUTATORS
1971extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* Data,
size_t Size,
size_t MaxSize,
unsigned int Seed)
1976 if ((fast_random.next() % 200) < fuzzer_havoc_settings.GEN_LLVM_POST_MUTATION_PROB) {
1977 size_occupied = LLVMFuzzerMutate(Data, size_occupied, MaxSize);
1979 return size_occupied;
1986extern "C" size_t LLVMFuzzerCustomCrossOver(
const uint8_t* Data1,
1988 const uint8_t* Data2,
2008extern "C" size_t LLVMFuzzerTestOneInput(
const uint8_t* Data,
size_t Size)
2010 RunWithBuilders<FieldBase, FuzzerCircuitTypes>(Data, Size, VarianceRNG);
2014#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
Class for quickly deterministically creating new random values. We don't care about distribution much...
Definition: fuzzer.hpp:64
Definition: field.fuzzer.hpp:503
This class implements the execution of safeuint with an oracle to detect discrepancies.
Definition: field.fuzzer.hpp:710
static size_t execute_ASSERT_EQUAL(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the ASSERT_EQUAL instruction.
Definition: field.fuzzer.hpp:1285
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)
Definition: field.fuzzer.hpp:1157
static size_t execute_CONSTANT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the constant instruction (push constant safeuint to the stack)
Definition: field.fuzzer.hpp:1110
static size_t execute_SET(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SET instruction.
Definition: field.fuzzer.hpp:1757
static size_t execute_ADD_TWO(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the ADD_TWO instruction.
Definition: field.fuzzer.hpp:1480
static size_t execute_SQR(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SQR instruction.
Definition: field.fuzzer.hpp:1250
static size_t execute_ASSERT_NOT_EQUAL(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the ASSERT_NOT_EQUAL instruction.
Definition: field.fuzzer.hpp:1313
static size_t execute_DIVIDE(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the division operator instruction.
Definition: field.fuzzer.hpp:1437
static size_t execute_COND_NEGATE(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the COND_NEGATE instruction.
Definition: field.fuzzer.hpp:1621
static size_t execute_INVERT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the INVERT instruction.
Definition: field.fuzzer.hpp:1790
static size_t execute_ASSERT_ZERO(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the ASSERT_ZERO instruction.
Definition: field.fuzzer.hpp:1341
static size_t execute_SUBTRACT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the subtraction operator instruction.
Definition: field.fuzzer.hpp:1402
static size_t execute_ASSERT_NOT_ZERO(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the ASSERT_NOT_ZERO instruction.
Definition: field.fuzzer.hpp:1372
static size_t execute_MADD(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the MADD instruction.
Definition: field.fuzzer.hpp:1516
static size_t execute_SELECT_IF_ZERO(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SELECT_IF_ZERO instruction.
Definition: field.fuzzer.hpp:1689
static size_t execute_MULTIPLY(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the multiply instruction.
Definition: field.fuzzer.hpp:1178
static size_t execute_SLICE(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the slice instruction.
Definition: field.fuzzer.hpp:1553
static size_t execute_COND_SELECT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the COND_SELECT instruction.
Definition: field.fuzzer.hpp:1655
static size_t execute_ADD(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the addition operator instruction.
Definition: field.fuzzer.hpp:1214
static size_t execute_WITNESS(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the witness instruction (push witness safeuit to the stack)
Definition: field.fuzzer.hpp:1132
static size_t execute_RANDOMSEED(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the RANDOMSEED instruction.
Definition: field.fuzzer.hpp:1603
static size_t execute_SELECT_IF_EQ(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SELECT_IF_EQ instruction.
Definition: field.fuzzer.hpp:1723
Optional subclass that governs limits on the use of certain instructions, since some of them can be t...
Definition: field.fuzzer.hpp:540
A class representing a single fuzzing instruction.
Definition: field.fuzzer.hpp:133
static Instruction mutateInstruction(Instruction instruction, T &rng, HavocSettings &havoc_config)
Mutate a single instruction.
Definition: field.fuzzer.hpp:427
static Instruction generateRandom(T &rng)
Generate a random instruction.
Definition: field.fuzzer.hpp:231
static barretenberg::fr mutateFieldElement(barretenberg::fr e, T &rng, HavocSettings &havoc_config)
Mutate the value of a field element.
Definition: field.fuzzer.hpp:330
Parser class handles the parsing and writing the instructions back to data buffer.
Definition: field.fuzzer.hpp:574
static void writeInstruction(Instruction &instruction, uint8_t *Data)
Write a single instruction to buffer.
Definition: field.fuzzer.hpp:644
static Instruction parseInstructionArgs(uint8_t *Data)
Parse a single instruction from data.
Definition: field.fuzzer.hpp:583
The class parametrizing Field fuzzing instructions, execution, etc.
Definition: field.fuzzer.hpp:121
std::vector< ExecutionHandler > ExecutionState
Definition: field.fuzzer.hpp:1820
static bool postProcess(Builder *builder, std::vector< FieldBase::ExecutionHandler > &stack)
Check that the resulting values are equal to expected.
Definition: field.fuzzer.hpp:1830
Definition: uint256.hpp:25
Definition: standard_circuit_builder.hpp:12
std::array< field_t, 3 > slice(uint8_t msb, uint8_t lsb) const
Definition: field.cpp:1033
static field_t accumulate(const std::vector< field_t > &to_add)
Definition: field.cpp:936
std::vector< bool_t< Builder > > decompose_into_bits(size_t num_bits=256, std::function< witness_t< Builder >(Builder *ctx, uint64_t, uint256_t)> get_bit=[](Builder *ctx, uint64_t j, const uint256_t &val) { return witness_t< Builder >(ctx, val.get_bit(j));}) const
Build a circuit allowing a user to prove that they have deomposed this into bits.
Definition: field.cpp:1090
void assert_equal(const field_t &rhs, std::string const &msg="field_t::assert_equal") const
Constrain that this field is equal to the given field.
Definition: field.cpp:749
bool_t< Builder > is_zero() const
Definition: field.cpp:588
Definition: witness.hpp:51
Definition: witness.hpp:10
Concept for a simple PRNG which returns a uint32_t when next is called.
Definition: fuzzer.hpp:91
Definition: field.fuzzer.hpp:182
Definition: field.fuzzer.hpp:176
Definition: field.fuzzer.hpp:189
Definition: field.fuzzer.hpp:193
Definition: field.fuzzer.hpp:164
Definition: field.fuzzer.hpp:198
Definition: field.fuzzer.hpp:171
Definition: field.fuzzer.hpp:167
Definition: fuzzer.hpp:27
BBERG_INLINE constexpr field sqr() const noexcept
Definition: field_impl.hpp:61
Definition: field.fuzzer.hpp:206