1use std::collections::BTreeSet;
7
8use crate::BlackBoxFunc;
9use crate::native_types::Witness;
10
11use acir_field::AcirField;
12use msgpack_tagged::MsgpackTagged;
13use serde::{Deserialize, Deserializer, Serialize, Serializer};
14use thiserror::Error;
15
16#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
18#[derive(Serialize, Deserialize, MsgpackTagged)]
19#[cfg_attr(feature = "arb", derive(proptest_derive::Arbitrary))]
20pub enum FunctionInput<F> {
21 #[tag(0)]
23 Constant(F),
24 #[tag(1)]
26 Witness(Witness),
27}
28
29impl<F: std::fmt::Display> std::fmt::Display for FunctionInput<F> {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 match &self {
32 FunctionInput::Constant(constant) => {
33 write!(f, "{constant}")
34 }
35 FunctionInput::Witness(witness) => {
36 write!(f, "w{}", witness.0)
37 }
38 }
39 }
40}
41
42impl<F> FunctionInput<F> {
43 pub fn is_constant(&self) -> bool {
44 match self {
45 FunctionInput::Constant(_) => true,
46 FunctionInput::Witness(_) => false,
47 }
48 }
49
50 pub fn to_witness(&self) -> Witness {
51 match self {
52 FunctionInput::Constant(_) => unreachable!("ICE - Expected Witness"),
53 FunctionInput::Witness(witness) => *witness,
54 }
55 }
56}
57
58#[derive(Clone, PartialEq, Eq, Debug, Error)]
59#[error("FunctionInput value has too many bits: value: {value}, {value_num_bits} >= {max_bits}")]
60pub struct InvalidInputBitSize {
61 pub value: String,
62 pub value_num_bits: u32,
63 pub max_bits: u32,
64}
65
66#[derive(Clone, PartialEq, Eq, Hash)]
72#[derive(Serialize, Deserialize, MsgpackTagged)]
73pub enum BlackBoxFuncCall<F> {
74 #[tag(0)]
81 AES128Encrypt {
82 #[tag(0)]
83 inputs: Vec<FunctionInput<F>>,
84 #[tag(1)]
85 iv: Box<[FunctionInput<F>; 16]>,
86 #[tag(2)]
87 key: Box<[FunctionInput<F>; 16]>,
88 #[tag(3)]
89 outputs: Vec<Witness>,
90 },
91 #[tag(1)]
98 AND {
99 #[tag(0)]
100 lhs: FunctionInput<F>,
101 #[tag(1)]
102 rhs: FunctionInput<F>,
103 #[tag(2)]
104 num_bits: u32,
105 #[tag(3)]
106 output: Witness,
107 },
108 #[tag(2)]
115 XOR {
116 #[tag(0)]
117 lhs: FunctionInput<F>,
118 #[tag(1)]
119 rhs: FunctionInput<F>,
120 #[tag(2)]
121 num_bits: u32,
122 #[tag(3)]
123 output: Witness,
124 },
125 #[tag(3)]
129 RANGE {
130 #[tag(0)]
131 input: FunctionInput<F>,
132 #[tag(1)]
133 num_bits: u32,
134 },
135 #[tag(4)]
141 Blake2s {
142 #[tag(0)]
143 inputs: Vec<FunctionInput<F>>,
144 #[tag(1)]
145 outputs: Box<[Witness; 32]>,
146 },
147 #[tag(5)]
152 Blake3 {
153 #[tag(0)]
154 inputs: Vec<FunctionInput<F>>,
155 #[tag(1)]
156 outputs: Box<[Witness; 32]>,
157 },
158 #[tag(6)]
180 EcdsaSecp256k1 {
181 #[tag(0)]
182 public_key_x: Box<[FunctionInput<F>; 32]>,
183 #[tag(1)]
184 public_key_y: Box<[FunctionInput<F>; 32]>,
185 #[serde(
186 serialize_with = "serialize_big_array",
187 deserialize_with = "deserialize_big_array_into_box"
188 )]
189 #[tag(2)]
190 signature: Box<[FunctionInput<F>; 64]>,
191 #[tag(3)]
192 hashed_message: Box<[FunctionInput<F>; 32]>,
193 #[tag(4)]
194 predicate: FunctionInput<F>,
195 #[tag(5)]
196 output: Witness,
197 },
198 #[tag(7)]
202 EcdsaSecp256r1 {
203 #[tag(0)]
204 public_key_x: Box<[FunctionInput<F>; 32]>,
205 #[tag(1)]
206 public_key_y: Box<[FunctionInput<F>; 32]>,
207 #[serde(
208 serialize_with = "serialize_big_array",
209 deserialize_with = "deserialize_big_array_into_box"
210 )]
211 #[tag(2)]
212 signature: Box<[FunctionInput<F>; 64]>,
213 #[tag(3)]
214 hashed_message: Box<[FunctionInput<F>; 32]>,
215 #[tag(4)]
216 predicate: FunctionInput<F>,
217 #[tag(5)]
218 output: Witness,
219 },
220 #[tag(8)]
243 MultiScalarMul {
244 #[tag(0)]
245 points: Vec<FunctionInput<F>>,
246 #[tag(1)]
247 scalars: Vec<FunctionInput<F>>,
248 #[tag(2)]
249 predicate: FunctionInput<F>,
250 #[tag(3)]
251 outputs: (Witness, Witness),
252 },
253 #[tag(9)]
268 EmbeddedCurveAdd {
269 #[tag(0)]
270 input1: Box<[FunctionInput<F>; 2]>,
271 #[tag(1)]
272 input2: Box<[FunctionInput<F>; 2]>,
273 #[tag(2)]
274 predicate: FunctionInput<F>,
275 #[tag(3)]
276 outputs: (Witness, Witness),
277 },
278 #[tag(10)]
282 Keccakf1600 {
283 #[tag(0)]
284 inputs: Box<[FunctionInput<F>; 25]>,
285 #[tag(1)]
286 outputs: Box<[Witness; 25]>,
287 },
288 #[tag(11)]
311 RecursiveAggregation {
312 #[tag(0)]
314 verification_key: Vec<FunctionInput<F>>,
315 #[tag(1)]
316 proof: Vec<FunctionInput<F>>,
317 #[tag(2)]
321 public_inputs: Vec<FunctionInput<F>>,
322 #[tag(3)]
326 key_hash: FunctionInput<F>,
327 #[tag(4)]
334 proof_type: u32,
335 #[tag(5)]
337 predicate: FunctionInput<F>,
338 },
339 #[tag(12)]
348 Poseidon2Permutation {
349 #[tag(0)]
351 inputs: Vec<FunctionInput<F>>,
352 #[tag(1)]
354 outputs: Vec<Witness>,
355 },
356 #[tag(13)]
364 Sha256Compression {
365 #[tag(0)]
367 inputs: Box<[FunctionInput<F>; 16]>,
368 #[tag(1)]
370 hash_values: Box<[FunctionInput<F>; 8]>,
371 #[tag(2)]
373 outputs: Box<[Witness; 8]>,
374 },
375}
376
377impl<F> BlackBoxFuncCall<F> {
378 pub fn get_black_box_func(&self) -> BlackBoxFunc {
379 match self {
380 BlackBoxFuncCall::AES128Encrypt { .. } => BlackBoxFunc::AES128Encrypt,
381 BlackBoxFuncCall::AND { .. } => BlackBoxFunc::AND,
382 BlackBoxFuncCall::XOR { .. } => BlackBoxFunc::XOR,
383 BlackBoxFuncCall::RANGE { .. } => BlackBoxFunc::RANGE,
384 BlackBoxFuncCall::Blake2s { .. } => BlackBoxFunc::Blake2s,
385 BlackBoxFuncCall::Blake3 { .. } => BlackBoxFunc::Blake3,
386 BlackBoxFuncCall::EcdsaSecp256k1 { .. } => BlackBoxFunc::EcdsaSecp256k1,
387 BlackBoxFuncCall::EcdsaSecp256r1 { .. } => BlackBoxFunc::EcdsaSecp256r1,
388 BlackBoxFuncCall::MultiScalarMul { .. } => BlackBoxFunc::MultiScalarMul,
389 BlackBoxFuncCall::EmbeddedCurveAdd { .. } => BlackBoxFunc::EmbeddedCurveAdd,
390 BlackBoxFuncCall::Keccakf1600 { .. } => BlackBoxFunc::Keccakf1600,
391 BlackBoxFuncCall::RecursiveAggregation { .. } => BlackBoxFunc::RecursiveAggregation,
392 BlackBoxFuncCall::Poseidon2Permutation { .. } => BlackBoxFunc::Poseidon2Permutation,
393 BlackBoxFuncCall::Sha256Compression { .. } => BlackBoxFunc::Sha256Compression,
394 }
395 }
396
397 pub fn name(&self) -> &str {
398 self.get_black_box_func().name()
399 }
400
401 pub fn bit_size(&self) -> Option<u32> {
402 match self {
403 BlackBoxFuncCall::AND { num_bits, .. }
404 | BlackBoxFuncCall::XOR { num_bits, .. }
405 | BlackBoxFuncCall::RANGE { num_bits, .. } => Some(*num_bits),
406 _ => None,
407 }
408 }
409
410 pub fn get_outputs_vec(&self) -> Vec<Witness> {
411 match self {
412 BlackBoxFuncCall::Blake2s { outputs, .. }
413 | BlackBoxFuncCall::Blake3 { outputs, .. } => outputs.to_vec(),
414
415 BlackBoxFuncCall::Keccakf1600 { outputs, .. } => outputs.to_vec(),
416
417 BlackBoxFuncCall::Sha256Compression { outputs, .. } => outputs.to_vec(),
418
419 BlackBoxFuncCall::AES128Encrypt { outputs, .. }
420 | BlackBoxFuncCall::Poseidon2Permutation { outputs, .. } => outputs.clone(),
421
422 BlackBoxFuncCall::AND { output, .. }
423 | BlackBoxFuncCall::XOR { output, .. }
424 | BlackBoxFuncCall::EcdsaSecp256k1 { output, .. }
425 | BlackBoxFuncCall::EcdsaSecp256r1 { output, .. } => vec![*output],
426 BlackBoxFuncCall::MultiScalarMul { outputs, .. }
427 | BlackBoxFuncCall::EmbeddedCurveAdd { outputs, .. } => {
428 vec![outputs.0, outputs.1]
429 }
430 BlackBoxFuncCall::RANGE { .. } | BlackBoxFuncCall::RecursiveAggregation { .. } => {
431 vec![]
432 }
433 }
434 }
435}
436
437impl<F: Copy + AcirField> BlackBoxFuncCall<F> {
438 pub fn get_inputs_vec(&self) -> Vec<FunctionInput<F>> {
439 match self {
440 BlackBoxFuncCall::Blake2s { inputs, outputs: _ }
441 | BlackBoxFuncCall::Blake3 { inputs, outputs: _ }
442 | BlackBoxFuncCall::Poseidon2Permutation { inputs, outputs: _ } => inputs.clone(),
443
444 BlackBoxFuncCall::Keccakf1600 { inputs, outputs: _ } => inputs.to_vec(),
445 BlackBoxFuncCall::AES128Encrypt { inputs, iv, key, outputs: _ } => {
446 [inputs, iv.as_slice(), key.as_slice()].concat()
447 }
448 BlackBoxFuncCall::Sha256Compression { inputs, hash_values, outputs: _ } => {
449 [inputs.as_slice(), hash_values.as_slice()].concat()
450 }
451 BlackBoxFuncCall::AND { lhs, rhs, output: _, num_bits: _ }
452 | BlackBoxFuncCall::XOR { lhs, rhs, output: _, num_bits: _ } => {
453 vec![*lhs, *rhs]
454 }
455 BlackBoxFuncCall::RANGE { input, num_bits: _ } => vec![*input],
456
457 BlackBoxFuncCall::MultiScalarMul { points, scalars, predicate, outputs: _ } => {
458 [points.as_slice(), scalars.as_slice(), &[*predicate]].concat()
459 }
460 BlackBoxFuncCall::EmbeddedCurveAdd { input1, input2, predicate, outputs: _ } => {
461 vec![input1[0], input1[1], input2[0], input2[1], *predicate]
462 }
463 BlackBoxFuncCall::EcdsaSecp256k1 {
464 public_key_x,
465 public_key_y,
466 signature,
467 hashed_message,
468 predicate,
469 output: _,
470 } => [
471 public_key_x.as_slice(),
472 public_key_y.as_slice(),
473 signature.as_slice(),
474 hashed_message.as_slice(),
475 &[*predicate],
476 ]
477 .concat(),
478 BlackBoxFuncCall::EcdsaSecp256r1 {
479 public_key_x,
480 public_key_y,
481 signature,
482 hashed_message,
483 predicate,
484 output: _,
485 } => [
486 public_key_x.as_slice(),
487 public_key_y.as_slice(),
488 signature.as_slice(),
489 hashed_message.as_slice(),
490 &[*predicate],
491 ]
492 .concat(),
493 BlackBoxFuncCall::RecursiveAggregation {
494 verification_key: key,
495 proof,
496 public_inputs,
497 key_hash,
498 proof_type: _,
499 predicate,
500 } => [key.as_slice(), proof, public_inputs, &[*key_hash], &[*predicate]].concat(),
501 }
502 }
503
504 pub fn get_input_witnesses(&self) -> BTreeSet<Witness> {
505 let mut result = BTreeSet::new();
506 for input in self.get_inputs_vec() {
507 if let FunctionInput::Witness(w) = input {
508 result.insert(w);
509 }
510 }
511 result
512 }
513
514 pub fn get_predicate(&self) -> Option<Witness> {
515 let predicate = match self {
516 BlackBoxFuncCall::AES128Encrypt { .. }
517 | BlackBoxFuncCall::AND { .. }
518 | BlackBoxFuncCall::XOR { .. }
519 | BlackBoxFuncCall::RANGE { .. }
520 | BlackBoxFuncCall::Blake2s { .. }
521 | BlackBoxFuncCall::Blake3 { .. }
522 | BlackBoxFuncCall::Keccakf1600 { .. }
523 | BlackBoxFuncCall::Poseidon2Permutation { .. }
524 | BlackBoxFuncCall::Sha256Compression { .. } => FunctionInput::Constant(F::one()),
525 BlackBoxFuncCall::EcdsaSecp256k1 { predicate, .. }
526 | BlackBoxFuncCall::EcdsaSecp256r1 { predicate, .. }
527 | BlackBoxFuncCall::MultiScalarMul { predicate, .. }
528 | BlackBoxFuncCall::EmbeddedCurveAdd { predicate, .. }
529 | BlackBoxFuncCall::RecursiveAggregation { predicate, .. } => *predicate,
530 };
531 if predicate.is_constant() { None } else { Some(predicate.to_witness()) }
532 }
533}
534
535impl<F: std::fmt::Display + Copy> std::fmt::Display for BlackBoxFuncCall<F> {
536 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
537 let uppercase_name = self.name().to_uppercase();
538 write!(f, "BLACKBOX::{uppercase_name} ")?;
539
540 match self {
541 BlackBoxFuncCall::AES128Encrypt { inputs, iv, key, outputs } => {
542 let inputs = slice_to_string(inputs);
543 let iv = slice_to_string(&iv.to_vec());
544 let key = slice_to_string(&key.to_vec());
545 let outputs = slice_to_string(outputs);
546 write!(f, "inputs: {inputs}, iv: {iv}, key: {key}, outputs: {outputs}")?;
547 }
548 BlackBoxFuncCall::AND { lhs, rhs, num_bits, output }
549 | BlackBoxFuncCall::XOR { lhs, rhs, num_bits, output } => {
550 write!(f, "lhs: {lhs}, rhs: {rhs}, output: {output}, bits: {num_bits}")?;
551 }
552 BlackBoxFuncCall::RANGE { input, num_bits } => {
553 write!(f, "input: {input}, bits: {num_bits}")?;
554 }
555 BlackBoxFuncCall::Blake2s { inputs, outputs }
556 | BlackBoxFuncCall::Blake3 { inputs, outputs } => {
557 let inputs = slice_to_string(inputs);
558 let outputs = slice_to_string(&outputs.to_vec());
559 write!(f, "inputs: {inputs}, outputs: {outputs}")?;
560 }
561 BlackBoxFuncCall::EcdsaSecp256k1 {
562 public_key_x,
563 public_key_y,
564 signature,
565 hashed_message,
566 predicate,
567 output,
568 }
569 | BlackBoxFuncCall::EcdsaSecp256r1 {
570 public_key_x,
571 public_key_y,
572 signature,
573 hashed_message,
574 predicate,
575 output,
576 } => {
577 let public_key_x = slice_to_string(&public_key_x.to_vec());
578 let public_key_y = slice_to_string(&public_key_y.to_vec());
579 let signature = slice_to_string(&signature.to_vec());
580 let hashed_message = slice_to_string(&hashed_message.to_vec());
581 write!(
582 f,
583 "public_key_x: {public_key_x}, public_key_y: {public_key_y}, signature: {signature}, hashed_message: {hashed_message}, predicate: {predicate}, output: {output}"
584 )?;
585 }
586 BlackBoxFuncCall::MultiScalarMul { points, scalars, predicate, outputs } => {
587 let points = slice_to_string(points);
588 let scalars = slice_to_string(scalars);
589 write!(
590 f,
591 "points: {points}, scalars: {scalars}, predicate: {predicate}, outputs: [{}, {}]",
592 outputs.0, outputs.1
593 )?;
594 }
595 BlackBoxFuncCall::EmbeddedCurveAdd { input1, input2, predicate, outputs } => {
596 let input1 = slice_to_string(&input1.to_vec());
597 let input2 = slice_to_string(&input2.to_vec());
598 write!(
599 f,
600 "input1: {input1}, input2: {input2}, predicate: {predicate}, outputs: [{}, {}]",
601 outputs.0, outputs.1
602 )?;
603 }
604 BlackBoxFuncCall::Keccakf1600 { inputs, outputs } => {
605 let inputs = slice_to_string(&inputs.to_vec());
606 let outputs = slice_to_string(&outputs.to_vec());
607 write!(f, "inputs: {inputs}, outputs: {outputs}")?;
608 }
609 BlackBoxFuncCall::RecursiveAggregation {
610 verification_key,
611 proof,
612 public_inputs,
613 key_hash,
614 proof_type,
615 predicate,
616 } => {
617 let verification_key = slice_to_string(verification_key);
618 let proof = slice_to_string(proof);
619 let public_inputs = slice_to_string(public_inputs);
620 write!(
621 f,
622 "verification_key: {verification_key}, proof: {proof}, public_inputs: {public_inputs}, key_hash: {key_hash}, proof_type: {proof_type}, predicate: {predicate}"
623 )?;
624 }
625 BlackBoxFuncCall::Poseidon2Permutation { inputs, outputs } => {
626 let inputs = slice_to_string(inputs);
627 let outputs = slice_to_string(outputs);
628 write!(f, "inputs: {inputs}, outputs: {outputs}")?;
629 }
630 BlackBoxFuncCall::Sha256Compression { inputs, hash_values, outputs } => {
631 let inputs = slice_to_string(&inputs.to_vec());
632 let hash_values = slice_to_string(&hash_values.to_vec());
633 let outputs = slice_to_string(&outputs.to_vec());
634 write!(f, "inputs: {inputs}, hash_values: {hash_values}, outputs: {outputs}")?;
635 }
636 }
637
638 Ok(())
639 }
640}
641
642fn slice_to_string<D: std::fmt::Display>(inputs: &[D]) -> String {
643 let inputs = inputs.iter().map(|i| i.to_string()).collect::<Vec<String>>().join(", ");
644 format!("[{inputs}]")
645}
646
647impl<F: std::fmt::Display + Copy> std::fmt::Debug for BlackBoxFuncCall<F> {
648 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
649 std::fmt::Display::fmt(self, f)
650 }
651}
652
653fn serialize_big_array<S, F: Serialize>(
654 big_array: &[FunctionInput<F>; 64],
655 s: S,
656) -> Result<S::Ok, S::Error>
657where
658 S: Serializer,
659{
660 use serde_big_array::BigArray;
661
662 (*big_array).serialize(s)
663}
664
665fn deserialize_big_array_into_box<'de, D, F: Deserialize<'de>>(
666 deserializer: D,
667) -> Result<Box<[FunctionInput<F>; 64]>, D::Error>
668where
669 D: Deserializer<'de>,
670{
671 use serde_big_array::BigArray;
672
673 let big_array: [FunctionInput<F>; 64] = BigArray::deserialize(deserializer)?;
674 Ok(Box::new(big_array))
675}
676
677#[cfg(test)]
678mod tests {
679
680 use crate::{circuit::Opcode, native_types::Witness};
681 use acir_field::{AcirField, FieldElement};
682
683 use super::{BlackBoxFuncCall, FunctionInput};
684
685 fn keccakf1600_opcode<F: AcirField>() -> Opcode<F> {
686 let inputs: Box<[FunctionInput<F>; 25]> =
687 Box::new(std::array::from_fn(|i| FunctionInput::Witness(Witness(i as u32 + 1))));
688 let outputs: Box<[Witness; 25]> = Box::new(std::array::from_fn(|i| Witness(i as u32 + 26)));
689
690 Opcode::BlackBoxFuncCall(BlackBoxFuncCall::Keccakf1600 { inputs, outputs })
691 }
692
693 #[test]
694 fn keccakf1600_serialization_roundtrip() {
695 use crate::serialization::{msgpack_deserialize, msgpack_serialize};
696
697 let opcode = keccakf1600_opcode::<FieldElement>();
698 let buf = msgpack_serialize(&opcode, true).unwrap();
699 let recovered_opcode = msgpack_deserialize(&buf).unwrap();
700 assert_eq!(opcode, recovered_opcode);
701 }
702}
703
704#[cfg(feature = "arb")]
705mod arb {
706 use acir_field::AcirField;
707 use proptest::prelude::*;
708
709 use crate::native_types::Witness;
710
711 use super::{BlackBoxFuncCall, FunctionInput};
712
713 impl<F> Arbitrary for BlackBoxFuncCall<F>
715 where
716 F: AcirField + Arbitrary,
717 {
718 type Parameters = ();
719 type Strategy = BoxedStrategy<Self>;
720
721 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
722 let input = any::<FunctionInput<F>>();
723 let input_vec = any::<Vec<FunctionInput<F>>>();
724 let input_arr_2 = any::<Box<[FunctionInput<F>; 2]>>();
725 let input_arr_3 = any::<Box<[FunctionInput<F>; 3]>>();
726 let input_arr_8 = any::<Box<[FunctionInput<F>; 8]>>();
727 let input_arr_16 = any::<Box<[FunctionInput<F>; 16]>>();
728 let input_arr_25 = any::<Box<[FunctionInput<F>; 25]>>();
729 let input_arr_32 = any::<Box<[FunctionInput<F>; 32]>>();
730 let input_arr_64 = any::<Box<[FunctionInput<F>; 64]>>();
731 let witness = any::<Witness>();
732 let witness_vec = any::<Vec<Witness>>();
733 let witness_arr_8 = any::<Box<[Witness; 8]>>();
734 let witness_arr_25 = any::<Box<[Witness; 25]>>();
735 let witness_arr_32 = any::<Box<[Witness; 32]>>();
736
737 let witness_arr_16 = any::<Box<[Witness; 16]>>();
740 let case_aes128_encrypt =
741 (input_arr_16.clone(), input_arr_16.clone(), input_arr_16.clone(), witness_arr_16)
742 .prop_map(|(inputs, iv, key, outputs)| BlackBoxFuncCall::AES128Encrypt {
743 inputs: inputs.to_vec(),
744 iv,
745 key,
746 outputs: outputs.to_vec(),
747 });
748
749 let case_and = (input_arr_3.clone(), input_arr_8.clone(), witness.clone()).prop_map(
750 |(lhs, rhs, output)| BlackBoxFuncCall::AND {
751 lhs: lhs[0],
752 rhs: rhs[1],
753 num_bits: 8,
754 output,
755 },
756 );
757
758 let case_xor = (input_arr_3, input_arr_8.clone(), witness.clone()).prop_map(
759 |(lhs, rhs, output)| BlackBoxFuncCall::XOR {
760 lhs: lhs[0],
761 rhs: rhs[1],
762 num_bits: 8,
763 output,
764 },
765 );
766
767 let case_range = witness.clone().prop_map(|witness| BlackBoxFuncCall::RANGE {
768 input: FunctionInput::Witness(witness),
769 num_bits: 32,
770 });
771
772 let case_blake2s =
773 (input_arr_8.clone(), witness_arr_32.clone()).prop_map(|(inputs, outputs)| {
774 BlackBoxFuncCall::Blake2s { inputs: inputs.to_vec(), outputs }
775 });
776
777 let case_blake3 =
778 (input_arr_8.clone(), witness_arr_32).prop_map(|(inputs, outputs)| {
779 BlackBoxFuncCall::Blake3 { inputs: inputs.to_vec(), outputs }
780 });
781
782 let case_ecdsa_secp256k1 = (
783 input_arr_32.clone(),
784 input_arr_32.clone(),
785 input_arr_64.clone(),
786 input_arr_32.clone(),
787 witness.clone(),
788 input.clone(),
789 )
790 .prop_map(
791 |(public_key_x, public_key_y, signature, hashed_message, output, predicate)| {
792 BlackBoxFuncCall::EcdsaSecp256k1 {
793 public_key_x,
794 public_key_y,
795 signature,
796 hashed_message,
797 output,
798 predicate,
799 }
800 },
801 );
802
803 let case_ecdsa_secp256r1 = (
804 input_arr_32.clone(),
805 input_arr_32.clone(),
806 input_arr_64,
807 input_arr_32,
808 witness.clone(),
809 input.clone(),
810 )
811 .prop_map(
812 |(public_key_x, public_key_y, signature, hashed_message, output, predicate)| {
813 BlackBoxFuncCall::EcdsaSecp256r1 {
814 public_key_x,
815 public_key_y,
816 signature,
817 hashed_message,
818 output,
819 predicate,
820 }
821 },
822 );
823
824 let case_multi_scalar_mul = (
825 input_vec.clone(),
826 input_vec.clone(),
827 input.clone(),
828 witness.clone(),
829 witness.clone(),
830 )
831 .prop_map(|(points, scalars, predicate, w1, w2)| {
832 BlackBoxFuncCall::MultiScalarMul {
833 points,
834 scalars,
835 predicate,
836 outputs: (w1, w2),
837 }
838 });
839
840 let case_embedded_curve_add =
841 (input_arr_2.clone(), input_arr_2, input.clone(), witness.clone(), witness)
842 .prop_map(|(input1, input2, predicate, w1, w2)| {
843 BlackBoxFuncCall::EmbeddedCurveAdd {
844 input1,
845 input2,
846 predicate,
847 outputs: (w1, w2),
848 }
849 });
850
851 let case_keccakf1600 = (input_arr_25, witness_arr_25)
852 .prop_map(|(inputs, outputs)| BlackBoxFuncCall::Keccakf1600 { inputs, outputs });
853
854 let case_recursive_aggregation = (
855 input_vec.clone(),
856 input_vec.clone(),
857 input_vec.clone(),
858 input.clone(),
859 any::<u32>(),
860 input,
861 )
862 .prop_map(
863 |(verification_key, proof, public_inputs, key_hash, proof_type, predicate)| {
864 BlackBoxFuncCall::RecursiveAggregation {
865 verification_key,
866 proof,
867 public_inputs,
868 key_hash,
869 proof_type,
870 predicate,
871 }
872 },
873 );
874
875 let case_poseidon2_permutation =
876 (input_vec, witness_vec).prop_map(|(inputs, outputs)| {
877 BlackBoxFuncCall::Poseidon2Permutation { inputs, outputs }
878 });
879
880 let case_sha256_compression = (input_arr_16, input_arr_8, witness_arr_8).prop_map(
881 |(inputs, hash_values, outputs)| BlackBoxFuncCall::Sha256Compression {
882 inputs,
883 hash_values,
884 outputs,
885 },
886 );
887
888 prop_oneof![
889 case_aes128_encrypt,
890 case_and,
891 case_xor,
892 case_range,
893 case_blake2s,
894 case_blake3,
895 case_ecdsa_secp256k1,
896 case_ecdsa_secp256r1,
897 case_multi_scalar_mul,
898 case_embedded_curve_add,
899 case_keccakf1600,
900 case_recursive_aggregation,
901 case_poseidon2_permutation,
902 case_sha256_compression,
903 ]
904 .boxed()
905 }
906 }
907}