571 .result = arg.output.
value,
572 .num_bits = arg.lhs.num_bits,
573 .is_xor_gate =
false,
583 .result = arg.output.
value,
584 .num_bits = arg.lhs.num_bits,
593 .num_bits = arg.input.num_bits,
606 .iv =
transform::map(*arg.iv, [](
auto& e) { return parse_input(e); }),
607 .key =
transform::map(*arg.key, [](
auto& e) { return parse_input(e); }),
608 .outputs =
transform::map(arg.outputs, [](
auto& e) { return e.value; }),
617 .hash_values =
transform::map(*arg.hash_values, [](
auto& e) { return parse_input(e); }),
618 .result =
transform::map(*arg.outputs, [](
auto& e) { return e.value; }),
629 .blackbox_input = parse_input(e),
630 .num_bits = e.num_bits,
644 .blackbox_input = parse_input(e),
645 .num_bits = e.num_bits,
655 af.ecdsa_k1_constraints.push_back(EcdsaConstraint{
657 transform::map(*arg.hashed_message, [](
auto& e) { return get_witness_from_function_input(e); }),
659 transform::map(*arg.signature, [](
auto& e) { return get_witness_from_function_input(e); }),
661 transform::map(*arg.public_key_x, [](
auto& e) { return get_witness_from_function_input(e); }),
663 transform::map(*arg.public_key_y, [](
auto& e) { return get_witness_from_function_input(e); }),
664 .result = arg.output.value,
666 af.constrained_witness.insert(af.ecdsa_k1_constraints.back().result);
667 af.original_opcode_indices.ecdsa_k1_constraints.push_back(opcode_index);
669 af.ecdsa_r1_constraints.push_back(EcdsaConstraint{
671 transform::map(*arg.hashed_message, [](
auto& e) { return get_witness_from_function_input(e); }),
673 transform::map(*arg.signature, [](
auto& e) { return get_witness_from_function_input(e); }),
675 transform::map(*arg.public_key_x, [](
auto& e) { return get_witness_from_function_input(e); }),
677 transform::map(*arg.public_key_y, [](
auto& e) { return get_witness_from_function_input(e); }),
678 .result = arg.output.value,
680 af.constrained_witness.insert(af.ecdsa_r1_constraints.back().result);
681 af.original_opcode_indices.ecdsa_r1_constraints.push_back(opcode_index);
683 af.multi_scalar_mul_constraints.push_back(MultiScalarMul{
684 .points =
transform::map(arg.points, [](
auto& e) { return parse_input(e); }),
685 .scalars =
transform::map(arg.scalars, [](
auto& e) { return parse_input(e); }),
686 .out_point_x = (*arg.outputs)[0].
value,
687 .out_point_y = (*arg.outputs)[1].value,
688 .out_point_is_infinite = (*arg.outputs)[2].
value,
690 af.constrained_witness.insert(af.multi_scalar_mul_constraints.back().out_point_x);
691 af.constrained_witness.insert(af.multi_scalar_mul_constraints.back().out_point_y);
692 af.constrained_witness.insert(af.multi_scalar_mul_constraints.back().out_point_is_infinite);
693 af.original_opcode_indices.multi_scalar_mul_constraints.push_back(opcode_index);
697 auto input_1_infinite =
parse_input((*arg.input1)[2]);
700 auto input_2_infinite =
parse_input((*arg.input2)[2]);
702 af.ec_add_constraints.push_back(EcAdd{
703 .input1_x = input_1_x,
704 .input1_y = input_1_y,
705 .input1_infinite = input_1_infinite,
706 .input2_x = input_2_x,
707 .input2_y = input_2_y,
708 .input2_infinite = input_2_infinite,
709 .result_x = (*arg.outputs)[0].
value,
710 .result_y = (*arg.outputs)[1].value,
711 .result_infinite = (*arg.outputs)[2].
value,
713 af.constrained_witness.insert(af.ec_add_constraints.back().result_x);
714 af.constrained_witness.insert(af.ec_add_constraints.back().result_y);
715 af.constrained_witness.insert(af.ec_add_constraints.back().result_infinite);
716 af.original_opcode_indices.ec_add_constraints.push_back(opcode_index);
718 af.keccak_permutations.push_back(Keccakf1600{
719 .state =
transform::map(*arg.inputs, [](
auto& e) { return parse_input(e); }),
720 .result =
transform::map(*arg.outputs, [](
auto& e) { return e.value; }),
722 for (
auto& output : af.keccak_permutations.back().result) {
723 af.constrained_witness.insert(output);
725 af.original_opcode_indices.keccak_permutations.push_back(opcode_index);
730 auto proof_type_in = arg.proof_type;
732 auto c = RecursionConstraint{
734 [](
auto& e) { return get_witness_from_function_input(e); }),
735 .proof =
transform::map(arg.proof, [](
auto& e) { return get_witness_from_function_input(e); }),
737 transform::map(arg.public_inputs, [](
auto& e) { return get_witness_from_function_input(e); }),
738 .key_hash = input_key,
739 .proof_type = proof_type_in,
743 switch (c.proof_type) {
748 af.honk_recursion_constraints.push_back(c);
749 af.original_opcode_indices.honk_recursion_constraints.push_back(opcode_index);
755 af.pg_recursion_constraints.push_back(c);
756 af.original_opcode_indices.pg_recursion_constraints.push_back(opcode_index);
759 af.avm_recursion_constraints.push_back(c);
760 af.original_opcode_indices.avm_recursion_constraints.push_back(opcode_index);
763 af.civc_recursion_constraints.push_back(c);
764 af.original_opcode_indices.civc_recursion_constraints.push_back(opcode_index);
770 af.bigint_from_le_bytes_constraints.push_back(BigIntFromLeBytes{
771 .inputs =
transform::map(arg.inputs, [](
auto& e) { return get_witness_from_function_input(e); }),
772 .modulus =
transform::map(arg.modulus, [](
auto& e) -> uint32_t { return e; }),
773 .result = arg.output,
775 af.original_opcode_indices.bigint_from_le_bytes_constraints.push_back(opcode_index);
777 af.bigint_to_le_bytes_constraints.push_back(BigIntToLeBytes{
779 .result =
transform::map(arg.outputs, [](
auto& e) { return e.value; }),
781 for (
auto& output : af.bigint_to_le_bytes_constraints.back().result) {
782 af.constrained_witness.insert(output);
784 af.original_opcode_indices.bigint_to_le_bytes_constraints.push_back(opcode_index);
786 af.bigint_operations.push_back(BigIntOperation{
789 .result = arg.output,
792 af.original_opcode_indices.bigint_operations.push_back(opcode_index);
794 af.bigint_operations.push_back(BigIntOperation{
797 .result = arg.output,
800 af.original_opcode_indices.bigint_operations.push_back(opcode_index);
802 af.bigint_operations.push_back(BigIntOperation{
805 .result = arg.output,
808 af.original_opcode_indices.bigint_operations.push_back(opcode_index);
810 af.bigint_operations.push_back(BigIntOperation{
813 .result = arg.output,
816 af.original_opcode_indices.bigint_operations.push_back(opcode_index);
818 af.poseidon2_constraints.push_back(Poseidon2Constraint{
819 .state =
transform::map(arg.inputs, [](
auto& e) { return parse_input(e); }),
820 .result =
transform::map(arg.outputs, [](
auto& e) { return e.value; }),
823 for (
auto& output : af.poseidon2_constraints.back().result) {
824 af.constrained_witness.insert(output);
826 af.original_opcode_indices.poseidon2_constraints.push_back(opcode_index);