1use std::collections::BTreeSet;
7
8use crate::BlackBoxFunc;
9use crate::native_types::Witness;
10
11use acir_field::AcirField;
12use serde::{Deserialize, Deserializer, Serialize, Serializer};
13use thiserror::Error;
14
15#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
17#[cfg_attr(feature = "arb", derive(proptest_derive::Arbitrary))]
18pub enum FunctionInput<F> {
19 Constant(F),
21 Witness(Witness),
23}
24
25impl<F: std::fmt::Display> std::fmt::Display for FunctionInput<F> {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 match &self {
28 FunctionInput::Constant(constant) => {
29 write!(f, "{constant}")
30 }
31 FunctionInput::Witness(witness) => {
32 write!(f, "w{}", witness.0)
33 }
34 }
35 }
36}
37
38impl<F> FunctionInput<F> {
39 pub fn is_constant(&self) -> bool {
40 match self {
41 FunctionInput::Constant(_) => true,
42 FunctionInput::Witness(_) => false,
43 }
44 }
45
46 pub fn to_witness(&self) -> Witness {
47 match self {
48 FunctionInput::Constant(_) => unreachable!("ICE - Expected Witness"),
49 FunctionInput::Witness(witness) => *witness,
50 }
51 }
52}
53
54#[derive(Clone, PartialEq, Eq, Debug, Error)]
55#[error("FunctionInput value has too many bits: value: {value}, {value_num_bits} >= {max_bits}")]
56pub struct InvalidInputBitSize {
57 pub value: String,
58 pub value_num_bits: u32,
59 pub max_bits: u32,
60}
61
62#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
68pub enum BlackBoxFuncCall<F> {
69 AES128Encrypt {
76 inputs: Vec<FunctionInput<F>>,
77 iv: Box<[FunctionInput<F>; 16]>,
78 key: Box<[FunctionInput<F>; 16]>,
79 outputs: Vec<Witness>,
80 },
81 AND { lhs: FunctionInput<F>, rhs: FunctionInput<F>, num_bits: u32, output: Witness },
88 XOR { lhs: FunctionInput<F>, rhs: FunctionInput<F>, num_bits: u32, output: Witness },
95 RANGE { input: FunctionInput<F>, num_bits: u32 },
99 Blake2s { inputs: Vec<FunctionInput<F>>, outputs: Box<[Witness; 32]> },
105 Blake3 { inputs: Vec<FunctionInput<F>>, outputs: Box<[Witness; 32]> },
110 EcdsaSecp256k1 {
132 public_key_x: Box<[FunctionInput<F>; 32]>,
133 public_key_y: Box<[FunctionInput<F>; 32]>,
134 #[serde(
135 serialize_with = "serialize_big_array",
136 deserialize_with = "deserialize_big_array_into_box"
137 )]
138 signature: Box<[FunctionInput<F>; 64]>,
139 hashed_message: Box<[FunctionInput<F>; 32]>,
140 predicate: FunctionInput<F>,
141 output: Witness,
142 },
143 EcdsaSecp256r1 {
147 public_key_x: Box<[FunctionInput<F>; 32]>,
148 public_key_y: Box<[FunctionInput<F>; 32]>,
149 #[serde(
150 serialize_with = "serialize_big_array",
151 deserialize_with = "deserialize_big_array_into_box"
152 )]
153 signature: Box<[FunctionInput<F>; 64]>,
154 hashed_message: Box<[FunctionInput<F>; 32]>,
155 predicate: FunctionInput<F>,
156 output: Witness,
157 },
158 MultiScalarMul {
175 points: Vec<FunctionInput<F>>,
176 scalars: Vec<FunctionInput<F>>,
177 predicate: FunctionInput<F>,
178 outputs: (Witness, Witness, Witness),
179 },
180 EmbeddedCurveAdd {
190 input1: Box<[FunctionInput<F>; 3]>,
191 input2: Box<[FunctionInput<F>; 3]>,
192 predicate: FunctionInput<F>,
193 outputs: (Witness, Witness, Witness),
194 },
195 Keccakf1600 { inputs: Box<[FunctionInput<F>; 25]>, outputs: Box<[Witness; 25]> },
199 RecursiveAggregation {
222 verification_key: Vec<FunctionInput<F>>,
224 proof: Vec<FunctionInput<F>>,
225 public_inputs: Vec<FunctionInput<F>>,
229 key_hash: FunctionInput<F>,
233 proof_type: u32,
240 predicate: FunctionInput<F>,
242 },
243 Poseidon2Permutation {
246 inputs: Vec<FunctionInput<F>>,
248 outputs: Vec<Witness>,
250 },
251 Sha256Compression {
259 inputs: Box<[FunctionInput<F>; 16]>,
261 hash_values: Box<[FunctionInput<F>; 8]>,
263 outputs: Box<[Witness; 8]>,
265 },
266}
267
268impl<F> BlackBoxFuncCall<F> {
269 pub fn get_black_box_func(&self) -> BlackBoxFunc {
270 match self {
271 BlackBoxFuncCall::AES128Encrypt { .. } => BlackBoxFunc::AES128Encrypt,
272 BlackBoxFuncCall::AND { .. } => BlackBoxFunc::AND,
273 BlackBoxFuncCall::XOR { .. } => BlackBoxFunc::XOR,
274 BlackBoxFuncCall::RANGE { .. } => BlackBoxFunc::RANGE,
275 BlackBoxFuncCall::Blake2s { .. } => BlackBoxFunc::Blake2s,
276 BlackBoxFuncCall::Blake3 { .. } => BlackBoxFunc::Blake3,
277 BlackBoxFuncCall::EcdsaSecp256k1 { .. } => BlackBoxFunc::EcdsaSecp256k1,
278 BlackBoxFuncCall::EcdsaSecp256r1 { .. } => BlackBoxFunc::EcdsaSecp256r1,
279 BlackBoxFuncCall::MultiScalarMul { .. } => BlackBoxFunc::MultiScalarMul,
280 BlackBoxFuncCall::EmbeddedCurveAdd { .. } => BlackBoxFunc::EmbeddedCurveAdd,
281 BlackBoxFuncCall::Keccakf1600 { .. } => BlackBoxFunc::Keccakf1600,
282 BlackBoxFuncCall::RecursiveAggregation { .. } => BlackBoxFunc::RecursiveAggregation,
283 BlackBoxFuncCall::Poseidon2Permutation { .. } => BlackBoxFunc::Poseidon2Permutation,
284 BlackBoxFuncCall::Sha256Compression { .. } => BlackBoxFunc::Sha256Compression,
285 }
286 }
287
288 pub fn name(&self) -> &str {
289 self.get_black_box_func().name()
290 }
291
292 pub fn bit_size(&self) -> Option<u32> {
293 match self {
294 BlackBoxFuncCall::AND { num_bits, .. }
295 | BlackBoxFuncCall::XOR { num_bits, .. }
296 | BlackBoxFuncCall::RANGE { num_bits, .. } => Some(*num_bits),
297 _ => None,
298 }
299 }
300
301 pub fn get_outputs_vec(&self) -> Vec<Witness> {
302 match self {
303 BlackBoxFuncCall::Blake2s { outputs, .. }
304 | BlackBoxFuncCall::Blake3 { outputs, .. } => outputs.to_vec(),
305
306 BlackBoxFuncCall::Keccakf1600 { outputs, .. } => outputs.to_vec(),
307
308 BlackBoxFuncCall::Sha256Compression { outputs, .. } => outputs.to_vec(),
309
310 BlackBoxFuncCall::AES128Encrypt { outputs, .. }
311 | BlackBoxFuncCall::Poseidon2Permutation { outputs, .. } => outputs.to_vec(),
312
313 BlackBoxFuncCall::AND { output, .. }
314 | BlackBoxFuncCall::XOR { output, .. }
315 | BlackBoxFuncCall::EcdsaSecp256k1 { output, .. }
316 | BlackBoxFuncCall::EcdsaSecp256r1 { output, .. } => vec![*output],
317 BlackBoxFuncCall::MultiScalarMul { outputs, .. }
318 | BlackBoxFuncCall::EmbeddedCurveAdd { outputs, .. } => {
319 vec![outputs.0, outputs.1, outputs.2]
320 }
321 BlackBoxFuncCall::RANGE { .. } | BlackBoxFuncCall::RecursiveAggregation { .. } => {
322 vec![]
323 }
324 }
325 }
326}
327
328impl<F: Copy + AcirField> BlackBoxFuncCall<F> {
329 pub fn get_inputs_vec(&self) -> Vec<FunctionInput<F>> {
330 match self {
331 BlackBoxFuncCall::Blake2s { inputs, outputs: _ }
332 | BlackBoxFuncCall::Blake3 { inputs, outputs: _ }
333 | BlackBoxFuncCall::Poseidon2Permutation { inputs, outputs: _ } => inputs.to_vec(),
334
335 BlackBoxFuncCall::Keccakf1600 { inputs, outputs: _ } => inputs.to_vec(),
336 BlackBoxFuncCall::AES128Encrypt { inputs, iv, key, outputs: _ } => {
337 [inputs, iv.as_slice(), key.as_slice()].concat()
338 }
339 BlackBoxFuncCall::Sha256Compression { inputs, hash_values, outputs: _ } => {
340 [inputs.as_slice(), hash_values.as_slice()].concat()
341 }
342 BlackBoxFuncCall::AND { lhs, rhs, output: _, num_bits: _ }
343 | BlackBoxFuncCall::XOR { lhs, rhs, output: _, num_bits: _ } => {
344 vec![*lhs, *rhs]
345 }
346 BlackBoxFuncCall::RANGE { input, num_bits: _ } => vec![*input],
347
348 BlackBoxFuncCall::MultiScalarMul { points, scalars, predicate, outputs: _ } => {
349 [points.as_slice(), scalars.as_slice(), &[*predicate]].concat()
350 }
351 BlackBoxFuncCall::EmbeddedCurveAdd { input1, input2, predicate, outputs: _ } => {
352 vec![input1[0], input1[1], input1[2], input2[0], input2[1], input2[2], *predicate]
353 }
354 BlackBoxFuncCall::EcdsaSecp256k1 {
355 public_key_x,
356 public_key_y,
357 signature,
358 hashed_message,
359 predicate,
360 output: _,
361 } => [
362 public_key_x.as_slice(),
363 public_key_y.as_slice(),
364 signature.as_slice(),
365 hashed_message.as_slice(),
366 &[*predicate],
367 ]
368 .concat(),
369 BlackBoxFuncCall::EcdsaSecp256r1 {
370 public_key_x,
371 public_key_y,
372 signature,
373 hashed_message,
374 predicate,
375 output: _,
376 } => [
377 public_key_x.as_slice(),
378 public_key_y.as_slice(),
379 signature.as_slice(),
380 hashed_message.as_slice(),
381 &[*predicate],
382 ]
383 .concat(),
384 BlackBoxFuncCall::RecursiveAggregation {
385 verification_key: key,
386 proof,
387 public_inputs,
388 key_hash,
389 proof_type: _,
390 predicate,
391 } => [key.as_slice(), proof, public_inputs, &[*key_hash], &[*predicate]].concat(),
392 }
393 }
394
395 pub fn get_input_witnesses(&self) -> BTreeSet<Witness> {
396 let mut result = BTreeSet::new();
397 for input in self.get_inputs_vec() {
398 if let FunctionInput::Witness(w) = input {
399 result.insert(w);
400 }
401 }
402 result
403 }
404
405 pub fn get_predicate(&self) -> Option<Witness> {
406 let predicate = match self {
407 BlackBoxFuncCall::AES128Encrypt { .. }
408 | BlackBoxFuncCall::AND { .. }
409 | BlackBoxFuncCall::XOR { .. }
410 | BlackBoxFuncCall::RANGE { .. }
411 | BlackBoxFuncCall::Blake2s { .. }
412 | BlackBoxFuncCall::Blake3 { .. }
413 | BlackBoxFuncCall::Keccakf1600 { .. }
414 | BlackBoxFuncCall::Poseidon2Permutation { .. }
415 | BlackBoxFuncCall::Sha256Compression { .. } => FunctionInput::Constant(F::one()),
416 BlackBoxFuncCall::EcdsaSecp256k1 { predicate, .. }
417 | BlackBoxFuncCall::EcdsaSecp256r1 { predicate, .. }
418 | BlackBoxFuncCall::MultiScalarMul { predicate, .. }
419 | BlackBoxFuncCall::EmbeddedCurveAdd { predicate, .. }
420 | BlackBoxFuncCall::RecursiveAggregation { predicate, .. } => *predicate,
421 };
422 if predicate.is_constant() { None } else { Some(predicate.to_witness()) }
423 }
424}
425
426impl<F: std::fmt::Display + Copy> std::fmt::Display for BlackBoxFuncCall<F> {
427 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
428 let uppercase_name = self.name().to_uppercase();
429 write!(f, "BLACKBOX::{uppercase_name} ")?;
430
431 match self {
432 BlackBoxFuncCall::AES128Encrypt { inputs, iv, key, outputs } => {
433 let inputs = slice_to_string(inputs);
434 let iv = slice_to_string(&iv.to_vec());
435 let key = slice_to_string(&key.to_vec());
436 let outputs = slice_to_string(outputs);
437 write!(f, "inputs: {inputs}, iv: {iv}, key: {key}, outputs: {outputs}")?;
438 }
439 BlackBoxFuncCall::AND { lhs, rhs, num_bits, output }
440 | BlackBoxFuncCall::XOR { lhs, rhs, num_bits, output } => {
441 write!(f, "lhs: {lhs}, rhs: {rhs}, output: {output}, bits: {num_bits}")?;
442 }
443 BlackBoxFuncCall::RANGE { input, num_bits } => {
444 write!(f, "input: {input}, bits: {num_bits}")?;
445 }
446 BlackBoxFuncCall::Blake2s { inputs, outputs }
447 | BlackBoxFuncCall::Blake3 { inputs, outputs } => {
448 let inputs = slice_to_string(inputs);
449 let outputs = slice_to_string(&outputs.to_vec());
450 write!(f, "inputs: {inputs}, outputs: {outputs}")?;
451 }
452 BlackBoxFuncCall::EcdsaSecp256k1 {
453 public_key_x,
454 public_key_y,
455 signature,
456 hashed_message,
457 predicate,
458 output,
459 }
460 | BlackBoxFuncCall::EcdsaSecp256r1 {
461 public_key_x,
462 public_key_y,
463 signature,
464 hashed_message,
465 predicate,
466 output,
467 } => {
468 let public_key_x = slice_to_string(&public_key_x.to_vec());
469 let public_key_y = slice_to_string(&public_key_y.to_vec());
470 let signature = slice_to_string(&signature.to_vec());
471 let hashed_message = slice_to_string(&hashed_message.to_vec());
472 write!(
473 f,
474 "public_key_x: {public_key_x}, public_key_y: {public_key_y}, signature: {signature}, hashed_message: {hashed_message}, predicate: {predicate}, output: {output}"
475 )?;
476 }
477 BlackBoxFuncCall::MultiScalarMul { points, scalars, predicate, outputs } => {
478 let points = slice_to_string(points);
479 let scalars = slice_to_string(scalars);
480 write!(
481 f,
482 "points: {points}, scalars: {scalars}, predicate: {predicate}, outputs: [{}, {}, {}]",
483 outputs.0, outputs.1, outputs.2
484 )?;
485 }
486 BlackBoxFuncCall::EmbeddedCurveAdd { input1, input2, predicate, outputs } => {
487 let input1 = slice_to_string(&input1.to_vec());
488 let input2 = slice_to_string(&input2.to_vec());
489 write!(
490 f,
491 "input1: {input1}, input2: {input2}, predicate: {predicate}, outputs: [{}, {}, {}]",
492 outputs.0, outputs.1, outputs.2
493 )?;
494 }
495 BlackBoxFuncCall::Keccakf1600 { inputs, outputs } => {
496 let inputs = slice_to_string(&inputs.to_vec());
497 let outputs = slice_to_string(&outputs.to_vec());
498 write!(f, "inputs: {inputs}, outputs: {outputs}")?;
499 }
500 BlackBoxFuncCall::RecursiveAggregation {
501 verification_key,
502 proof,
503 public_inputs,
504 key_hash,
505 proof_type,
506 predicate,
507 } => {
508 let verification_key = slice_to_string(verification_key);
509 let proof = slice_to_string(proof);
510 let public_inputs = slice_to_string(public_inputs);
511 write!(
512 f,
513 "verification_key: {verification_key}, proof: {proof}, public_inputs: {public_inputs}, key_hash: {key_hash}, proof_type: {proof_type}, predicate: {predicate}"
514 )?;
515 }
516 BlackBoxFuncCall::Poseidon2Permutation { inputs, outputs } => {
517 let inputs = slice_to_string(inputs);
518 let outputs = slice_to_string(outputs);
519 write!(f, "inputs: {inputs}, outputs: {outputs}")?;
520 }
521 BlackBoxFuncCall::Sha256Compression { inputs, hash_values, outputs } => {
522 let inputs = slice_to_string(&inputs.to_vec());
523 let hash_values = slice_to_string(&hash_values.to_vec());
524 let outputs = slice_to_string(&outputs.to_vec());
525 write!(f, "inputs: {inputs}, hash_values: {hash_values}, outputs: {outputs}")?;
526 }
527 }
528
529 Ok(())
530 }
531}
532
533fn slice_to_string<D: std::fmt::Display>(inputs: &[D]) -> String {
534 let inputs = inputs.iter().map(|i| i.to_string()).collect::<Vec<String>>().join(", ");
535 format!("[{inputs}]")
536}
537
538impl<F: std::fmt::Display + Copy> std::fmt::Debug for BlackBoxFuncCall<F> {
539 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
540 std::fmt::Display::fmt(self, f)
541 }
542}
543
544fn serialize_big_array<S, F: Serialize>(
545 big_array: &[FunctionInput<F>; 64],
546 s: S,
547) -> Result<S::Ok, S::Error>
548where
549 S: Serializer,
550{
551 use serde_big_array::BigArray;
552
553 (*big_array).serialize(s)
554}
555
556fn deserialize_big_array_into_box<'de, D, F: Deserialize<'de>>(
557 deserializer: D,
558) -> Result<Box<[FunctionInput<F>; 64]>, D::Error>
559where
560 D: Deserializer<'de>,
561{
562 use serde_big_array::BigArray;
563
564 let big_array: [FunctionInput<F>; 64] = BigArray::deserialize(deserializer)?;
565 Ok(Box::new(big_array))
566}
567
568#[cfg(test)]
569mod tests {
570
571 use crate::{circuit::Opcode, native_types::Witness};
572 use acir_field::{AcirField, FieldElement};
573
574 use super::{BlackBoxFuncCall, FunctionInput};
575
576 fn keccakf1600_opcode<F: AcirField>() -> Opcode<F> {
577 let inputs: Box<[FunctionInput<F>; 25]> =
578 Box::new(std::array::from_fn(|i| FunctionInput::Witness(Witness(i as u32 + 1))));
579 let outputs: Box<[Witness; 25]> = Box::new(std::array::from_fn(|i| Witness(i as u32 + 26)));
580
581 Opcode::BlackBoxFuncCall(BlackBoxFuncCall::Keccakf1600 { inputs, outputs })
582 }
583
584 #[test]
585 fn keccakf1600_serialization_roundtrip() {
586 use crate::serialization::{msgpack_deserialize, msgpack_serialize};
587
588 let opcode = keccakf1600_opcode::<FieldElement>();
589 let buf = msgpack_serialize(&opcode, true).unwrap();
590 let recovered_opcode = msgpack_deserialize(&buf).unwrap();
591 assert_eq!(opcode, recovered_opcode);
592 }
593}
594
595#[cfg(feature = "arb")]
596mod arb {
597 use acir_field::AcirField;
598 use proptest::prelude::*;
599
600 use crate::native_types::Witness;
601
602 use super::{BlackBoxFuncCall, FunctionInput};
603
604 impl<F> Arbitrary for BlackBoxFuncCall<F>
606 where
607 F: AcirField + Arbitrary,
608 {
609 type Parameters = ();
610 type Strategy = BoxedStrategy<Self>;
611
612 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
613 let input = any::<FunctionInput<F>>();
614 let input_vec = any::<Vec<FunctionInput<F>>>();
615 let input_arr_3 = any::<Box<[FunctionInput<F>; 3]>>();
616 let input_arr_8 = any::<Box<[FunctionInput<F>; 8]>>();
617 let input_arr_16 = any::<Box<[FunctionInput<F>; 16]>>();
618 let input_arr_25 = any::<Box<[FunctionInput<F>; 25]>>();
619 let input_arr_32 = any::<Box<[FunctionInput<F>; 32]>>();
620 let input_arr_64 = any::<Box<[FunctionInput<F>; 64]>>();
621 let witness = any::<Witness>();
622 let witness_vec = any::<Vec<Witness>>();
623 let witness_arr_8 = any::<Box<[Witness; 8]>>();
624 let witness_arr_25 = any::<Box<[Witness; 25]>>();
625 let witness_arr_32 = any::<Box<[Witness; 32]>>();
626
627 let witness_arr_16 = any::<Box<[Witness; 16]>>();
630 let case_aes128_encrypt =
631 (input_arr_16.clone(), input_arr_16.clone(), input_arr_16.clone(), witness_arr_16)
632 .prop_map(|(inputs, iv, key, outputs)| BlackBoxFuncCall::AES128Encrypt {
633 inputs: inputs.to_vec(),
634 iv,
635 key,
636 outputs: outputs.to_vec(),
637 });
638
639 let case_and = (input_arr_3.clone(), input_arr_8.clone(), witness.clone()).prop_map(
640 |(lhs, rhs, output)| BlackBoxFuncCall::AND {
641 lhs: lhs[0],
642 rhs: rhs[1],
643 num_bits: 8,
644 output,
645 },
646 );
647
648 let case_xor = (input_arr_3.clone(), input_arr_8.clone(), witness.clone()).prop_map(
649 |(lhs, rhs, output)| BlackBoxFuncCall::XOR {
650 lhs: lhs[0],
651 rhs: rhs[1],
652 num_bits: 8,
653 output,
654 },
655 );
656
657 let case_range = witness.clone().prop_map(|witness| BlackBoxFuncCall::RANGE {
658 input: FunctionInput::Witness(witness),
659 num_bits: 32,
660 });
661
662 let case_blake2s =
663 (input_arr_8.clone(), witness_arr_32.clone()).prop_map(|(inputs, outputs)| {
664 BlackBoxFuncCall::Blake2s { inputs: inputs.to_vec(), outputs }
665 });
666
667 let case_blake3 =
668 (input_arr_8.clone(), witness_arr_32.clone()).prop_map(|(inputs, outputs)| {
669 BlackBoxFuncCall::Blake3 { inputs: inputs.to_vec(), outputs }
670 });
671
672 let case_ecdsa_secp256k1 = (
673 input_arr_32.clone(),
674 input_arr_32.clone(),
675 input_arr_64.clone(),
676 input_arr_32.clone(),
677 witness.clone(),
678 input.clone(),
679 )
680 .prop_map(
681 |(public_key_x, public_key_y, signature, hashed_message, output, predicate)| {
682 BlackBoxFuncCall::EcdsaSecp256k1 {
683 public_key_x,
684 public_key_y,
685 signature,
686 hashed_message,
687 output,
688 predicate,
689 }
690 },
691 );
692
693 let case_ecdsa_secp256r1 = (
694 input_arr_32.clone(),
695 input_arr_32.clone(),
696 input_arr_64.clone(),
697 input_arr_32.clone(),
698 witness.clone(),
699 input.clone(),
700 )
701 .prop_map(
702 |(public_key_x, public_key_y, signature, hashed_message, output, predicate)| {
703 BlackBoxFuncCall::EcdsaSecp256r1 {
704 public_key_x,
705 public_key_y,
706 signature,
707 hashed_message,
708 output,
709 predicate,
710 }
711 },
712 );
713
714 let case_multi_scalar_mul = (
715 input_vec.clone(),
716 input_vec.clone(),
717 input.clone(),
718 witness.clone(),
719 witness.clone(),
720 witness.clone(),
721 )
722 .prop_map(|(points, scalars, predicate, w1, w2, w3)| {
723 BlackBoxFuncCall::MultiScalarMul {
724 points,
725 scalars,
726 predicate,
727 outputs: (w1, w2, w3),
728 }
729 });
730
731 let case_embedded_curve_add = (
732 input_arr_3.clone(),
733 input_arr_3.clone(),
734 input.clone(),
735 witness.clone(),
736 witness.clone(),
737 witness.clone(),
738 )
739 .prop_map(|(input1, input2, predicate, w1, w2, w3)| {
740 BlackBoxFuncCall::EmbeddedCurveAdd {
741 input1,
742 input2,
743 predicate,
744 outputs: (w1, w2, w3),
745 }
746 });
747
748 let case_keccakf1600 = (input_arr_25.clone(), witness_arr_25.clone())
749 .prop_map(|(inputs, outputs)| BlackBoxFuncCall::Keccakf1600 { inputs, outputs });
750
751 let case_recursive_aggregation = (
752 input_vec.clone(),
753 input_vec.clone(),
754 input_vec.clone(),
755 input.clone(),
756 any::<u32>(),
757 input.clone(),
758 )
759 .prop_map(
760 |(verification_key, proof, public_inputs, key_hash, proof_type, predicate)| {
761 BlackBoxFuncCall::RecursiveAggregation {
762 verification_key,
763 proof,
764 public_inputs,
765 key_hash,
766 proof_type,
767 predicate,
768 }
769 },
770 );
771
772 let case_poseidon2_permutation =
773 (input_vec.clone(), witness_vec.clone()).prop_map(|(inputs, outputs)| {
774 BlackBoxFuncCall::Poseidon2Permutation { inputs, outputs }
775 });
776
777 let case_sha256_compression = (input_arr_16, input_arr_8, witness_arr_8).prop_map(
778 |(inputs, hash_values, outputs)| BlackBoxFuncCall::Sha256Compression {
779 inputs,
780 hash_values,
781 outputs,
782 },
783 );
784
785 prop_oneof![
786 case_aes128_encrypt,
787 case_and,
788 case_xor,
789 case_range,
790 case_blake2s,
791 case_blake3,
792 case_ecdsa_secp256k1,
793 case_ecdsa_secp256r1,
794 case_multi_scalar_mul,
795 case_embedded_curve_add,
796 case_keccakf1600,
797 case_recursive_aggregation,
798 case_poseidon2_permutation,
799 case_sha256_compression,
800 ]
801 .boxed()
802 }
803 }
804}