Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
instruction.cpp
Go to the documentation of this file.
2
13#include <optional>
14
19
21{
23 auto index = generate_random_uint32(rng);
27 return VariableRef{ .tag = tag,
28 .index = index,
29 .pointer_address_seed = pointer_address,
30 .base_offset_seed = base_offset,
31 .mode = mode };
32}
33
34// Maximum operand values based on instruction operand size
35constexpr uint32_t MAX_8BIT_OPERAND = 255;
36constexpr uint32_t MAX_16BIT_OPERAND = 65535;
37
38AddressRef generate_address_ref(std::mt19937_64& rng, uint32_t max_operand_value)
39{
44 // For Direct mode, constrain address to fit in the operand
46 address = address % (max_operand_value + 1);
47 }
48 return AddressRef{
49 .address = address, .pointer_address_seed = pointer_address, .base_offset_seed = base_offset, .mode = mode
50 };
51}
52
54{
55 // 80% chance to use backfill (4 out of 5) to increase success rate
56 bool use_backfill = std::uniform_int_distribution<int>(0, 4)(rng) != 0;
57
58 if (!use_backfill) {
59 // Random mode: use existing memory values (may fail if not valid points on curve)
61 .p1_y = generate_variable_ref(rng),
62 .p1_infinite = generate_variable_ref(rng),
63 .p2_x = generate_variable_ref(rng),
64 .p2_y = generate_variable_ref(rng),
65 .p2_infinite = generate_variable_ref(rng),
66 .result = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
67 }
68
69 // Backfill mode: generate valid points on the Grumpkin curve and SET them
70 // 6 SET instructions (2 points * 3 fields each) + 1 ECADD = 7 instructions
72 instructions.reserve(7);
73
74 // Generate a valid point via scalar multiplication of the generator (always on curve)
75 auto generate_point = [&rng]() {
77 return bb::avm2::EmbeddedCurvePoint::one() * scalar;
78 };
79
80 // Generate SET instructions to backfill a point at the given addresses
81 auto backfill_point = [&instructions](const bb::avm2::EmbeddedCurvePoint& point,
82 AddressRef x_addr,
83 AddressRef y_addr,
84 AddressRef inf_addr) {
85 instructions.push_back(
86 SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF, .result_address = x_addr, .value = point.x() });
87 instructions.push_back(
88 SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF, .result_address = y_addr, .value = point.y() });
89 instructions.push_back(SET_8_Instruction{ .value_tag = bb::avm2::MemoryTag::U1,
90 .result_address = inf_addr,
91 .value = static_cast<uint8_t>(point.is_infinity() ? 1 : 0) });
92 };
93
94 auto p1 = generate_point();
95 auto p2 = generate_point();
96
97 // Generate addresses (SET_FF uses 16-bit, SET_8 uses 8-bit operands)
104
105 backfill_point(p1, p1_x_addr, p1_y_addr, p1_inf_addr);
106 backfill_point(p2, p2_x_addr, p2_y_addr, p2_inf_addr);
107
108 instructions.push_back(ECADD_Instruction{ .p1_x = p1_x_addr,
109 .p1_y = p1_y_addr,
110 .p1_infinite = p1_inf_addr,
111 .p2_x = p2_x_addr,
112 .p2_y = p2_y_addr,
113 .p2_infinite = p2_inf_addr,
114 .result = generate_address_ref(rng, MAX_16BIT_OPERAND) });
115
116 return instructions;
117}
118
119// Helper to generate a SET instruction for a given tag at a given address
121{
122 switch (tag) {
123 // We use set 16 for u1 and u8 because using set_8 will limit the address range to 255.
125 return SET_16_Instruction{ .value_tag = tag, .result_address = addr, .value = static_cast<uint8_t>(rng() & 1) };
127 return SET_16_Instruction{ .value_tag = tag, .result_address = addr, .value = generate_random_uint8(rng) };
129 return SET_16_Instruction{ .value_tag = tag, .result_address = addr, .value = generate_random_uint16(rng) };
131 return SET_32_Instruction{ .value_tag = tag, .result_address = addr, .value = generate_random_uint32(rng) };
133 return SET_64_Instruction{ .value_tag = tag, .result_address = addr, .value = generate_random_uint64(rng) };
136 .result_address = addr,
137 .value_low = generate_random_uint64(rng),
138 .value_high = generate_random_uint64(rng) };
140 default:
141 return SET_FF_Instruction{ .value_tag = tag, .result_address = addr, .value = generate_random_field(rng) };
142 }
143}
144
145// Generate binary ALU instruction with optional backfill for matching tagged operands
146template <typename InstructionType>
148{
149 // 80% chance to use backfill (4 out of 5) to increase success rate
150 bool use_backfill = std::uniform_int_distribution<int>(0, 4)(rng) != 0;
151
152 if (!use_backfill) {
153 return { InstructionType{ .a_address = generate_variable_ref(rng),
154 .b_address = generate_variable_ref(rng),
155 .result_address = generate_address_ref(rng, max_operand) } };
156 }
157
159 AddressRef a_addr = generate_address_ref(rng, max_operand);
160 AddressRef b_addr = generate_address_ref(rng, max_operand);
161
162 std::vector<FuzzInstruction> instructions;
163 instructions.push_back(generate_set_for_tag(tag, a_addr, rng));
164 instructions.push_back(generate_set_for_tag(tag, b_addr, rng));
165 instructions.push_back(InstructionType{
166 .a_address = a_addr, .b_address = b_addr, .result_address = generate_address_ref(rng, max_operand) });
167 return instructions;
168}
169
170// Generate binary ALU instruction with optional backfill for matching non-FF tagged operands
171// Used for bitwise operations (AND, OR, XOR) and integer DIV which don't support FF
172template <typename InstructionType>
174{
175 // 80% chance to use backfill (4 out of 5) to increase success rate
176 bool use_backfill = std::uniform_int_distribution<int>(0, 4)(rng) != 0;
177
178 if (!use_backfill) {
179 return { InstructionType{ .a_address = generate_variable_ref(rng),
180 .b_address = generate_variable_ref(rng),
181 .result_address = generate_address_ref(rng, max_operand) } };
182 }
183
184 // Pick a random non-FF tag (U1, U8, U16, U32, U64, U128)
185 static constexpr std::array<bb::avm2::MemoryTag, 6> int_tags = {
188 };
189 auto tag = int_tags[std::uniform_int_distribution<size_t>(0, int_tags.size() - 1)(rng)];
190
191 AddressRef a_addr = generate_address_ref(rng, max_operand);
192 AddressRef b_addr = generate_address_ref(rng, max_operand);
193
194 std::vector<FuzzInstruction> instructions;
195 instructions.push_back(generate_set_for_tag(tag, a_addr, rng));
196 instructions.push_back(generate_set_for_tag(tag, b_addr, rng));
197 instructions.push_back(InstructionType{
198 .a_address = a_addr, .b_address = b_addr, .result_address = generate_address_ref(rng, max_operand) });
199 return instructions;
200}
201
203{
204 // 80% chance to use backfill (4 out of 5) to increase success rate
205 bool use_backfill = std::uniform_int_distribution<int>(0, 4)(rng) != 0;
206
207 if (!use_backfill) {
208 // Random mode: use existing memory values
210 .b_address = generate_variable_ref(rng),
211 .result_address = generate_address_ref(rng, max_operand) } };
212 }
213
214 // Backfill mode: generate two non-zero FF values
215 std::vector<FuzzInstruction> instructions;
216 instructions.reserve(3);
217
218 // Generate non-zero field values (avoid division by zero)
219 auto generate_nonzero_field = [&rng]() {
221 do {
223 } while (value.is_zero());
224 return value;
225 };
226
227 AddressRef a_addr = generate_address_ref(rng, max_operand);
228 AddressRef b_addr = generate_address_ref(rng, max_operand);
229
230 // SET the dividend (a)
231 instructions.push_back(SET_FF_Instruction{
232 .value_tag = bb::avm2::MemoryTag::FF, .result_address = a_addr, .value = generate_nonzero_field() });
233
234 // SET the divisor (b) - must be non-zero
235 instructions.push_back(SET_FF_Instruction{
236 .value_tag = bb::avm2::MemoryTag::FF, .result_address = b_addr, .value = generate_nonzero_field() });
237
238 // FDIV instruction
239 instructions.push_back(FDIV_8_Instruction{
240 .a_address = a_addr, .b_address = b_addr, .result_address = generate_address_ref(rng, max_operand) });
241
242 return instructions;
243}
244
246{
247 // 80% chance to use backfill (4 out of 5) to increase success rate
248 bool use_backfill = std::uniform_int_distribution<int>(0, 4)(rng) != 0;
249 if (!use_backfill) {
250 // Random mode
252 .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
253 }
254 // Backfill mode
255 std::vector<FuzzInstruction> instructions;
256
257 // Keccak needs to backfill 25 U64 values, these need be contiguous in memory
259 for (size_t i = 0; i < 25; i++) {
260 AddressRef item_address = src_address;
261 item_address.address += static_cast<uint32_t>(i);
262 instructions.push_back(SET_64_Instruction{ .value_tag = bb::avm2::MemoryTag::U64,
263 .result_address = item_address,
264 .value = generate_random_uint64(rng) });
265 }
266 instructions.push_back(KECCAKF1600_Instruction{ .src_address = src_address,
267 .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND) });
268 return instructions;
269}
270
272{
273 // 80% chance to use backfill (4 out of 5) to increase success rate
274 bool use_backfill = std::uniform_int_distribution<int>(0, 4)(rng) != 0;
275 if (!use_backfill) {
276 // Random mode
278 .input_address = generate_variable_ref(rng),
279 .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
280 }
281 // Backfill mode
282 // SHA256 compression needs 8 U32 values for state and 16 U32 values for input (contiguous)
283 std::vector<FuzzInstruction> instructions;
284 instructions.reserve(8 + 16 + 1);
285
286 // Generate state address (8 contiguous U32 values)
287 AddressRef state_address = generate_address_ref(rng, MAX_16BIT_OPERAND - 7);
288
289 for (size_t i = 0; i < 8; i++) {
290 AddressRef item_address = state_address;
291 item_address.address += static_cast<uint32_t>(i);
292 instructions.push_back(SET_32_Instruction{ .value_tag = bb::avm2::MemoryTag::U32,
293 .result_address = item_address,
294 .value = generate_random_uint32(rng) });
295 }
296
297 // Generate input address (16 contiguous U32 values)
298 AddressRef input_address = generate_address_ref(rng, MAX_16BIT_OPERAND - 15);
299
300 for (size_t i = 0; i < 16; i++) {
301 AddressRef item_address = input_address;
302 item_address.address += static_cast<uint32_t>(i);
303 instructions.push_back(SET_32_Instruction{ .value_tag = bb::avm2::MemoryTag::U32,
304 .result_address = item_address,
305 .value = generate_random_uint32(rng) });
306 }
307
308 instructions.push_back(
310 .input_address = input_address,
311 .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND) });
312 return instructions;
313}
314
316{
317 // 80% chance to use backfill (4 out of 5) to increase success rate
318 bool use_backfill = std::uniform_int_distribution<int>(0, 4)(rng) != 0;
319 if (!use_backfill) {
320 // Random mode
322 .radix_address = generate_variable_ref(rng),
323 .num_limbs_address = generate_variable_ref(rng),
324 .output_bits_address = generate_variable_ref(rng),
325 .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
326 .is_output_bits = std::uniform_int_distribution<int>(0, 1)(rng) == 0 } };
327 }
328 // Backfill mode: set up proper typed values
329 // value: FF, radix: U32, num_limbs: U32, output_bits: U1
330 std::vector<FuzzInstruction> instructions;
331 instructions.reserve(5);
332
336 AddressRef output_bits_addr = generate_address_ref(rng, MAX_8BIT_OPERAND);
337
338 // SET the radix (U32) - pick radix between 2 and 256
339 uint32_t radix = std::uniform_int_distribution<uint32_t>(2, 256)(rng);
340 instructions.push_back(
341 SET_32_Instruction{ .value_tag = bb::avm2::MemoryTag::U32, .result_address = radix_addr, .value = radix });
342
343 // SET the output_bits (U1)
344 bool is_output_bits = radix == 2;
345 instructions.push_back(SET_8_Instruction{ .value_tag = bb::avm2::MemoryTag::U1,
346 .result_address = output_bits_addr,
347 .value = static_cast<uint8_t>(is_output_bits ? 1 : 0) });
348
349 // Generate value with num_limbs digits
350 uint32_t num_limbs = std::uniform_int_distribution<uint32_t>(1, 256)(rng);
352 bb::avm2::FF exponent = 1;
353 for (uint32_t i = 0; i < num_limbs; i++) {
354 uint32_t digit = std::uniform_int_distribution<uint32_t>(0, radix - 1)(rng);
355 value += bb::avm2::FF(digit) * exponent;
356 exponent *= radix;
357 }
358
359 // 20% chance to truncate - reduce the number of limbs we request
360 if (std::uniform_int_distribution<int>(0, 4)(rng) == 0) {
361 num_limbs--;
362 }
363
364 // SET the num_limbs (U32)
365 instructions.push_back(SET_32_Instruction{
366 .value_tag = bb::avm2::MemoryTag::U32, .result_address = num_limbs_addr, .value = num_limbs });
367
368 // SET the value (FF)
369 instructions.push_back(
370 SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF, .result_address = value_addr, .value = value });
371
372 // TORADIXBE instruction
373 instructions.push_back(TORADIXBE_Instruction{ .value_address = value_addr,
374 .radix_address = radix_addr,
375 .num_limbs_address = num_limbs_addr,
376 .output_bits_address = output_bits_addr,
377 .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
378 .is_output_bits = is_output_bits });
379 return instructions;
380}
381
382// A better way in the future is to pass in a vector of possible slots that have been written to,
383// this would allow us to supply external world state info.
385{
386 // 80% chance to use backfill (4 out of 5) to increase success rate
387 bool use_backfill = std::uniform_int_distribution<int>(0, 4)(rng) != 0;
388
389 if (!use_backfill) {
390 // Random mode: requires at least one prior SSTORE to have been processed
392 .slot_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
393 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
394 }
395
396 // Backfill mode: generate SSTORE first to ensure storage_addresses is non-empty
397 // This guarantees SLOAD will find a valid slot (get_slot uses modulo on non-empty vector)
398 std::vector<FuzzInstruction> instructions;
399 instructions.reserve(3);
400
402
403 // SET a value to store
404 instructions.push_back(SET_FF_Instruction{
405 .value_tag = bb::avm2::MemoryTag::FF, .result_address = sstore_src, .value = generate_random_field(rng) });
406
407 // SSTORE - appends to storage_addresses in memory_manager
408 instructions.push_back(SSTORE_Instruction{ .src_address = sstore_src,
409 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
410 .slot = generate_random_field(rng) });
411
412 // SLOAD - now guaranteed to succeed (storage_addresses not empty, get_slot uses modulo)
413 instructions.push_back(SLOAD_Instruction{ .slot_index = generate_random_uint16(rng),
414 .slot_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
415 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) });
416
417 return instructions;
418}
419
421{
422 // 80% chance to use backfill (4 out of 5) to increase success rate
423 bool use_backfill = std::uniform_int_distribution<int>(0, 4)(rng) != 0;
424
425 if (!use_backfill) {
427 .log_values_address = generate_variable_ref(rng) } };
428 }
429
431 std::vector<FuzzInstruction> instructions;
432 instructions.reserve(3);
433
436
437 instructions.push_back(SET_32_Instruction{
438 .value_tag = bb::avm2::MemoryTag::U32, .result_address = log_size_address, .value = log_size });
439
440 // Write one random FF in the log
441 instructions.push_back(SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF,
442 .result_address = log_values_address,
443 .value = generate_random_field(rng) });
444
446 .log_values_address = log_values_address });
447
448 return instructions;
449}
450
453{
454 // 80% chance to use backfill (4 out of 5) to increase success rate
455 bool use_backfill = std::uniform_int_distribution<int>(0, 4)(rng) != 0;
456
457 if (!use_backfill) {
458
460 .da_gas_address = generate_variable_ref(rng),
461 .contract_address_address = generate_variable_ref(rng),
462 .calldata_address = generate_variable_ref(rng),
463 .calldata_size_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
464 .calldata_size = generate_random_uint16(rng),
465 .is_static_call = rng() % 2 == 0 } };
466 }
467
468 std::vector<FuzzInstruction> instructions;
469 instructions.reserve(5);
470
472 instructions.push_back(SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF,
473 .result_address = contract_address_address,
474 .value = context.get_contract_address(generate_random_uint16(rng)) });
475
477 instructions.push_back(SET_32_Instruction{ .value_tag = bb::avm2::MemoryTag::U32,
478 .result_address = l2_gas_address,
479 .value = generate_random_uint32(rng) });
480
482 instructions.push_back(SET_32_Instruction{ .value_tag = bb::avm2::MemoryTag::U32,
483 .result_address = da_gas_address,
484 .value = generate_random_uint32(rng) });
485
488
490 // Write one random FF in the calldata
491 instructions.push_back(SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF,
492 .result_address = calldata_address,
493 .value = generate_random_field(rng) });
494
495 instructions.push_back(CALL_Instruction{ .l2_gas_address = l2_gas_address,
496 .da_gas_address = da_gas_address,
497 .contract_address_address = contract_address_address,
498 .calldata_address = calldata_address,
499 .calldata_size_address = calldata_size_address,
500 .calldata_size = calldata_size,
501 .is_static_call = rng() % 2 == 0 });
502
503 return instructions;
504}
505
508{
509 bool use_backfill = std::uniform_int_distribution<int>(0, 4)(rng) != 0;
510 if (!use_backfill) {
513 .member_enum = generate_random_uint8(rng),
514 .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
515 } };
516 }
517
518 std::vector<FuzzInstruction> instructions;
519 instructions.reserve(2);
520
522 instructions.push_back(SET_FF_Instruction{ .value_tag = bb::avm2::MemoryTag::FF,
523 .result_address = contract_address_address,
524 .value = context.get_contract_address(generate_random_uint16(rng)) });
526
527 instructions.push_back(GETCONTRACTINSTANCE_Instruction{
529 .member_enum = member_enum,
530 .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
531 });
532
533 return instructions;
534}
535
536namespace bb::avm2::fuzzer {
538{
540 // forgive me
541 switch (option) {
543 return generate_alu_with_matching_tags<ADD_8_Instruction>(rng, MAX_8BIT_OPERAND);
545 return generate_alu_with_matching_tags<SUB_8_Instruction>(rng, MAX_8BIT_OPERAND);
547 return generate_alu_with_matching_tags<MUL_8_Instruction>(rng, MAX_8BIT_OPERAND);
549 return generate_alu_with_matching_tags_not_ff<DIV_8_Instruction>(rng, MAX_8BIT_OPERAND);
554 .b_address = generate_variable_ref(rng),
555 .result_address = generate_address_ref(rng, MAX_8BIT_OPERAND) } };
558 .b_address = generate_variable_ref(rng),
559 .result_address = generate_address_ref(rng, MAX_8BIT_OPERAND) } };
562 .b_address = generate_variable_ref(rng),
563 .result_address = generate_address_ref(rng, MAX_8BIT_OPERAND) } };
565 return generate_alu_with_matching_tags_not_ff<AND_8_Instruction>(rng, MAX_8BIT_OPERAND);
567 return generate_alu_with_matching_tags_not_ff<OR_8_Instruction>(rng, MAX_8BIT_OPERAND);
569 return generate_alu_with_matching_tags_not_ff<XOR_8_Instruction>(rng, MAX_8BIT_OPERAND);
572 .result_address = generate_address_ref(rng, MAX_8BIT_OPERAND) } };
575 .b_address = generate_variable_ref(rng),
576 .result_address = generate_address_ref(rng, MAX_8BIT_OPERAND) } };
577
580 .b_address = generate_variable_ref(rng),
581 .result_address = generate_address_ref(rng, MAX_8BIT_OPERAND) } };
584 .result_address = generate_address_ref(rng, MAX_8BIT_OPERAND),
585 .value = generate_random_uint8(rng) } };
588 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
589 .value = generate_random_uint16(rng) } };
592 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
593 .value = generate_random_uint32(rng) } };
596 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
597 .value = generate_random_uint64(rng) } };
600 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
601 .value_low = generate_random_uint64(rng),
602 .value_high = generate_random_uint64(rng) } };
605 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
606 .value = generate_random_field(rng) } };
609 .src_address = generate_variable_ref(rng),
610 .result_address = generate_address_ref(rng, MAX_8BIT_OPERAND) } };
613 .src_address = generate_variable_ref(rng),
614 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
616 return generate_alu_with_matching_tags<ADD_16_Instruction>(rng, MAX_16BIT_OPERAND);
618 return generate_alu_with_matching_tags<SUB_16_Instruction>(rng, MAX_16BIT_OPERAND);
620 return generate_alu_with_matching_tags<MUL_16_Instruction>(rng, MAX_16BIT_OPERAND);
622 return generate_alu_with_matching_tags_not_ff<DIV_16_Instruction>(rng, MAX_16BIT_OPERAND);
625 .b_address = generate_variable_ref(rng),
626 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
629 .b_address = generate_variable_ref(rng),
630 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
633 .b_address = generate_variable_ref(rng),
634 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
637 .b_address = generate_variable_ref(rng),
638 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
640 return generate_alu_with_matching_tags_not_ff<AND_16_Instruction>(rng, MAX_16BIT_OPERAND);
642 return generate_alu_with_matching_tags_not_ff<OR_16_Instruction>(rng, MAX_16BIT_OPERAND);
644 return generate_alu_with_matching_tags_not_ff<XOR_16_Instruction>(rng, MAX_16BIT_OPERAND);
647 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
650 .b_address = generate_variable_ref(rng),
651 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
654 .b_address = generate_variable_ref(rng),
655 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
658 .result_address = generate_address_ref(rng, MAX_8BIT_OPERAND),
659 .target_tag =
663 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
664 .target_tag =
668 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
669 .slot = generate_random_field(rng) } };
671 return generate_sload_instruction(rng);
674 .type = generate_random_uint8(rng) } };
679 .contract_address_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
680 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
683 .leaf_index_address = generate_variable_ref(rng),
684 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
687 .note_hash = generate_random_field(rng) } };
690 .notehash_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
691 .leaf_index_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
692 .result_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
695 .copy_size = generate_random_uint8(rng),
696 .copy_size_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
697 .cd_start = generate_random_uint16(rng),
698 .cd_start_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
701 .recipient_address = generate_address_ref(rng, MAX_16BIT_OPERAND),
702 .content = generate_random_field(rng),
703 .content_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
710 .dst_address = generate_random_uint16(rng),
711 .rd_start_offset = generate_random_uint16(rng) } };
717 return generate_ecadd_instruction(rng);
720 .dst_address = generate_address_ref(rng, MAX_16BIT_OPERAND) } };
727 }
728}
755
756void mutate_address_ref(AddressRef& address, std::mt19937_64& rng, uint32_t max_operand_value)
757{
759 switch (option) {
762 // Constrain address for Direct mode
763 if (address.mode == AddressingMode::Direct) {
764 address.address = address.address % (max_operand_value + 1);
765 }
766 break;
769 break;
772 break;
775 // Constrain address if mode changed to Direct
776 if (address.mode == AddressingMode::Direct) {
777 address.address = address.address % (max_operand_value + 1);
778 }
779 break;
780 }
781}
782
784 std::mt19937_64& rng,
785 std::optional<MemoryTag> default_tag,
786 uint32_t max_operand_value)
787{
788 std::visit(overloaded{ [&](VariableRef& var) { mutate_variable_ref(var, rng, default_tag); },
789 [&](AddressRef& addr) { mutate_address_ref(addr, rng, max_operand_value); } },
790 param);
791}
792
794{
795 return std::visit(overloaded{ [](const VariableRef& var) -> std::optional<MemoryTag> { return var.tag.value; },
796 [](const AddressRef&) -> std::optional<MemoryTag> { return std::nullopt; } },
797 param);
798}
799
800template <typename BinaryInstructionType>
816
817template <typename BinaryInstructionType>
833
846
862
878
894
910
929
945
947{
948 int choice = std::uniform_int_distribution<int>(0, 2)(rng);
949 switch (choice) {
950 case 0:
952 break;
953 case 1:
955 break;
956 case 2:
957 mutate_address_ref(instruction.result_address, rng, MAX_8BIT_OPERAND);
958 break;
959 }
960}
961
963{
964 int choice = std::uniform_int_distribution<int>(0, 2)(rng);
965 switch (choice) {
966 case 0:
968 break;
969 case 1:
971 break;
972 case 2:
974 break;
975 }
976}
977
990
1006
1022
1038
1054
1067
1069{
1070 // emitnulifier only has one field
1071
1073}
1074
1090
1106
1137
1159
1178
1191
1193{
1195 switch (option) {
1198 break;
1201 break;
1203 mutate_param_ref(instruction.contract_address_address, rng, MemoryTag::FF, MAX_16BIT_OPERAND);
1204 break;
1206 mutate_address_ref(instruction.calldata_size_address, rng, MAX_16BIT_OPERAND);
1207 break;
1210 break;
1213 break;
1215 // with 0.5 probability, set to true, otherwise false
1216 instruction.is_static_call = rng() % 2 == 0;
1217 }
1218}
1219
1237
1253
1263
1265{
1266 // ECADD has 7 operands, select one to mutate
1267 int choice = std::uniform_int_distribution<int>(0, 6)(rng);
1268 switch (choice) {
1269 case 0:
1271 break;
1272 case 1:
1274 break;
1275 case 2:
1277 break;
1278 case 3:
1280 break;
1281 case 4:
1283 break;
1284 case 5:
1286 break;
1287 case 6:
1289 break;
1290 }
1291}
1292
1294{
1295 int choice = std::uniform_int_distribution<int>(0, 1)(rng);
1296 switch (choice) {
1297 case 0:
1299 break;
1300 case 1:
1302 break;
1303 }
1304}
1305
1307{
1308 int choice = std::uniform_int_distribution<int>(0, 1)(rng);
1309 switch (choice) {
1310 case 0:
1312 break;
1313 case 1:
1315 break;
1316 }
1317}
1318
1320{
1321 int choice = std::uniform_int_distribution<int>(0, 2)(rng);
1322 switch (choice) {
1323 case 0:
1325 break;
1326 case 1:
1328 break;
1329 case 2:
1331 break;
1332 }
1333}
1334
1359
1361 std::mt19937_64& rng,
1362 [[maybe_unused]] const FuzzerContext& context)
1363{
1364 std::visit(
1365 overloaded{
1366 [&rng](ADD_8_Instruction& instr) { mutate_binary_instruction_8(instr, rng); },
1367 [&rng](SUB_8_Instruction& instr) { mutate_binary_instruction_8(instr, rng); },
1368 [&rng](MUL_8_Instruction& instr) { mutate_binary_instruction_8(instr, rng); },
1369 [&rng](DIV_8_Instruction& instr) { mutate_binary_instruction_8(instr, rng); },
1370 [&rng](EQ_8_Instruction& instr) { mutate_binary_instruction_8(instr, rng); },
1371 [&rng](LT_8_Instruction& instr) { mutate_binary_instruction_8(instr, rng); },
1372 [&rng](LTE_8_Instruction& instr) { mutate_binary_instruction_8(instr, rng); },
1373 [&rng](AND_8_Instruction& instr) { mutate_binary_instruction_8(instr, rng); },
1374 [&rng](OR_8_Instruction& instr) { mutate_binary_instruction_8(instr, rng); },
1375 [&rng](XOR_8_Instruction& instr) { mutate_binary_instruction_8(instr, rng); },
1376 [&rng](SHL_8_Instruction& instr) { mutate_binary_instruction_8(instr, rng); },
1377 [&rng](SHR_8_Instruction& instr) { mutate_binary_instruction_8(instr, rng); },
1378 [&rng](SET_8_Instruction& instr) { mutate_set_8_instruction(instr, rng); },
1379 [&rng](SET_16_Instruction& instr) { mutate_set_16_instruction(instr, rng); },
1380 [&rng](SET_32_Instruction& instr) { mutate_set_32_instruction(instr, rng); },
1381 [&rng](SET_64_Instruction& instr) { mutate_set_64_instruction(instr, rng); },
1382 [&rng](SET_128_Instruction& instr) { mutate_set_128_instruction(instr, rng); },
1383 [&rng](SET_FF_Instruction& instr) { mutate_set_ff_instruction(instr, rng); },
1384 [&rng](MOV_8_Instruction& instr) { mutate_mov_8_instruction(instr, rng); },
1385 [&rng](MOV_16_Instruction& instr) { mutate_mov_16_instruction(instr, rng); },
1386 [&rng](FDIV_8_Instruction& instr) { mutate_binary_instruction_8(instr, rng); },
1387 [&rng](NOT_8_Instruction& instr) { mutate_not_8_instruction(instr, rng); },
1388 [&rng](ADD_16_Instruction& instr) { mutate_binary_instruction_16(instr, rng); },
1389 [&rng](SUB_16_Instruction& instr) { mutate_binary_instruction_16(instr, rng); },
1390 [&rng](MUL_16_Instruction& instr) { mutate_binary_instruction_16(instr, rng); },
1391 [&rng](DIV_16_Instruction& instr) { mutate_binary_instruction_16(instr, rng); },
1392 [&rng](FDIV_16_Instruction& instr) { mutate_binary_instruction_16(instr, rng); },
1393 [&rng](EQ_16_Instruction& instr) { mutate_binary_instruction_16(instr, rng); },
1394 [&rng](LT_16_Instruction& instr) { mutate_binary_instruction_16(instr, rng); },
1395 [&rng](LTE_16_Instruction& instr) { mutate_binary_instruction_16(instr, rng); },
1396 [&rng](AND_16_Instruction& instr) { mutate_binary_instruction_16(instr, rng); },
1397 [&rng](OR_16_Instruction& instr) { mutate_binary_instruction_16(instr, rng); },
1398 [&rng](XOR_16_Instruction& instr) { mutate_binary_instruction_16(instr, rng); },
1399 [&rng](NOT_16_Instruction& instr) { mutate_not_16_instruction(instr, rng); },
1400 [&rng](SHL_16_Instruction& instr) { mutate_binary_instruction_16(instr, rng); },
1401 [&rng](SHR_16_Instruction& instr) { mutate_binary_instruction_16(instr, rng); },
1402 [&rng](CAST_8_Instruction& instr) { mutate_cast_8_instruction(instr, rng); },
1403 [&rng](CAST_16_Instruction& instr) { mutate_cast_16_instruction(instr, rng); },
1404 [&rng](SSTORE_Instruction& instr) { mutate_sstore_instruction(instr, rng); },
1405 [&rng](SLOAD_Instruction& instr) { mutate_sload_instruction(instr, rng); },
1406 [&rng](GETENVVAR_Instruction& instr) { mutate_getenvvar_instruction(instr, rng); },
1407 [&rng](EMITNULLIFIER_Instruction& instr) { mutate_emit_nullifier_instruction(instr, rng); },
1410 [&rng](EMITNOTEHASH_Instruction& instr) { mutate_emit_note_hash_instruction(instr, rng); },
1412 [&rng](CALLDATACOPY_Instruction& instr) { mutate_calldatacopy_instruction(instr, rng); },
1413 [&rng](SENDL2TOL1MSG_Instruction& instr) { mutate_sendl2tol1msg_instruction(instr, rng); },
1415 [&rng](CALL_Instruction& instr) { mutate_call_instruction(instr, rng); },
1418 },
1420 [&rng](SUCCESSCOPY_Instruction& instr) { mutate_successcopy_instruction(instr, rng); },
1421 [&rng](ECADD_Instruction& instr) { mutate_ecadd_instruction(instr, rng); },
1422 [&rng](POSEIDON2PERM_Instruction& instr) { mutate_poseidon2perm_instruction(instr, rng); },
1423 [&rng](KECCAKF1600_Instruction& instr) { mutate_keccakf1600_instruction(instr, rng); },
1425 [&rng](TORADIXBE_Instruction& instr) { mutate_toradixbe_instruction(instr, rng); },
1426 [](auto&) { throw std::runtime_error("Unknown instruction"); } },
1427 instruction);
1428}
1429
1430} // namespace bb::avm2::fuzzer
::FuzzInstruction FuzzInstruction
FF generate_random_field(std::mt19937_64 &rng)
Definition field.cpp:23
void mutate_field(bb::avm2::FF &value, std::mt19937_64 &rng, const FieldMutationConfig &config)
Definition field.cpp:54
#define FLAT_PUBLIC_LOGS_PAYLOAD_LENGTH
T select(std::mt19937_64 &rng) const
constexpr bool is_infinity() const noexcept
constexpr const BaseField & x() const noexcept
constexpr const BaseField & y() const noexcept
Set32MutationOptions
constexpr Set128MutationConfig BASIC_SET_128_MUTATION_CONFIGURATION
constexpr AddressRefMutationConfig BASIC_ADDRESS_REF_MUTATION_CONFIGURATION
Set64MutationOptions
constexpr SLoadMutationConfig BASIC_SLOAD_MUTATION_CONFIGURATION
constexpr GetEnvVarMutationConfig BASIC_GETENVVAR_MUTATION_CONFIGURATION
constexpr Set16MutationConfig BASIC_SET_16_MUTATION_CONFIGURATION
L1ToL2MsgExistsMutationOptions
constexpr NoteHashExistsMutationConfig BASIC_NOTEHASHEXISTS_MUTATION_CONFIGURATION
NoteHashExistsMutationOptions
constexpr ToRadixBEMutationConfig BASIC_TORADIXBE_MUTATION_CONFIGURATION
constexpr Set64MutationConfig BASIC_SET_64_MUTATION_CONFIGURATION
EmitNoteHashMutationOptions
CallMutationOptions
SetFFMutationOptions
constexpr MemoryTagGenerationConfig BASIC_MEMORY_TAG_GENERATION_CONFIGURATION
constexpr ReturndatasizeWithReturndatacopyMutationConfig BASIC_RETURNDATASIZE_WITH_RETURNDATACOPY_MUTATION_CONFIGURATION
SuccessCopyMutationOptions
constexpr Uint64MutationConfig BASIC_UINT64_T_MUTATION_CONFIGURATION
Set8MutationOptions
Set16MutationOptions
constexpr CalldataCopyMutationConfig BASIC_CALLDATACOPY_MUTATION_CONFIGURATION
constexpr GetContractInstanceMutationConfig BASIC_GETCONTRACTINSTANCE_MUTATION_CONFIGURATION
InstructionGenerationOptions
constexpr L1ToL2MsgExistsMutationConfig BASIC_L1TOL2MSGEXISTS_MUTATION_CONFIGURATION
constexpr Uint32MutationConfig BASIC_UINT32_T_MUTATION_CONFIGURATION
constexpr UnaryInstruction8MutationConfig BASIC_UNARY_INSTRUCTION_8_MUTATION_CONFIGURATION
ReturndatasizeWithReturndatacopyMutationOptions
SStoreMutationOptions
constexpr SetFFMutationConfig BASIC_SET_FF_MUTATION_CONFIGURATION
constexpr Set32MutationConfig BASIC_SET_32_MUTATION_CONFIGURATION
constexpr FieldMutationConfig BASIC_FIELD_MUTATION_CONFIGURATION
UnaryInstruction8MutationOptions
constexpr BinaryInstruction8MutationConfig BASIC_BINARY_INSTRUCTION_8_MUTATION_CONFIGURATION
constexpr Uint16MutationConfig BASIC_UINT16_T_MUTATION_CONFIGURATION
constexpr SStoreMutationConfig BASIC_SSTORE_MUTATION_CONFIGURATION
CalldataCopyMutationOptions
EmitUnencryptedLogMutationOptions
constexpr NullifierExistsMutationConfig BASIC_NULLIFIER_EXISTS_MUTATION_CONFIGURATION
constexpr EmitUnencryptedLogMutationConfig BASIC_EMITUNENCRYPTEDLOG_MUTATION_CONFIGURATION
constexpr CallMutationConfig BASIC_CALL_MUTATION_CONFIGURATION
constexpr SendL2ToL1MsgMutationConfig BASIC_SENDL2TOL1MSG_MUTATION_CONFIGURATION
constexpr VariableRefMutationConfig BASIC_VARIABLE_REF_MUTATION_CONFIGURATION
Set128MutationOptions
constexpr EmitNoteHashMutationConfig BASIC_EMITNOTEHASH_MUTATION_CONFIGURATION
ToRadixBEMutationOptions
constexpr MemoryTagMutationConfig BASIC_MEMORY_TAG_MUTATION_CONFIGURATION
SLoadMutationOptions
constexpr Uint8MutationConfig BASIC_UINT8_T_MUTATION_CONFIGURATION
VariableRefMutationOptions
constexpr InstructionGenerationConfig BASIC_INSTRUCTION_GENERATION_CONFIGURATION
constexpr SuccessCopyMutationConfig BASIC_SUCCESSCOPY_MUTATION_CONFIGURATION
GetContractInstanceMutationOptions
GetEnvVarMutationOptions
AddressRefMutationOptions
BinaryInstruction8MutationOptions
SendL2ToL1MsgMutationOptions
constexpr Set8MutationConfig BASIC_SET_8_MUTATION_CONFIGURATION
NullifierExistsMutationOptions
StrictMock< MockContext > context
overloaded(Ts...) -> overloaded< Ts... >
AddressingMode
std::variant< VariableRef, AddressRef > ParamRef
Instruction instruction
std::vector< FuzzInstruction > generate_sha256compression_instruction(std::mt19937_64 &rng)
VariableRef generate_variable_ref(std::mt19937_64 &rng)
std::vector< FuzzInstruction > generate_call_instruction(std::mt19937_64 &rng, const bb::avm2::fuzzer::FuzzerContext &context)
std::vector< FuzzInstruction > generate_alu_with_matching_tags_not_ff(std::mt19937_64 &rng, uint32_t max_operand)
AddressingMode generate_addressing_mode(std::mt19937_64 &rng)
std::vector< FuzzInstruction > generate_alu_with_matching_tags(std::mt19937_64 &rng, uint32_t max_operand)
std::vector< FuzzInstruction > generate_sload_instruction(std::mt19937_64 &rng)
std::vector< FuzzInstruction > generate_ecadd_instruction(std::mt19937_64 &rng)
std::vector< FuzzInstruction > generate_keccakf_instruction(std::mt19937_64 &rng)
std::vector< FuzzInstruction > generate_toradixbe_instruction(std::mt19937_64 &rng)
std::vector< FuzzInstruction > generate_fdiv_instruction(std::mt19937_64 &rng, uint32_t max_operand)
constexpr uint32_t MAX_8BIT_OPERAND
FuzzInstruction generate_set_for_tag(bb::avm2::MemoryTag tag, AddressRef addr, std::mt19937_64 &rng)
constexpr uint32_t MAX_16BIT_OPERAND
std::vector< FuzzInstruction > generate_getcontractinstance_instruction(std::mt19937_64 &rng, const bb::avm2::fuzzer::FuzzerContext &context)
std::vector< FuzzInstruction > generate_emitunencryptedlog_instruction(std::mt19937_64 &rng)
AddressRef generate_address_ref(std::mt19937_64 &rng, uint32_t max_operand_value)
MemoryTag generate_memory_tag(std::mt19937_64 &rng, const MemoryTagGenerationConfig &config)
Definition memory_tag.cpp:8
void mutate_or_default_tag(MemoryTag &value, std::mt19937_64 &rng, MemoryTag default_tag, double probability=0.1)
Mutate the memory tag or set to the chosen tag with a given probability.
void mutate_memory_tag(MemoryTag &value, std::mt19937_64 &rng, const MemoryTagMutationConfig &config)
void mutate_variable_ref(VariableRef &variable, std::mt19937_64 &rng, std::optional< MemoryTag > default_tag)
Most of the tags will be equal to the default tag.
void mutate_l1tol2msgexists_instruction(L1TOL2MSGEXISTS_Instruction &instruction, std::mt19937_64 &rng)
void mutate_poseidon2perm_instruction(POSEIDON2PERM_Instruction &instruction, std::mt19937_64 &rng)
void mutate_keccakf1600_instruction(KECCAKF1600_Instruction &instruction, std::mt19937_64 &rng)
void mutate_not_16_instruction(NOT_16_Instruction &instruction, std::mt19937_64 &rng)
void mutate_call_instruction(CALL_Instruction &instruction, std::mt19937_64 &rng)
void mutate_cast_16_instruction(CAST_16_Instruction &instruction, std::mt19937_64 &rng)
void mutate_emit_note_hash_instruction(EMITNOTEHASH_Instruction &instruction, std::mt19937_64 &rng)
std::optional< MemoryTag > get_param_ref_tag(const ParamRef &param)
void mutate_nullifier_exists_instruction(NULLIFIEREXISTS_Instruction &instruction, std::mt19937_64 &rng)
void mutate_set_16_instruction(SET_16_Instruction &instruction, std::mt19937_64 &rng)
void mutate_instruction(FuzzInstruction &instruction, std::mt19937_64 &rng, const FuzzerContext &context)
void mutate_sload_instruction(SLOAD_Instruction &instruction, std::mt19937_64 &rng)
void mutate_sstore_instruction(SSTORE_Instruction &instruction, std::mt19937_64 &rng)
void mutate_calldatacopy_instruction(CALLDATACOPY_Instruction &instruction, std::mt19937_64 &rng)
void mutate_getenvvar_instruction(GETENVVAR_Instruction &instruction, std::mt19937_64 &rng)
void mutate_address_ref(AddressRef &address, std::mt19937_64 &rng, uint32_t max_operand_value)
void mutate_returndatasize_with_returndatacopy_instruction(RETURNDATASIZE_WITH_RETURNDATACOPY_Instruction &instruction, std::mt19937_64 &rng)
void mutate_ecadd_instruction(ECADD_Instruction &instruction, std::mt19937_64 &rng)
void mutate_set_32_instruction(SET_32_Instruction &instruction, std::mt19937_64 &rng)
void mutate_note_hash_exists_instruction(NOTEHASHEXISTS_Instruction &instruction, std::mt19937_64 &rng)
void mutate_set_128_instruction(SET_128_Instruction &instruction, std::mt19937_64 &rng)
void mutate_mov_8_instruction(MOV_8_Instruction &instruction, std::mt19937_64 &rng)
void mutate_emitunencryptedlog_instruction(EMITUNENCRYPTEDLOG_Instruction &instruction, std::mt19937_64 &rng)
void mutate_toradixbe_instruction(TORADIXBE_Instruction &instruction, std::mt19937_64 &rng)
void mutate_not_8_instruction(NOT_8_Instruction &instruction, std::mt19937_64 &rng)
void mutate_binary_instruction_8(BinaryInstructionType &instruction, std::mt19937_64 &rng)
void mutate_set_ff_instruction(SET_FF_Instruction &instruction, std::mt19937_64 &rng)
std::vector< FuzzInstruction > generate_instruction(std::mt19937_64 &rng, const FuzzerContext &context)
Generate one instruction and optionally backfill.
void mutate_set_64_instruction(SET_64_Instruction &instruction, std::mt19937_64 &rng)
void mutate_emit_nullifier_instruction(EMITNULLIFIER_Instruction &instruction, std::mt19937_64 &rng)
void mutate_getcontractinstance_instruction(GETCONTRACTINSTANCE_Instruction &instruction, std::mt19937_64 &rng)
void mutate_binary_instruction_16(BinaryInstructionType &instruction, std::mt19937_64 &rng)
void mutate_mov_16_instruction(MOV_16_Instruction &instruction, std::mt19937_64 &rng)
void mutate_sha256compression_instruction(SHA256COMPRESSION_Instruction &instruction, std::mt19937_64 &rng)
void mutate_set_8_instruction(SET_8_Instruction &instruction, std::mt19937_64 &rng)
void mutate_cast_8_instruction(CAST_8_Instruction &instruction, std::mt19937_64 &rng)
void mutate_successcopy_instruction(SUCCESSCOPY_Instruction &instruction, std::mt19937_64 &rng)
void mutate_sendl2tol1msg_instruction(SENDL2TOL1MSG_Instruction &instruction, std::mt19937_64 &rng)
void mutate_param_ref(ParamRef &param, std::mt19937_64 &rng, std::optional< MemoryTag > default_tag, uint32_t max_operand_value)
AvmFlavorSettings::G1::Fq Fq
Definition field.hpp:11
AvmFlavorSettings::FF FF
Definition field.hpp:10
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
mem[result_offset] = mem[a_address] + mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] + mem[b_address]
mem[result_offset] = mem[a_address] & mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] & mem[b_address]
uint32_t address
ParamRef l2_gas_address
CALLDATACOPY: M[dstOffset:dstOffset+M[copySizeOffset]] = calldata[M[cdStartOffset]:M[cdStartOffset]+M...
CAST_16: cast mem[src_offset_index] to target_tag and store at dst_offset.
CAST_8: cast mem[src_offset_index] to target_tag and store at dst_offset.
mem[result_offset] = mem[a_address] / mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] / mem[b_address]
EMITNOTEHASH: M[note_hash_offset] = note_hash; emit note hash to the note hash tree.
EMITNULIFIER: inserts new nullifier to the nullifier tree.
mem[result_offset] = mem[a_address] == mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] == mem[b_address]
GETENVVAR: M[result_offset] = getenvvar(type)
KECCAKF1600: Perform Keccak-f[1600] permutation on 25 U64 values M[dst_address:dst_address+25] = kecc...
L1TOL2MSGEXISTS: Check if a L1 to L2 message exists M[result_address] = L1TOL2MSGEXISTS(M[msg_hash_ad...
mem[result_offset] = mem[a_address] < mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] < mem[b_address]
mem[result_offset] = mem[a_address] <= mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] <= mem[b_address]
MOV_16 instruction: mem[dst_offset] = mem[src_offset].
MemoryTagWrapper value_tag
MOV_8 instruction: mem[dst_offset] = mem[src_offset].
MemoryTagWrapper value_tag
mem[result_offset] = mem[a_address] * mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] * mem[b_address]
NOTEHASHEXISTS: M[result_offset] = NOTEHASHEXISTS(M[notehash_offset], M[leaf_index_offset]) len = len...
NULLIFIEREXISTS: checks if nullifier exists in the nullifier tree Gets contract's address by GETENVVA...
mem[result_offset] = mem[a_address] | mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] | mem[b_address]
POSEIDON2PERM: Perform Poseidon2 permutation on 4 FF values M[dst_address:dst_address+4] = poseidon2_...
: RETURNDATASIZE + RETURNDATACOPY:
SET_128 instruction.
MemoryTagWrapper value_tag
SET_16 instruction.
MemoryTagWrapper value_tag
SET_32 instruction.
MemoryTagWrapper value_tag
SET_64 instruction.
MemoryTagWrapper value_tag
SET_8 instruction.
MemoryTagWrapper value_tag
SET_FF instruction.
MemoryTagWrapper value_tag
SHA256COMPRESSION: Perform SHA256 compression M[dst_address:dst_address+8] = sha256_compression(M[sta...
mem[result_offset] = mem[a_address] << mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] << mem[b_address]
mem[result_offset] = mem[a_address] >> mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] >> mem[b_address]
SLOAD: M[slot_offset] = slot; M[result_offset] = S[M[slotOffset]].
SSTORE: M[slot_offset_index] = slot; S[M[slotOffset]] = M[srcOffset].
mem[result_offset] = mem[a_address] - mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] - mem[b_address]
TORADIXBE: Convert a field element to a vector of limbs in big-endian radix representation M[dst_addr...
AddressingModeWrapper mode
uint32_t base_offset_seed
A seed for the generation of the base offset Used for Relative/IndirectRelative modes only Sets M[0] ...
uint32_t index
Index of the variable in the memory_manager.stored_variables map.
MemoryTagWrapper tag
uint16_t pointer_address_seed
A seed for the generation of the pointer address Used for Indirect/IndirectRelative modes only.
mem[result_offset] = mem[a_address] ^ mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] ^ mem[b_address]
BB_INLINE constexpr bool is_zero() const noexcept
void mutate_uint16_t(uint16_t &value, std::mt19937_64 &rng, const Uint16MutationConfig &config)
Definition uint16_t.cpp:4
void mutate_uint32_t(uint32_t &value, std::mt19937_64 &rng, const Uint32MutationConfig &config)
Definition uint32_t.cpp:4
void mutate_uint64_t(uint64_t &value, std::mt19937_64 &rng, const Uint64MutationConfig &config)
Definition uint64_t.cpp:4
void mutate_uint8_t(uint8_t &value, std::mt19937_64 &rng, const Uint8MutationConfig &config)
Definition uint8_t.cpp:4
uint64_t generate_random_uint64(std::mt19937_64 &rng)
uint32_t generate_random_uint32(std::mt19937_64 &rng)
uint16_t generate_random_uint16(std::mt19937_64 &rng)
uint8_t generate_random_uint8(std::mt19937_64 &rng)