12#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wc99-designator"
34#ifdef FUZZING_SHOW_INFORMATION
35#define PREP_SINGLE_ARG(stack, first_index, output_index) \
36 std::string rhs = stack[first_index].cycle_group.is_constant() ? "c" : "w"; \
37 std::string out = rhs; \
38 rhs += std::to_string(first_index); \
39 out += std::to_string(output_index >= stack.size() ? stack.size() : output_index); \
40 out = (output_index >= stack.size() ? "auto " : "") + out;
42#define PREP_TWO_ARG(stack, first_index, second_index, output_index) \
43 std::string lhs = stack[first_index].cycle_group.is_constant() ? "c" : "w"; \
44 std::string rhs = stack[second_index].cycle_group.is_constant() ? "c" : "w"; \
46 (stack[first_index].cycle_group.is_constant() && stack[second_index].cycle_group.is_constant()) ? "c" : "w"; \
47 lhs += std::to_string(first_index); \
48 rhs += std::to_string(second_index); \
49 out += std::to_string(output_index >= stack.size() ? stack.size() : output_index); \
50 out = (output_index >= stack.size() ? "auto " : "") + out;
93#ifndef DISABLE_MULTIPLICATION
96#ifndef DISABLE_BATCH_MUL
167 template <
typename T>
172 uint8_t in, in1, in2, in3, out;
175 switch (instruction_opcode) {
179 auto scalar =
ScalarField(
static_cast<uint64_t
>(fast_log_distributed_uint256(rng)));
180 auto el = GroupElement::one() * scalar;
181 return { .id = instruction_opcode, .arguments.element =
Element(scalar, el) };
188 in =
static_cast<uint8_t
>(rng.next() & 0xff);
189 out =
static_cast<uint8_t
>(rng.next() & 0xff);
190 return { .id = instruction_opcode, .arguments.twoArgs = { .in = in, .out = out } };
193 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
194 in2 =
static_cast<uint8_t
>(rng.next() & 0xff);
195 out =
static_cast<uint8_t
>(rng.next() & 0xff);
196 return { .id = instruction_opcode,
197 .arguments.threeArgs.in1 = in1,
198 .arguments.threeArgs.in2 = in2,
199 .arguments.threeArgs.out = out };
201 in1 =
static_cast<uint8_t
>(rng.next() & 0xff);
202 in2 =
static_cast<uint8_t
>(rng.next() & 0xff);
203 in3 =
static_cast<uint8_t
>(rng.next() & 0xff);
204 out =
static_cast<uint8_t
>(rng.next() & 0xff);
205 return { .id = instruction_opcode,
206 .arguments.fourArgs.in1 = in1,
207 .arguments.fourArgs.in2 = in2,
208 .arguments.fourArgs.in3 = in3,
209 .arguments.fourArgs.out = out };
210#ifndef DISABLE_MULTIPLICATION
212 in =
static_cast<uint8_t
>(rng.next() & 0xff);
213 out =
static_cast<uint8_t
>(rng.next() & 0xff);
214 return { .id = instruction_opcode,
216 .arguments.mulArgs.in = in,
217 .arguments.mulArgs.out = out };
219#ifndef DISABLE_BATCH_MUL
230 instr.
id = instruction_opcode;
232 for (
size_t i = 0; i < mult_size; i++) {
235 for (
size_t i = 0; i < mult_size; i++) {
243 return { .
id = instruction_opcode, .arguments.randomseed = rng.next() * rng.next() };
259 template <
typename T>
270 bool convert_to_montgomery = (rng.next() % (havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY +
271 havoc_config.VAL_MUT_NON_MONTGOMERY_PROBABILITY)) <
272 havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY;
273 bool normalize = (rng.next() % (havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY +
274 havoc_config.VAL_MUT_NON_MONTGOMERY_PROBABILITY)) <
275 havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY;
278#define MONT_CONVERSION \
279 if (convert_to_montgomery) { \
280 value_data = uint256_t(e.scalar.to_montgomery_form()); \
282 value_data = uint256_t(e.scalar); \
285#define INV_MONT_CONVERSION \
286 if (convert_to_montgomery) { \
287 e.scalar = ScalarField(value_data).from_montgomery_form(); \
289 e.scalar = ScalarField(value_data); \
293 const size_t mutation_type_count = havoc_config.value_mutation_distribution.size();
295 const size_t choice = rng.next() % havoc_config.value_mutation_distribution[mutation_type_count - 1];
296 if (choice < havoc_config.value_mutation_distribution[0]) {
301 e.value = GroupElement::one() * e.scalar;
302 }
else if (choice < havoc_config.value_mutation_distribution[1]) {
304 if (convert_to_montgomery) {
305 e.scalar = e.scalar.to_montgomery_form();
310 if (rng.next() & 1) {
311 auto switch_sign =
static_cast<bool>(rng.next() & 1);
314 e.value += GroupElement::one() * extra;
317 e.value -= GroupElement::one() * extra;
325 e.value = e.value.normalize();
327 if (convert_to_montgomery) {
328 e.scalar = e.scalar.from_montgomery_form();
330 }
else if (choice < havoc_config.value_mutation_distribution[2]) {
331 if (convert_to_montgomery) {
332 e.scalar = e.scalar.to_montgomery_form();
335 switch (rng.next() % 8) {
337 e.scalar = ScalarField::zero();
340 e.scalar = ScalarField::one();
343 e.scalar = -ScalarField::one();
346 e.scalar = ScalarField::one().sqrt().second;
349 e.scalar = ScalarField::one().sqrt().second.invert();
352 e.scalar = ScalarField::get_root_of_unity(13);
358 e.scalar =
ScalarField((ScalarField::modulus - 1) / 2);
364 if (convert_to_montgomery) {
365 e.scalar = e.scalar.to_montgomery_form();
367 e.value = GroupElement::one() * e.scalar;
381 template <
typename T>
389 bool convert_to_montgomery = (rng.next() % (havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY +
390 havoc_config.VAL_MUT_NON_MONTGOMERY_PROBABILITY)) <
391 havoc_config.VAL_MUT_MONTGOMERY_PROBABILITY;
394#define MONT_CONVERSION_SCALAR \
395 if (convert_to_montgomery) { \
396 value_data = uint256_t(e.to_montgomery_form()); \
398 value_data = uint256_t(e); \
401#define INV_MONT_CONVERSION_SCALAR \
402 if (convert_to_montgomery) { \
403 e = ScalarField(value_data).from_montgomery_form(); \
405 e = ScalarField(value_data); \
409 const size_t mutation_type_count = havoc_config.value_mutation_distribution.size();
411 const size_t choice = rng.next() % havoc_config.value_mutation_distribution[mutation_type_count - 1];
412 if (choice < havoc_config.value_mutation_distribution[0]) {
417 }
else if (choice < havoc_config.value_mutation_distribution[1]) {
419 if (convert_to_montgomery) {
420 e = e.to_montgomery_form();
425 if (rng.next() & 1) {
426 auto switch_sign =
static_cast<bool>(rng.next() & 1);
436 if (convert_to_montgomery) {
437 e = e.from_montgomery_form();
439 }
else if (choice < havoc_config.value_mutation_distribution[2]) {
440 if (convert_to_montgomery) {
441 e = e.to_montgomery_form();
445 switch (rng.next() % 7) {
447 e = ScalarField::one();
450 e = -ScalarField::one();
453 e = ScalarField::one().sqrt().second;
456 e = ScalarField::one().sqrt().second.invert();
459 e = ScalarField::get_root_of_unity(13);
471 if (convert_to_montgomery) {
472 e = e.to_montgomery_form();
487 template <
typename T>
491#define PUT_RANDOM_BYTE_IF_LUCKY(variable) \
492 if (rng.next() & 1) { \
493 variable = rng.next() & 0xff; \
502 if (rng.next() & 1) {
516#ifndef DISABLE_MULTIPLICATION
520 if (rng.next() & 1) {
538#ifndef DISABLE_BATCH_MUL
540 if (rng.next() & 1) {
550 instruction.arguments.batchMulArgs.add_elements_count = mult_size;
552 if (
instruction.arguments.batchMulArgs.add_elements_count && (rng.next() & 1)) {
554 static_cast<uint8_t
>(rng.next() % (
instruction.arguments.batchMulArgs.add_elements_count));
555 for (
size_t i = 0; i < mut_count; i++) {
557 rng.next() %
static_cast<size_t>(
instruction.arguments.batchMulArgs.add_elements_count);
561 if (
instruction.arguments.batchMulArgs.add_elements_count && (rng.next() & 1)) {
563 static_cast<uint8_t
>(rng.next() % (
instruction.arguments.batchMulArgs.add_elements_count));
564 for (
size_t i = 0; i < mut_count; i++) {
566 rng.next() %
static_cast<size_t>(
instruction.arguments.batchMulArgs.add_elements_count);
591 static constexpr size_t DBL = 2;
592 static constexpr size_t NEG = 2;
594 static constexpr size_t SET = 2;
596 static constexpr size_t ADD = 3;
599#ifndef DISABLE_MULTIPLICATION
602#ifndef DISABLE_BATCH_MUL
615 static constexpr size_t SET = 0;
621 static constexpr size_t ADD = 1;
623 static constexpr size_t DBL = 1;
624 static constexpr size_t NEG = 1;
627#ifndef DISABLE_MULTIPLICATION
633#ifndef DISABLE_BATCH_MUL
659 auto scalar = ScalarField::serialize_from_buffer(Data);
660 auto el = GroupElement::one() * scalar;
676 instr.
arguments.
fourArgs = { .
in1 = *Data, .in2 = *(Data + 1), .in3 = *(Data + 2), .out = *(Data + 3) };
679#ifndef DISABLE_MULTIPLICATION
686#ifndef DISABLE_BATCH_MUL
699 for (
size_t i = 0; i < n; i++) {
720 template <
typename Instruction::OPCODE instruction_opcode>
724 switch (instruction_opcode) {
728 ScalarField::serialize_to_buffer(
instruction.arguments.element.scalar, Data + 1);
750#ifndef DISABLE_MULTIPLICATION
754 ScalarField::serialize_to_buffer(
instruction.arguments.mulArgs.scalar, Data + 3);
757#ifndef DISABLE_BATCH_MUL
759 *(Data + 1) =
instruction.arguments.batchMulArgs.add_elements_count;
760 *(Data + 2) =
instruction.arguments.batchMulArgs.output_index;
762 size_t n =
instruction.arguments.batchMulArgs.add_elements_count;
764 memcpy(Data + 3,
instruction.arguments.batchMulArgs.inputs, n);
766 for (
size_t i = 0; i < n; i++) {
767 ScalarField::serialize_to_buffer(
instruction.arguments.batchMulArgs.scalars[i], Data +
offset);
774 memcpy(Data + 1, &
instruction.arguments.randomseed,
sizeof(uint32_t));
794 const bool predicate_is_const =
static_cast<bool>(
VarianceRNG.
next() & 1);
795 if (predicate_is_const) {
796 const bool predicate_has_ctx =
static_cast<bool>(
VarianceRNG.
next() % 2);
797#ifdef FUZZING_SHOW_INFORMATION
798 std::cout <<
"bool_t(" << (predicate_has_ctx ?
"&builder," :
"nullptr,")
799 << (predicate ?
"true)" :
"false)");
801 return bool_t(predicate_has_ctx ?
builder :
nullptr, predicate);
803#ifdef FUZZING_SHOW_INFORMATION
804 std::cout <<
"bool_t(witness_t(&builder, " << (predicate ?
"true));" :
"false))");
835 if (other.
cg().get_value() == this->cg().get_value()) {
839#ifdef FUZZING_SHOW_INFORMATION
844#ifdef FUZZING_SHOW_INFORMATION
853 }
else if (other.
cg().get_value() == -this->cg().get_value()) {
858#ifdef FUZZING_SHOW_INFORMATION
859 std::cout <<
"left.set_point_at_infinity(";
863#ifdef FUZZING_SHOW_INFORMATION
868#ifdef FUZZING_SHOW_INFORMATION
869 std::cout <<
"right.set_point_at_infinity(";
873#ifdef FUZZING_SHOW_INFORMATION
883 bool smth_inf = this->cycle_group.is_point_at_infinity().get_value() ||
884 other.
cycle_group.is_point_at_infinity().get_value();
887 switch (add_option) {
889#ifdef FUZZING_SHOW_INFORMATION
894#ifdef FUZZING_SHOW_INFORMATION
897 return ExecutionHandler(base_scalar_res, base_res, other.
cg().unconditional_add(this->cg()));
899#ifdef FUZZING_SHOW_INFORMATION
902 return ExecutionHandler(base_scalar_res, base_res, this->
cg().checked_unconditional_add(other.
cg()));
904#ifdef FUZZING_SHOW_INFORMATION
907 return ExecutionHandler(base_scalar_res, base_res, other.
cg().checked_unconditional_add(this->cg()));
921 if (other.
cg().get_value() == -this->cg().get_value()) {
926#ifdef FUZZING_SHOW_INFORMATION
931#ifdef FUZZING_SHOW_INFORMATION
938 }
else if (other.
cg().get_value() == this->cg().get_value()) {
944#ifdef FUZZING_SHOW_INFORMATION
945 std::cout <<
"left.set_point_at_infinity(";
949#ifdef FUZZING_SHOW_INFORMATION
954#ifdef FUZZING_SHOW_INFORMATION
955 std::cout <<
"right.set_point_at_infinity(";
959#ifdef FUZZING_SHOW_INFORMATION
967 bool smth_inf = this->cycle_group.is_point_at_infinity().get_value() ||
968 other.
cycle_group.is_point_at_infinity().get_value();
971 switch (add_option) {
973#ifdef FUZZING_SHOW_INFORMATION
976 return ExecutionHandler(base_scalar_res, base_res, this->
cg().unconditional_subtract(other.
cg()));
978#ifdef FUZZING_SHOW_INFORMATION
982 base_scalar_res, base_res, this->
cg().checked_unconditional_subtract(other.
cg()));
992#ifdef FUZZING_SHOW_INFORMATION
993 std::cout <<
" * cycle_scalar_t" << (is_witness ?
"::from_witness(&builder, " :
"(") <<
"ScalarField(\""
994 << multiplier <<
"\"));";
996 auto scalar = is_witness ? cycle_scalar_t::from_witness(
builder, multiplier) :
cycle_scalar_t(multiplier);
997 return ExecutionHandler(this->base_scalar * multiplier, this->base * multiplier, this->
cg() * scalar);
1002 const std::vector<ScalarField>& to_mul)
1005 to_add_cg.reserve(to_add.size());
1007 to_mul_cs.reserve(to_mul.size());
1012 for (
size_t i = 0; i < to_add.size(); i++) {
1016#ifdef FUZZING_SHOW_INFORMATION
1017 std::cout <<
"cycle_scalar_t" << (is_witness ?
"::from_witness(&builder, " :
"(") <<
"ScalarField(\""
1018 << to_mul[i] <<
"\")), ";
1020 auto scalar = is_witness ? cycle_scalar_t::from_witness(
builder, to_mul[i]) :
cycle_scalar_t(to_mul[i]);
1021 to_mul_cs.push_back(scalar);
1023 accumulator_cg += to_add[i].base * to_mul[i];
1024 accumulator_cs += to_add[i].base_scalar * to_mul[i];
1026 accumulator_cg -= GroupElement::one();
1030 if (accumulator_cg.is_point_at_infinity()) {
1033 accumulator_cg += GroupElement::one();
1034 accumulator_cs += ScalarField::one();
1044 this->base = -this->
base;
1050 return ExecutionHandler(this->base_scalar + this->base_scalar, this->base.dbl(), this->cg().dbl());
1064 if (other.
cg().is_constant()) {
1065 if (this->
cg().is_constant()) {
1071 auto to_ae = other.
cg() + to_add;
1072 this->
cg().assert_equal(to_ae);
1079 switch (switch_case) {
1081#ifdef FUZZING_SHOW_INFORMATION
1087#ifdef FUZZING_SHOW_INFORMATION
1088 std::cout <<
"cycle_group_t::from" << (this->cycle_group.is_constant() ?
"" :
"_constant")
1089 <<
"_witness(&builder, e.get_value());";
1093 if (this->cycle_group.is_constant()) {
1100#ifdef FUZZING_SHOW_INFORMATION
1106 cg_new = this->
cg();
1110#ifdef FUZZING_SHOW_INFORMATION
1125 auto res = this->
set(builder);
1128#ifdef FUZZING_SHOW_INFORMATION
1129 std::cout <<
"el.set_point_at_infinty(";
1132#ifdef FUZZING_SHOW_INFORMATION
1155#ifdef FUZZING_SHOW_INFORMATION
1156 std::cout <<
"auto c" << stack.size() - 1 <<
" = cycle_group_t(ae(\""
1178#ifdef FUZZING_SHOW_INFORMATION
1179 std::cout <<
"auto w" << stack.size() - 1 <<
" = cycle_group_t::from_witness(&builder, ae(\""
1203#ifdef FUZZING_SHOW_INFORMATION
1204 std::cout <<
"auto cw" << stack.size() - 1 <<
" = cycle_group_t::from_constant_witness(&builder, ae(\""
1223 if (stack.size() == 0) {
1226 size_t first_index =
instruction.arguments.twoArgs.in % stack.size();
1227 size_t output_index =
instruction.arguments.twoArgs.out;
1229#ifdef FUZZING_SHOW_INFORMATION
1230 PREP_SINGLE_ARG(stack, first_index, output_index)
1234 result = stack[first_index].
dbl();
1236 if (output_index >= stack.size()) {
1237 stack.push_back(result);
1239 stack[output_index] = result;
1257 if (stack.size() == 0) {
1260 size_t first_index =
instruction.arguments.twoArgs.in % stack.size();
1261 size_t output_index =
instruction.arguments.twoArgs.out;
1263#ifdef FUZZING_SHOW_INFORMATION
1264 PREP_SINGLE_ARG(stack, first_index, output_index)
1268 result = -stack[first_index];
1270 if (output_index >= stack.size()) {
1271 stack.push_back(result);
1273 stack[output_index] = result;
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#ifdef FUZZING_SHOW_INFORMATION
1297 PREP_TWO_ARG(stack, first_index, second_index, 0)
1300 stack[first_index].assert_equal(
builder, stack[second_index]);
1317 if (stack.size() == 0) {
1320 size_t first_index =
instruction.arguments.twoArgs.in % stack.size();
1321 size_t output_index =
instruction.arguments.twoArgs.out;
1324#ifdef FUZZING_SHOW_INFORMATION
1325 PREP_SINGLE_ARG(stack, first_index, output_index)
1329#ifdef FUZZING_SHOW_INFORMATION
1333 if (output_index >= stack.size()) {
1334 stack.push_back(result);
1336 stack[output_index] = result;
1354 if (stack.size() == 0) {
1357 size_t first_index =
instruction.arguments.twoArgs.in % stack.size();
1358 size_t output_index =
instruction.arguments.twoArgs.out;
1361#ifdef FUZZING_SHOW_INFORMATION
1362 PREP_SINGLE_ARG(stack, first_index, output_index)
1367 if (output_index >= stack.size()) {
1368 stack.push_back(result);
1370 stack[output_index] = result;
1388 if (stack.size() == 0) {
1391 size_t first_index =
instruction.arguments.threeArgs.in1 % stack.size();
1392 size_t second_index =
instruction.arguments.threeArgs.in2 % stack.size();
1393 size_t output_index =
instruction.arguments.threeArgs.out;
1395#ifdef FUZZING_SHOW_INFORMATION
1396 PREP_TWO_ARG(stack, first_index, second_index, output_index)
1402 if (output_index >= stack.size()) {
1403 stack.push_back(result);
1405 stack[output_index] = result;
1423 if (stack.size() == 0) {
1426 size_t first_index =
instruction.arguments.threeArgs.in1 % stack.size();
1427 size_t second_index =
instruction.arguments.threeArgs.in2 % stack.size();
1428 size_t output_index =
instruction.arguments.threeArgs.out;
1430#ifdef FUZZING_SHOW_INFORMATION
1431 PREP_TWO_ARG(stack, first_index, second_index, output_index)
1437 if (output_index >= stack.size()) {
1438 stack.push_back(result);
1440 stack[output_index] = result;
1458 if (stack.size() == 0) {
1461 size_t first_index =
instruction.arguments.fourArgs.in1 % stack.size();
1462 size_t second_index =
instruction.arguments.fourArgs.in2 % stack.size();
1463 size_t output_index =
instruction.arguments.fourArgs.out % stack.size();
1464 bool predicate =
instruction.arguments.fourArgs.in3 % 2;
1468#ifdef FUZZING_SHOW_INFORMATION
1469 PREP_TWO_ARG(stack, first_index, second_index, output_index)
1470 std::cout << out <<
" = cycle_group_t::conditional_assign(";
1473#ifdef FUZZING_SHOW_INFORMATION
1477 if (output_index >= stack.size()) {
1478 stack.push_back(result);
1480 stack[output_index] = result;
1498 if (stack.size() == 0) {
1501 size_t first_index =
instruction.arguments.mulArgs.in % stack.size();
1502 size_t output_index =
instruction.arguments.mulArgs.out;
1505#ifdef FUZZING_SHOW_INFORMATION
1506 PREP_SINGLE_ARG(stack, first_index, output_index)
1510 result = stack[first_index].
mul(
builder, scalar);
1512 if (output_index >= stack.size()) {
1513 stack.push_back(result);
1515 stack[output_index] = result;
1533 if (stack.size() == 0) {
1537 std::vector<ScalarField> to_mul;
1538 for (
size_t i = 0; i <
instruction.arguments.batchMulArgs.add_elements_count; i++) {
1539 to_add.push_back(stack[(
size_t)
instruction.arguments.batchMulArgs.inputs[i] % stack.size()]);
1540 to_mul.push_back(
instruction.arguments.batchMulArgs.scalars[i]);
1542 size_t output_index = (size_t)
instruction.arguments.batchMulArgs.output_index;
1544#ifdef FUZZING_SHOW_INFORMATION
1545 std::string res =
"";
1546 bool is_const =
true;
1547 for (
size_t i = 0; i <
instruction.arguments.batchMulArgs.add_elements_count; i++) {
1548 size_t idx =
instruction.arguments.batchMulArgs.inputs[i] % stack.size();
1549 std::string el = stack[idx].cycle_group.is_constant() ?
"c" :
"w";
1552 is_const &= stack[idx].cycle_group.is_constant();
1554 std::string out = is_const ?
"c" :
"w";
1555 out = ((output_index >= stack.size()) ?
"auto " :
"") + out;
1556 out +=
std::to_string(output_index >= stack.size() ? stack.size() : output_index);
1557 std::cout << out <<
" = cycle_group_t::batch_mul({" << res <<
"}, {";
1561#ifdef FUZZING_SHOW_INFORMATION
1565 if (output_index >= stack.size()) {
1566 stack.push_back(result);
1568 stack[output_index] = result;
1610 for (
size_t i = 0; i < stack.size(); i++) {
1611 auto element = stack[i];
1612 if (element.cycle_group.get_value() !=
AffineElement(element.base)) {
1614 <<
" and value in CycleGroup " << element.cycle_group.get_value() <<
std::endl;
1617 if ((AffineElement::one() * element.base_scalar) !=
AffineElement(element.base)) {
1618 std::cerr <<
"Failed at " << i <<
" with actual mul value " << element.base
1619 <<
" and value in scalar * CG " << element.cycle_group.get_value() * element.base_scalar
1624 bool fake_standardized = element.cycle_group.is_standard();
1625 fake_standardized &= element.cycle_group.is_point_at_infinity().get_value();
1626 fake_standardized &= (element.cycle_group.x.get_value() != 0) || (element.cycle_group.y.get_value() != 0);
1627 if (fake_standardized) {
1628 std::cerr <<
"Failed at " << i <<
" with value claimed to be standard: (0, 0) but the actual value is ("
1629 << element.cycle_group.x.get_value() <<
", " << element.cycle_group.y.get_value() <<
")"
1647 .GEN_MUTATION_COUNT_LOG = 5,
1648 .GEN_STRUCTURAL_MUTATION_PROBABILITY = 300,
1649 .GEN_VALUE_MUTATION_PROBABILITY = 700,
1650 .ST_MUT_DELETION_PROBABILITY = 100,
1651 .ST_MUT_DUPLICATION_PROBABILITY = 80,
1652 .ST_MUT_INSERTION_PROBABILITY = 120,
1653 .ST_MUT_MAXIMUM_DELETION_LOG = 6,
1654 .ST_MUT_MAXIMUM_DUPLICATION_LOG = 2,
1655 .ST_MUT_SWAP_PROBABILITY = 50,
1656 .VAL_MUT_LLVM_MUTATE_PROBABILITY = 250,
1657 .VAL_MUT_MONTGOMERY_PROBABILITY = 130,
1658 .VAL_MUT_NON_MONTGOMERY_PROBABILITY = 50,
1659 .VAL_MUT_SMALL_ADDITION_PROBABILITY = 110,
1660 .VAL_MUT_SPECIAL_VALUE_PROBABILITY = 130,
1661 .structural_mutation_distribution = {},
1662 .value_mutation_distribution = {} };
1733 std::vector<size_t> structural_mutation_distribution;
1734 std::vector<size_t> value_mutation_distribution;
1736 temp += fuzzer_havoc_settings.ST_MUT_DELETION_PROBABILITY;
1737 structural_mutation_distribution.push_back(temp);
1738 temp += fuzzer_havoc_settings.ST_MUT_DUPLICATION_PROBABILITY;
1739 structural_mutation_distribution.push_back(temp);
1740 temp += fuzzer_havoc_settings.ST_MUT_INSERTION_PROBABILITY;
1741 structural_mutation_distribution.push_back(temp);
1742 temp += fuzzer_havoc_settings.ST_MUT_SWAP_PROBABILITY;
1743 structural_mutation_distribution.push_back(temp);
1744 fuzzer_havoc_settings.structural_mutation_distribution = structural_mutation_distribution;
1747 temp += fuzzer_havoc_settings.VAL_MUT_LLVM_MUTATE_PROBABILITY;
1748 value_mutation_distribution.push_back(temp);
1749 temp += fuzzer_havoc_settings.VAL_MUT_SMALL_ADDITION_PROBABILITY;
1750 value_mutation_distribution.push_back(temp);
1751 temp += fuzzer_havoc_settings.VAL_MUT_SPECIAL_VALUE_PROBABILITY;
1752 value_mutation_distribution.push_back(temp);
1754 fuzzer_havoc_settings.value_mutation_distribution = value_mutation_distribution;
1765 RunWithBuilders<CycleGroupBase, FuzzerCircuitTypes>(Data, Size,
VarianceRNG);
1769#pragma clang diagnostic pop
static constexpr size_t CONSTANT_WITNESS
static constexpr size_t ADD
static constexpr size_t CONSTANT
static constexpr size_t MULTIPLY
static constexpr size_t COND_ASSIGN
static constexpr size_t ASSERT_EQUAL
static constexpr size_t RANDOMSEED
static constexpr size_t DBL
static constexpr size_t BATCH_MUL
static constexpr size_t SET
static constexpr size_t WITNESS
static constexpr size_t NEG
static constexpr size_t SUBTRACT
static constexpr size_t SET_INF
This class implements the execution of cycle group with an oracle to detect discrepancies.
static size_t execute_SET_INF(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SET_INF instruction.
ExecutionHandler operator-()
static size_t execute_SUBTRACT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the subtraction operator instruction.
static size_t execute_COND_ASSIGN(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the COND_ASSIGN instruction.
ExecutionHandler()=default
static size_t execute_DBL(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the DBL instruction.
ExecutionHandler(ScalarField s, GroupElement g, cycle_group_t w_g)
static bool_t construct_predicate(Builder *builder, const bool predicate)
ExecutionHandler set_inf(Builder *builder)
static size_t execute_NEG(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the NEG instruction.
static size_t execute_WITNESS(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the witness instruction (push witness cycle group to the stack)
static size_t execute_BATCH_MUL(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the BATCH_MUL instruction.
static size_t execute_RANDOMSEED(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the RANDOMSEED instruction.
static size_t execute_ASSERT_EQUAL(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the ASSERT_EQUAL instruction.
static size_t execute_SET(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the SET instruction.
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)
static size_t execute_ADD(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the addition operator instruction.
ExecutionHandler mul(Builder *builder, const ScalarField &multiplier)
static ExecutionHandler batch_mul(Builder *builder, const std::vector< ExecutionHandler > &to_add, const std::vector< ScalarField > &to_mul)
ExecutionHandler operator_sub(Builder *builder, const ExecutionHandler &other)
static size_t execute_MULTIPLY(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the multiply instruction.
void assert_equal(Builder *builder, ExecutionHandler &other)
cycle_group_t cycle_group
static size_t execute_CONSTANT(Builder *builder, std::vector< ExecutionHandler > &stack, Instruction &instruction)
Execute the constant instruction (push constant cycle group to the stack)
ExecutionHandler operator_add(Builder *builder, const ExecutionHandler &other)
ExecutionHandler conditional_assign(Builder *builder, ExecutionHandler &other, const bool predicate)
ExecutionHandler set(Builder *builder)
ArgumentContents arguments
static Instruction generateRandom(T &rng)
Generates a random instruction.
static Instruction mutateInstruction(Instruction instruction, T &rng, HavocSettings &havoc_config)
Mutate a single instruction.
static ScalarField mutateScalarElement(ScalarField e, T &rng, HavocSettings &havoc_config)
Mutate the value of a scalar element.
static Element mutateGroupElement(Element e, T &rng, HavocSettings &havoc_config)
Mutate the value of a group element.
Optional subclass that governs limits on the use of certain instructions, since some of them can be t...
static constexpr size_t RANDOMSEED
static constexpr size_t SET
static constexpr size_t BATCH_MUL
static constexpr size_t COND_ASSIGN
static constexpr size_t WITNESS
static constexpr size_t DBL
static constexpr size_t _LIMIT
static constexpr size_t SUBTRACT
static constexpr size_t ASSERT_EQUAL
static constexpr size_t CONSTANT_WITNESS
static constexpr size_t CONSTANT
static constexpr size_t SET_INF
static constexpr size_t MULTIPLY
static constexpr size_t NEG
static constexpr size_t ADD
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 CycleGroup fuzzing instructions, execution, etc.
typename bb::stdlib::witness_t< Builder > witness_t
typename bb::stdlib::cycle_group< Builder >::Curve Curve
typename bb::stdlib::public_witness_t< Builder > public_witness_t
typename bb::stdlib::cycle_group< Builder > cycle_group_t
typename bb::stdlib::field_t< Builder > field_t
static bool postProcess(Builder *builder, std::vector< CycleGroupBase::ExecutionHandler > &stack)
Check that the resulting values are equal to expected.
std::vector< ExecutionHandler > ExecutionState
typename bb::stdlib::bool_t< Builder > bool_t
typename cycle_group_t::cycle_scalar cycle_scalar_t
typename Curve::Element GroupElement
typename Curve::AffineElement AffineElement
typename Curve::ScalarField ScalarField
typename Curve::BaseField BaseField
Class for quickly deterministically creating new random values. We don't care about distribution much...
void reseed(uint32_t seed)
typename Group::element Element
typename Group::affine_element AffineElement
Implements boolean logic in-circuit.
cycle_group represents a group Element of the proving system's embedded curve i.e....
static cycle_group from_constant_witness(Builder *_context, const AffineElement &_in)
Converts a native AffineElement into a witness, but constrains the witness values to be known constan...
typename Builder::EmbeddedCurve Curve
static cycle_group conditional_assign(const bool_t &predicate, const cycle_group &lhs, const cycle_group &rhs)
static cycle_group from_witness(Builder *_context, const AffineElement &_in)
Converts an AffineElement into a circuit witness.
::bb::stdlib::cycle_scalar< Builder > cycle_scalar
static cycle_group batch_mul(const std::vector< cycle_group > &base_points, const std::vector< BigScalarField > &scalars, GeneratorContext context={})
Concept for a simple PRNG which returns a uint32_t when next is called.
#define INV_MONT_CONVERSION_SCALAR
constexpr size_t MINIMUM_MUL_ELEMENTS
constexpr size_t MAXIMUM_MUL_ELEMENTS
#define INV_MONT_CONVERSION
size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize)
FastRandom VarianceRNG(0)
int LLVMFuzzerInitialize(int *argc, char ***argv)
#define MONT_CONVERSION_SCALAR
size_t LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
Fuzzer entry function.
#define PUT_RANDOM_BYTE_IF_LUCKY(variable)
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]
ScalarField scalars[MAXIMUM_MUL_ELEMENTS]
uint8_t add_elements_count
Element(ScalarField s=ScalarField::one(), GroupElement g=GroupElement::one())
size_t GEN_LLVM_POST_MUTATION_PROB