44#pragma clang diagnostic push
51#pragma clang diagnostic ignored "-Wc99-designator"
53#ifdef FUZZING_SHOW_INFORMATION
70template <
typename Stack>
inline FormattedArgs format_self_arg(
const Stack& stack,
size_t first_index)
72 std::string out = stack[first_index].biggroup.is_constant() ?
"c" :
"w";
74 return FormattedArgs{ .lhs =
"", .rhs =
"", .out = out };
84template <
typename Stack>
85inline FormattedArgs format_single_arg(
const Stack& stack,
size_t first_index,
size_t output_index)
87 std::string
rhs = stack[first_index].biggroup.is_constant() ?
"c" :
"w";
88 std::string out =
rhs;
90 out +=
std::to_string(output_index >= stack.size() ? stack.size() : output_index);
91 out = (output_index >= stack.size() ?
"auto " :
"") + out;
92 return FormattedArgs{ .lhs =
"", .rhs =
rhs, .out = out };
103template <
typename Stack>
104inline FormattedArgs format_two_arg(
const Stack& stack,
size_t first_index,
size_t second_index,
size_t output_index)
106 std::string lhs = stack[first_index].biggroup.is_constant() ?
"c" :
"w";
107 std::string
rhs = stack[second_index].biggroup.is_constant() ?
"c" :
"w";
109 (stack[first_index].biggroup.is_constant() && stack[second_index].biggroup.is_constant()) ?
"c" :
"w";
112 out +=
std::to_string(output_index >= stack.size() ? stack.size() : output_index);
113 out = (output_index >= stack.size() ?
"auto " :
"") + out;
114 return FormattedArgs{ .lhs = lhs, .rhs =
rhs, .out = out };
203 typename BigGroupType,
204 bool _use_bigfield =
false,
205 typename BigfieldScalar =
typename BigGroupType::ScalarField>
231 using CircuitFq =
typename biggroup_t::BaseField;
235 const bool is_inf = native_elem.is_point_at_infinity();
255#ifndef DISABLE_MULTIPLICATION
258#ifndef DISABLE_BATCH_MUL
335 template <
typename T>
340 uint8_t in, in1, in2, in3, out;
343 switch (instruction_opcode) {
347 auto scalar =
ScalarField(
static_cast<uint64_t
>(fast_log_distributed_uint256(rng)));
348 auto el = GroupElement::one() * scalar;
349 return { .id = instruction_opcode, .arguments.element =
Element(scalar, el) };
352 in =
static_cast<uint8_t
>(rng.next() & 0xff);
353 return { .id = instruction_opcode, .arguments.oneArg = { .in = in } };
358 in =
static_cast<uint8_t
>(rng.next() & 0xff);
359 out =
static_cast<uint8_t
>(rng.next() & 0xff);
360 return { .id = instruction_opcode, .arguments.twoArgs = { .in = in, .out = out } };
363 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
364 in2 =
static_cast<uint8_t
>(rng.next() & 0xff);
365 out =
static_cast<uint8_t
>(rng.next() & 0xff);
366 return { .id = instruction_opcode,
367 .arguments.threeArgs.in1 = in1,
368 .arguments.threeArgs.in2 = in2,
369 .arguments.threeArgs.out = out };
371 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
372 in2 =
static_cast<uint8_t
>(rng.next() & 0xff);
373 in3 =
static_cast<uint8_t
>(rng.next() & 0xff);
374 out =
static_cast<uint8_t
>(rng.next() & 0xff);
375 return { .id = instruction_opcode,
376 .arguments.fourArgs.in1 = in1,
377 .arguments.fourArgs.in2 = in2,
378 .arguments.fourArgs.in3 = in3,
379 .arguments.fourArgs.out = out };
380#ifndef DISABLE_MULTIPLICATION
382 in =
static_cast<uint8_t
>(rng.next() & 0xff);
383 out =
static_cast<uint8_t
>(rng.next() & 0xff);
384 return { .id = instruction_opcode,
386 .arguments.mulArgs.in = in,
387 .arguments.mulArgs.out = out };
389#ifndef DISABLE_BATCH_MUL
400 instr.
id = instruction_opcode;
402 for (
size_t i = 0; i < mult_size; i++) {
405 for (
size_t i = 0; i < mult_size; i++) {
413 return { .
id = instruction_opcode, .arguments.randomseed = rng.next() * rng.next() };
436 if (from_montgomery) {
451 template <
typename T>
462 bool convert_to_montgomery = (rng.next() % (havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY +
463 havoc_config.VAL_MUT_NON_MONTGOMERY_PROBABILITY)) <
464 havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY;
465 bool normalize = (rng.next() % (havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY +
466 havoc_config.VAL_MUT_NON_MONTGOMERY_PROBABILITY)) <
467 havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY;
471 const size_t mutation_type_count = havoc_config.value_mutation_distribution.size();
473 const size_t choice = rng.next() % havoc_config.value_mutation_distribution[mutation_type_count - 1];
474 if (choice < havoc_config.value_mutation_distribution[0]) {
478 e.scalar = from_uint256_montgomery<ScalarField>(value_data, convert_to_montgomery);
479 e.value = GroupElement::one() * e.scalar;
480 }
else if (choice < havoc_config.value_mutation_distribution[1]) {
482 if (convert_to_montgomery) {
483 e.scalar = e.scalar.to_montgomery_form();
488 if (rng.next() & 1) {
489 auto switch_sign =
static_cast<bool>(rng.next() & 1);
492 e.value += GroupElement::one() * extra;
495 e.value -= GroupElement::one() * extra;
503 e.value = e.value.normalize();
505 if (convert_to_montgomery) {
506 e.scalar = e.scalar.from_montgomery_form();
508 }
else if (choice < havoc_config.value_mutation_distribution[2]) {
509 if (convert_to_montgomery) {
510 e.scalar = e.scalar.to_montgomery_form();
514 e.scalar = get_special_scalar_value<ScalarField>(special_value);
515 if (convert_to_montgomery) {
516 e.scalar = e.scalar.to_montgomery_form();
518 e.value = GroupElement::one() * e.scalar;
532 template <
typename T>
540 bool convert_to_montgomery = (rng.next() % (havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY +
541 havoc_config.VAL_MUT_NON_MONTGOMERY_PROBABILITY)) <
542 havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY;
546 const size_t mutation_type_count = havoc_config.value_mutation_distribution.size();
548 const size_t choice = rng.next() % havoc_config.value_mutation_distribution[mutation_type_count - 1];
549 if (choice < havoc_config.value_mutation_distribution[0]) {
553 e = from_uint256_montgomery<ScalarField>(value_data, convert_to_montgomery);
554 }
else if (choice < havoc_config.value_mutation_distribution[1]) {
556 if (convert_to_montgomery) {
557 e = e.to_montgomery_form();
562 if (rng.next() & 1) {
563 auto switch_sign =
static_cast<bool>(rng.next() & 1);
573 if (convert_to_montgomery) {
574 e = e.from_montgomery_form();
576 }
else if (choice < havoc_config.value_mutation_distribution[2]) {
577 if (convert_to_montgomery) {
578 e = e.to_montgomery_form();
583 e = get_special_scalar_value<ScalarField>(special_value);
584 if (convert_to_montgomery) {
585 e = e.to_montgomery_form();
600 template <
typename T>
604#define PUT_RANDOM_BYTE_IF_LUCKY(variable) \
605 if (rng.next() & 1) { \
606 variable = rng.next() & 0xff; \
615 if (rng.next() & 1) {
628#ifndef DISABLE_MULTIPLICATION
632 if (rng.next() & 1) {
650#ifndef DISABLE_BATCH_MUL
652 if (rng.next() & 1) {
662 instruction.arguments.batchMulArgs.add_elements_count = mult_size;
664 if (
instruction.arguments.batchMulArgs.add_elements_count && (rng.next() & 1)) {
666 static_cast<uint8_t
>(rng.next() % (
instruction.arguments.batchMulArgs.add_elements_count));
667 for (
size_t i = 0; i < mut_count; i++) {
669 rng.next() %
static_cast<size_t>(
instruction.arguments.batchMulArgs.add_elements_count);
673 if (
instruction.arguments.batchMulArgs.add_elements_count && (rng.next() & 1)) {
675 static_cast<uint8_t
>(rng.next() % (
instruction.arguments.batchMulArgs.add_elements_count));
676 for (
size_t i = 0; i < mut_count; i++) {
678 rng.next() %
static_cast<size_t>(
instruction.arguments.batchMulArgs.add_elements_count);
704 static constexpr size_t DBL = 2;
705 static constexpr size_t NEG = 2;
707 static constexpr size_t SET = 2;
708 static constexpr size_t ADD = 3;
711#ifndef DISABLE_MULTIPLICATION
714#ifndef DISABLE_BATCH_MUL
727 static constexpr size_t SET = 0;
733 static constexpr size_t ADD = 1;
735 static constexpr size_t DBL = 1;
736 static constexpr size_t NEG = 1;
741#ifndef DISABLE_MULTIPLICATION
746#ifndef DISABLE_BATCH_MUL
773 auto scalar = ScalarField::serialize_from_buffer(Data);
774 auto el = GroupElement::one() * scalar;
793 instr.
arguments.
fourArgs = { .
in1 = *Data, .in2 = *(Data + 1), .in3 = *(Data + 2), .out = *(Data + 3) };
796#ifndef DISABLE_MULTIPLICATION
803#ifndef DISABLE_BATCH_MUL
816 for (
size_t i = 0; i < n; i++) {
838 template <
typename Instruction::OPCODE instruction_opcode>
842 switch (instruction_opcode) {
846 ScalarField::serialize_to_buffer(
instruction.arguments.element.scalar, Data + 1);
870#ifndef DISABLE_MULTIPLICATION
874 ScalarField::serialize_to_buffer(
instruction.arguments.mulArgs.scalar, Data + 3);
877#ifndef DISABLE_BATCH_MUL
879 *(Data + 1) =
instruction.arguments.batchMulArgs.add_elements_count;
880 *(Data + 2) =
instruction.arguments.batchMulArgs.output_index;
882 size_t n =
instruction.arguments.batchMulArgs.add_elements_count;
884 memcpy(Data + 3,
instruction.arguments.batchMulArgs.inputs, n);
886 for (
size_t i = 0; i < n; i++) {
887 ScalarField::serialize_to_buffer(
instruction.arguments.batchMulArgs.scalars[i], Data +
offset);
894 memcpy(Data + 1, &
instruction.arguments.randomseed,
sizeof(uint32_t));
915 const bool predicate_is_const =
static_cast<bool>(
VarianceRNG.
next() & 1);
916 if (predicate_is_const) {
917 const bool predicate_has_ctx =
static_cast<bool>(
VarianceRNG.
next() % 2);
918 debug_log(
"bool_t(", (predicate_has_ctx ?
"&builder," :
"nullptr,"), (predicate ?
"true)" :
"false)"));
919 return bool_t(predicate_has_ctx ?
builder :
nullptr, predicate);
921 debug_log(
"bool_t(witness_t(&builder, ", (predicate ?
"true));" :
"false))"));
1008 this->biggroup.is_point_at_infinity().get_value() || other.
biggroup.is_point_at_infinity().get_value();
1011 switch (add_option) {
1013 debug_log(
"left.checked_unconditional_add(right);",
"\n");
1014 return ExecutionHandler(base_scalar_res, base_res, this->
bg().checked_unconditional_add(other.
bg()));
1016 debug_log(
"right.checked_unconditional_add(left);",
"\n");
1017 return ExecutionHandler(base_scalar_res, base_res, other.
bg().checked_unconditional_add(this->bg()));
1033 if (other.
bg().get_value() == this->bg().get_value()) {
1038 if (other.
bg().get_value() == -this->bg().get_value()) {
1088 this->biggroup.is_point_at_infinity().get_value() || other.
biggroup.is_point_at_infinity().get_value();
1091 switch (add_option) {
1093 debug_log(
"left.checked_unconditional_subtract(right);",
"\n");
1095 base_scalar_res, base_res, this->
bg().checked_unconditional_subtract(other.
bg()));
1111 if (other.
bg().get_value() == -this->bg().get_value()) {
1114 if (other.
bg().get_value() == this->bg().get_value()) {
1124 (is_witness ?
"::from_witness(&builder, " :
"("),
1128 auto scalar = is_witness ? big_scalar_t::from_witness(
builder, multiplier) :
big_scalar_t(multiplier);
1129 return ExecutionHandler(this->base_scalar * multiplier, this->base * multiplier, this->
bg() * scalar);
1134 const std::vector<ScalarField>& to_mul)
1137 to_add_bg.reserve(to_add.size());
1139 to_mul_bs.reserve(to_mul.size());
1144 for (
size_t i = 0; i < to_add.size(); i++) {
1145 to_add_bg.push_back(to_add[i].
biggroup);
1149 (is_witness ?
"::from_witness(&builder, " :
"("),
1153 auto scalar = is_witness ? big_scalar_t::from_witness(
builder, to_mul[i]) :
big_scalar_t(to_mul[i]);
1154 to_mul_bs.push_back(scalar);
1156 accumulator_bg += to_add[i].base * to_mul[i];
1157 accumulator_bs += to_add[i].base_scalar * to_mul[i];
1159 accumulator_bg -= GroupElement::one();
1163 if (accumulator_bg.is_point_at_infinity()) {
1166 accumulator_bg += GroupElement::one();
1167 accumulator_bs += ScalarField::one();
1170 auto batch_mul_res = biggroup_t::batch_mul(to_add_bg, to_mul_bs);
1180 return ExecutionHandler(this->base_scalar + this->base_scalar, this->base.dbl(), this->bg().dbl());
1189 debug_log(
"lhs.conditional_select(rhs, ");
1192 debug_log(
"rhs.conditional_select(lhs, ");
1201 if (other.
bg().is_constant()) {
1202 if (this->
bg().is_constant()) {
1208 auto to_ae = other.
bg() + to_add;
1209 this->
bg().incomplete_assert_equal(to_ae);
1216 switch (switch_case) {
1223 (this->biggroup.is_constant() ?
"" :
"_constant"),
1224 "_witness(&builder, e.get_value());");
1231 debug_log(
"res = biggroup_t(tmp);",
"\n");
1234 bg_new = this->
bg();
1239 debug_log(
"res = biggroup_t(std::move(tmp));",
"\n");
1268 "auto c", stack.size() - 1,
" = biggroup_t(ae(\"",
instruction.arguments.element.scalar,
"\"));\n");
1291 " = biggroup_t::from_witness(&builder, ae(\"",
1321 " = biggroup_t::from_witness(&builder, ae(\"",
1325 debug_log(
"cw", stack.size() - 1,
".fix_witness();",
"\n");
1336 " = biggroup_t(ae(\"",
1340 debug_log(
"cw", stack.size() - 1,
".convert_constant_to_fixed_witness(&builder);",
"\n");
1359 if (stack.size() == 0) {
1362 size_t first_index =
instruction.arguments.oneArg.in % stack.size();
1365 auto args = format_self_arg(stack, first_index);
1366 debug_log(args.out,
".validate_on_curve();",
"\n");
1368 stack[first_index].validate_on_curve();
1385 if (stack.size() == 0) {
1388 size_t first_index =
instruction.arguments.twoArgs.in % stack.size();
1389 size_t output_index =
instruction.arguments.twoArgs.out;
1392 auto args = format_single_arg(stack, first_index, output_index);
1393 debug_log(args.out,
" = ", args.rhs,
".dbl();",
"\n");
1397 if (output_index >= stack.size()) {
1398 stack.push_back(result);
1400 stack[output_index] = result;
1418 if (stack.size() == 0) {
1421 size_t first_index =
instruction.arguments.twoArgs.in % stack.size();
1422 size_t output_index =
instruction.arguments.twoArgs.out;
1425 auto args = format_single_arg(stack, first_index, output_index);
1426 debug_log(args.out,
" = -", args.rhs,
";",
"\n");
1430 if (output_index >= stack.size()) {
1431 stack.push_back(result);
1433 stack[output_index] = result;
1450 if (stack.size() == 0) {
1453 size_t first_index =
instruction.arguments.twoArgs.in % stack.size();
1454 size_t second_index =
instruction.arguments.twoArgs.out % stack.size();
1457 auto args = format_two_arg(stack, first_index, second_index, 0);
1458 debug_log(
"incomplete_assert_equal(", args.lhs,
", ", args.rhs,
", builder);",
"\n");
1460 stack[first_index].incomplete_assert_equal(
builder, stack[second_index]);
1477 if (stack.size() == 0) {
1480 size_t first_index =
instruction.arguments.twoArgs.in % stack.size();
1481 size_t output_index =
instruction.arguments.twoArgs.out;
1485 auto args = format_single_arg(stack, first_index, output_index);
1494 if (output_index >= stack.size()) {
1495 stack.push_back(result);
1497 stack[output_index] = result;
1515 if (stack.size() == 0) {
1518 size_t first_index =
instruction.arguments.threeArgs.in1 % stack.size();
1519 size_t second_index =
instruction.arguments.threeArgs.in2 % stack.size();
1520 size_t output_index =
instruction.arguments.threeArgs.out;
1523 auto args = format_two_arg(stack, first_index, second_index, output_index);
1524 debug_log(args.out,
" = ", args.lhs,
" + ", args.rhs,
";",
"\n");
1528 if (output_index >= stack.size()) {
1529 stack.push_back(result);
1531 stack[output_index] = result;
1549 if (stack.size() == 0) {
1552 size_t first_index =
instruction.arguments.threeArgs.in1 % stack.size();
1553 size_t second_index =
instruction.arguments.threeArgs.in2 % stack.size();
1554 size_t output_index =
instruction.arguments.threeArgs.out;
1557 auto args = format_two_arg(stack, first_index, second_index, output_index);
1558 debug_log(args.out,
" = ", args.lhs,
" - ", args.rhs,
";",
"\n");
1562 if (output_index >= stack.size()) {
1563 stack.push_back(result);
1565 stack[output_index] = result;
1583 if (stack.size() == 0) {
1586 size_t first_index =
instruction.arguments.fourArgs.in1 % stack.size();
1587 size_t second_index =
instruction.arguments.fourArgs.in2 % stack.size();
1588 size_t output_index =
instruction.arguments.fourArgs.out % stack.size();
1589 bool predicate =
instruction.arguments.fourArgs.in3 % 2;
1593 auto args = format_two_arg(stack, first_index, second_index, output_index);
1594 debug_log(
"// ", args.out,
" = ::conditional_select::", args.lhs,
", ", args.rhs,
";",
"\n");
1602 if (output_index >= stack.size()) {
1603 stack.push_back(result);
1605 stack[output_index] = result;
1623 if (stack.size() == 0) {
1626 size_t first_index =
instruction.arguments.mulArgs.in % stack.size();
1627 size_t output_index =
instruction.arguments.mulArgs.out;
1631 auto args = format_single_arg(stack, first_index, output_index);
1636 if (output_index >= stack.size()) {
1637 stack.push_back(result);
1639 stack[output_index] = result;
1657 if (stack.size() == 0) {
1661 std::vector<ScalarField> to_mul;
1662 for (
size_t i = 0; i <
instruction.arguments.batchMulArgs.add_elements_count; i++) {
1663 to_add.push_back(stack[(
size_t)
instruction.arguments.batchMulArgs.inputs[i] % stack.size()]);
1664 to_mul.push_back(
instruction.arguments.batchMulArgs.scalars[i]);
1666 size_t output_index = (size_t)
instruction.arguments.batchMulArgs.output_index;
1670 std::string res =
"";
1671 bool is_const =
true;
1672 for (
size_t i = 0; i <
instruction.arguments.batchMulArgs.add_elements_count; i++) {
1673 size_t idx =
instruction.arguments.batchMulArgs.inputs[i] % stack.size();
1674 std::string el = stack[idx].
biggroup.is_constant() ?
"c" :
"w";
1677 is_const &= stack[idx].biggroup.is_constant();
1679 std::string out = is_const ?
"c" :
"w";
1680 out = ((output_index >= stack.size()) ?
"auto " :
"") + out;
1681 out +=
std::to_string(output_index >= stack.size() ? stack.size() : output_index);
1682 debug_log(out,
" = biggroup_t::batch_mul({", res,
"}, {");
1690 if (output_index >= stack.size()) {
1691 stack.push_back(result);
1693 stack[output_index] = result;
1735 for (
size_t i = 0; i < stack.size(); i++) {
1736 auto element = stack[i];
1737 if (element.biggroup.get_value() !=
AffineElement(element.base)) {
1739 <<
" and value in BigGroup " << element.biggroup.get_value() <<
std::endl;
1742 if ((AffineElement::one() * element.base_scalar) !=
AffineElement(element.base)) {
1743 std::cerr <<
"Failed at " << i <<
" with actual mul value " << element.base
1744 <<
" and value in scalar * BG " << element.biggroup.get_value() * element.base_scalar
1753template <
typename Builder>
1757template <
typename Builder>
1764template <
typename Builder>
1767template <
typename Builder>
1779 .GEN_MUTATION_COUNT_LOG = 5,
1780 .GEN_STRUCTURAL_MUTATION_PROBABILITY = 300,
1781 .GEN_VALUE_MUTATION_PROBABILITY = 700,
1782 .ST_MUT_DELETION_PROBABILITY = 100,
1783 .ST_MUT_DUPLICATION_PROBABILITY = 80,
1784 .ST_MUT_INSERTION_PROBABILITY = 120,
1785 .ST_MUT_MAXIMUM_DELETION_LOG = 6,
1786 .ST_MUT_MAXIMUM_DUPLICATION_LOG = 2,
1787 .ST_MUT_SWAP_PROBABILITY = 50,
1788 .VAL_MUT_LLVM_MUTATE_PROBABILITY = 250,
1789 .VAL_MUT_MONTGOMERY_PROBABILITY = 130,
1790 .VAL_MUT_NON_MONTGOMERY_PROBABILITY = 50,
1791 .VAL_MUT_SMALL_ADDITION_PROBABILITY = 110,
1792 .VAL_MUT_SPECIAL_VALUE_PROBABILITY = 130,
1793 .structural_mutation_distribution = {},
1794 .value_mutation_distribution = {} };
1865 std::vector<size_t> structural_mutation_distribution;
1866 std::vector<size_t> value_mutation_distribution;
1868 temp += fuzzer_havoc_settings.ST_MUT_DELETION_PROBABILITY;
1869 structural_mutation_distribution.push_back(temp);
1870 temp += fuzzer_havoc_settings.ST_MUT_DUPLICATION_PROBABILITY;
1871 structural_mutation_distribution.push_back(temp);
1872 temp += fuzzer_havoc_settings.ST_MUT_INSERTION_PROBABILITY;
1873 structural_mutation_distribution.push_back(temp);
1874 temp += fuzzer_havoc_settings.ST_MUT_SWAP_PROBABILITY;
1875 structural_mutation_distribution.push_back(temp);
1876 fuzzer_havoc_settings.structural_mutation_distribution = structural_mutation_distribution;
1879 temp += fuzzer_havoc_settings.VAL_MUT_LLVM_MUTATE_PROBABILITY;
1880 value_mutation_distribution.push_back(temp);
1881 temp += fuzzer_havoc_settings.VAL_MUT_SMALL_ADDITION_PROBABILITY;
1882 value_mutation_distribution.push_back(temp);
1883 temp += fuzzer_havoc_settings.VAL_MUT_SPECIAL_VALUE_PROBABILITY;
1884 value_mutation_distribution.push_back(temp);
1886 fuzzer_havoc_settings.value_mutation_distribution = value_mutation_distribution;
1898 RunWithBuilders<BigGroupBN254Base, FuzzerCircuitTypes>(Data, Size,
VarianceRNG);
1900 RunWithBuilders<BigGroupBN254BFBase, FuzzerCircuitTypes>(Data, Size,
VarianceRNG);
1902 RunWithBuilders<BigGroupSecp256k1Base, FuzzerCircuitTypes>(Data, Size,
VarianceRNG);
1904 RunWithBuilders<BigGroupSecp256r1Base, FuzzerCircuitTypes>(Data, Size,
VarianceRNG);
1911#pragma clang diagnostic pop
bb::field< bb::Bn254FrParams > FF
constexpr size_t MINIMUM_MUL_ELEMENTS
constexpr uint8_t SPECIAL_VALUE_COUNT_NO_ZERO
constexpr size_t MAXIMUM_MUL_ELEMENTS
constexpr uint8_t SPECIAL_VALUE_COUNT
SpecialScalarValue
Special scalar field values used for mutation testing.
size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize)
FastRandom VarianceRNG(0)
int LLVMFuzzerInitialize(int *argc, char ***argv)
FF get_special_scalar_value(SpecialScalarValue type)
Generate a special scalar field value for testing.
size_t LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
Fuzzer entry function.
#define PUT_RANDOM_BYTE_IF_LUCKY(variable)
constexpr uint64_t BigCurveTypes
static constexpr size_t SET
static constexpr size_t DBL
static constexpr size_t NEG
static constexpr size_t ASSERT_EQUAL
static constexpr size_t RANDOMSEED
static constexpr size_t ADD
static constexpr size_t BATCH_MUL
static constexpr size_t SUBTRACT
static constexpr size_t WITNESS
static constexpr size_t CONSTANT_WITNESS
static constexpr size_t MULTIPLY
static constexpr size_t COND_ASSIGN
static constexpr size_t CONSTANT
static constexpr size_t VALIDATE_ON_CURVE
This class implements the execution of biggroup with an oracle to detect discrepancies.
ExecutionHandler()=default
static size_t execute_VALIDATE_ON_CURVE(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the VALIDATE_ON_CURVE instruction.
static size_t execute_MULTIPLY(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the multiply instruction.
static size_t execute_SUBTRACT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the subtraction operator instruction.
ExecutionHandler handle_sub_infinity_case(const ExecutionHandler &other, const ScalarField &base_scalar_res, const GroupElement &base_res)
Handle subtraction when points are equal: x - x = 0 (point at infinity)
ExecutionHandler operator_add(Builder *builder, const ExecutionHandler &other)
ExecutionHandler handle_sub_normal_case(const ExecutionHandler &other, const ScalarField &base_scalar_res, const GroupElement &base_res)
Handle normal subtraction case (no special edge cases)
ExecutionHandler mul(Builder *builder, const ScalarField &multiplier)
static size_t execute_DBL(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the DBL instruction.
static size_t execute_NEG(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the NEG instruction.
static size_t execute_ADD(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the addition operator instruction.
static bool_t construct_predicate(Builder *builder, const bool predicate)
ExecutionHandler operator-()
static size_t execute_CONSTANT_WITNESS(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the constant_witness instruction (push a biggroup witness set to be public or constant made w...
static size_t execute_ASSERT_EQUAL(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the ASSERT_EQUAL instruction.
static ExecutionHandler batch_mul(Builder *builder, const std::vector< ExecutionHandler > &to_add, const std::vector< ScalarField > &to_mul)
void incomplete_assert_equal(Builder *builder, ExecutionHandler &other)
static size_t execute_RANDOMSEED(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the RANDOMSEED instruction.
static size_t execute_SET(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SET instruction.
static size_t execute_COND_ASSIGN(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the COND_ASSIGN instruction.
ExecutionHandler set(Builder *builder)
static size_t execute_CONSTANT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the constant instruction (push constant biggroup to the stack)
void validate_on_curve() const
ExecutionHandler handle_add_normal_case(const ExecutionHandler &other, const ScalarField &base_scalar_res, const GroupElement &base_res)
Handle normal addition (no special edge cases)
ExecutionHandler handle_sub_doubling_case(Builder *builder, const ExecutionHandler &other, const ScalarField &base_scalar_res, const GroupElement &base_res)
Handle subtraction when points are negations: x - (-x) = 2x (doubling case)
static size_t execute_BATCH_MUL(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the BATCH_MUL instruction.
ExecutionHandler handle_add_doubling_case(Builder *builder, const ExecutionHandler &other, const ScalarField &base_scalar_res, const GroupElement &base_res)
Handle addition when points are equal (requires doubling)
ExecutionHandler operator_sub(Builder *builder, const ExecutionHandler &other)
Subtract two ExecutionHandlers, exploring different code paths for edge cases.
ExecutionHandler conditional_select(Builder *builder, ExecutionHandler &other, const bool predicate)
ExecutionHandler(ScalarField s, GroupElement g, biggroup_t w_g)
static size_t execute_WITNESS(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the witness instruction (push witness biggroup to the stack)
ExecutionHandler handle_add_infinity_case(const ExecutionHandler &other, const ScalarField &base_scalar_res, const GroupElement &base_res)
Handle addition when points are negations (result is point at infinity)
static uint256_t to_uint256_montgomery(const FF &value, bool as_montgomery)
Convert a scalar field element to uint256_t, optionally using Montgomery form.
static Element mutateGroupElement(Element e, T &rng, HavocSettings &havoc_config)
Mutate the value of a group element.
static Instruction mutateInstruction(Instruction instruction, T &rng, HavocSettings &havoc_config)
Mutate a single instruction.
static Instruction generateRandom(T &rng)
Generates a random instruction.
static ScalarField mutateScalarElement(ScalarField e, T &rng, HavocSettings &havoc_config)
Mutate the value of a scalar element.
ArgumentContents arguments
static FF from_uint256_montgomery(const uint256_t &data, bool from_montgomery)
Convert uint256_t back to scalar field element, optionally from Montgomery form.
Optional subclass that governs limits on the use of certain instructions, since some of them can be t...
static constexpr size_t SET
static constexpr size_t RANDOMSEED
static constexpr size_t MULTIPLY
static constexpr size_t CONSTANT
static constexpr size_t _LIMIT
static constexpr size_t BATCH_MUL
static constexpr size_t CONSTANT_WITNESS
static constexpr size_t ASSERT_EQUAL
static constexpr size_t WITNESS
static constexpr size_t NEG
static constexpr size_t VALIDATE_ON_CURVE
static constexpr size_t COND_ASSIGN
static constexpr size_t SUBTRACT
static constexpr size_t ADD
static constexpr size_t DBL
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 BigGroup fuzzing instructions, execution, etc.
std::conditional_t< _use_bigfield, bb::stdlib::element< Builder, typename Curve::BaseField, BigfieldScalar, typename Curve::GroupNative >, typename Curve::Group > biggroup_t
typename Curve::AffineElementNative AffineElement
typename Curve::ElementNative GroupElement
std::conditional_t< _use_bigfield, BigfieldScalar, typename Curve::ScalarField > big_scalar_t
typename Curve::ScalarFieldNative ScalarField
typename bb::stdlib::bool_t< Builder > bool_t
static bool postProcess(Builder *builder, std::vector< BigGroupBase::ExecutionHandler > &stack)
Check that the resulting values are equal to expected.
typename bb::stdlib::field_t< Builder > field_t
static biggroup_t make_constant_biggroup(const AffineElement &native_elem)
Create a constant (no-witness) biggroup element from a native affine element.
std::vector< ExecutionHandler > ExecutionState
typename bb::stdlib::witness_t< Builder > witness_t
typename Curve::BaseFieldNative BaseField
Class for quickly deterministically creating new random values. We don't care about distribution much...
void reseed(uint32_t seed)
Implements boolean logic in-circuit.
Concept for a simple PRNG which returns a uint32_t when next is called.
const std::vector< MemoryValue > data
ECCVMCircuitBuilder Builder
void debug_log(Args &&... args)
Compile-time debug logging helper.
constexpr bool SHOW_FUZZING_INFO
std::conditional_t< IsGoblinBigGroup< C, Fq, Fr, G >, element_goblin::goblin_element< C, goblin_field< C >, Fr, G >, element_default::element< C, Fq, Fr, G > > element
element wraps either element_default::element or element_goblin::goblin_element depending on parametr...
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::string to_string(bb::avm2::ValueTag tag)
BatchMulArgs batchMulArgs
uint8_t inputs[MAXIMUM_MUL_ELEMENTS]
uint8_t add_elements_count
ScalarField scalars[MAXIMUM_MUL_ELEMENTS]
Element(ScalarField s=ScalarField::one(), GroupElement g=GroupElement::one())
size_t GEN_LLVM_POST_MUTATION_PROB
static constexpr field get_root_of_unity(size_t subgroup_size) noexcept
static constexpr field one()
static constexpr uint256_t modulus
BB_INLINE constexpr field to_montgomery_form() const noexcept
constexpr std::pair< bool, field > sqrt() const noexcept
Compute square root of the field element.
BB_INLINE constexpr field from_montgomery_form() const noexcept
static constexpr field zero()