1use crate::{
2 hyrax_worldcoin::{
3 orb::PUBLIC_STRING,
4 v3::{V3CircuitAndAuxData, V3Proof, V3ProofError, V3Prover},
5 },
6 layouter::builder::{Circuit, LayerVisibility},
7 worldcoin_mpc::{
8 circuits::{
9 build_circuit, mpc_attach_data, MPC_AUXILIARY_INVARIANT_LAYER, MPC_AUXILIARY_LAYER,
10 MPC_IRISCODE_INPUT_LAYER, MPC_MASKCODE_INPUT_LAYER, MPC_SHARES_LAYER, MPC_SLOPES_LAYER,
11 },
12 data::{gen_mpc_encoding_matrix, gen_mpc_evaluation_points, gen_mpc_input_data},
13 parameters::{GR4_MODULUS, MPC_NUM_IRIS_4_CHUNKS},
14 },
15 zk_iriscode_ss::parameters::{IRISCODE_LEN, SHAMIR_SECRET_SHARE_SLOPE_LOG_NUM_COLS},
16};
17use hyrax::{
18 gkr::{
19 input_layer::{commit_to_input_values, HyraxProverInputCommitment},
20 verify_hyrax_proof, HyraxProof,
21 },
22 provable_circuit::HyraxProvableCircuit,
23 utils::vandermonde::VandermondeInverse,
24 verifiable_circuit::HyraxVerifiableCircuit,
25};
26
27use itertools::Itertools;
28use rand::{CryptoRng, Rng, RngCore};
29use remainder::{layer::LayerId, mle::evals::MultilinearExtension};
30use serde::{Deserialize, Serialize};
31use shared_types::{
32 config::{
33 global_config::{
34 global_prover_claim_agg_constant_column_optimization, global_prover_enable_bit_packing,
35 global_prover_lazy_beta_evals,
36 },
37 GKRCircuitProverConfig, ProofConfig,
38 },
39 curves::PrimeOrderCurve,
40 pedersen::PedersenCommitter,
41 transcript::{ec_transcript::ECTranscript, poseidon_sponge::PoseidonSponge},
42 Base, Bn256Point, Field, Fr, Scalar,
43};
44use thiserror::Error;
45
46#[derive(Debug, Error)]
48pub enum MPCError {
49 #[error("Incorrect MLEs that should be invariant between circuits")]
50 IncorrectInvariantAuxMles,
51 #[error("Couldn't find the shares input layer MLE")]
52 NoSharesInputLayerMle,
53}
54
55#[derive(Error, Debug)]
57pub enum MPCProofError {
58 #[error("Found empty proof field")]
59 EmptyProofField,
60
61 #[error("Verification produced an MPC error")]
62 MPCError(#[from] MPCError),
63}
64
65#[derive(Error, Debug)]
67pub enum V3MPCProofError {
68 #[error("Found empty proof field")]
69 EmptyProofField,
70
71 #[error("Verification produced an V3 error")]
72 V3Error(#[from] V3ProofError),
73
74 #[error("Verification produced an MPC error")]
75 MPCError(#[from] MPCProofError),
76}
77
78pub fn print_features_status() {
79 const STATUS_STR: [&str; 2] = ["OFF", "ON"];
80
81 println!("=== FEATURES ===");
82 println!(
83 "Parallel feature for prover: {}",
84 STATUS_STR[remainder::utils::is_parallel_feature_on() as usize]
85 );
86 println!(
87 "Parallel feature for hyrax: {}",
88 STATUS_STR[hyrax::utils::is_parallel_feature_on() as usize]
89 );
90 println!(
91 "Lazy beta evaluation: {}",
92 STATUS_STR[global_prover_lazy_beta_evals() as usize]
93 );
94 println!(
95 "BitPackedVector: {}",
96 STATUS_STR[global_prover_enable_bit_packing() as usize]
97 );
98 println!(
99 "Claim aggregation constant column optimization for prover: {}",
100 STATUS_STR[global_prover_claim_agg_constant_column_optimization() as usize]
101 );
102 println!("================\n");
103}
104
105#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
106#[serde(bound = "C: PrimeOrderCurve")]
107pub struct V3MPCCommitments<C: PrimeOrderCurve> {
108 left_iris_code: Vec<C>,
109 left_mask_code: Vec<C>,
110 right_iris_code: Vec<C>,
111 right_mask_code: Vec<C>,
112 slope_left_iris_code: Vec<C>,
113 slope_right_iris_code: Vec<C>,
114}
115
116impl<C: PrimeOrderCurve> V3MPCCommitments<C> {
117 pub fn new(
118 left_iris_code: Vec<C>,
119 left_mask_code: Vec<C>,
120 right_iris_code: Vec<C>,
121 right_mask_code: Vec<C>,
122 slope_left_iris_code: Vec<C>,
123 slope_right_iris_code: Vec<C>,
124 ) -> Self {
125 Self {
126 left_iris_code,
127 left_mask_code,
128 right_iris_code,
129 right_mask_code,
130 slope_left_iris_code,
131 slope_right_iris_code,
132 }
133 }
134
135 pub fn get_code_commit_ref(&self, is_mask: bool, is_left_eye: bool) -> &Vec<C> {
136 if is_mask {
137 if is_left_eye {
138 &self.left_mask_code
139 } else {
140 &self.right_mask_code
141 }
142 } else if is_left_eye {
143 &self.left_iris_code
144 } else {
145 &self.right_iris_code
146 }
147 }
148
149 pub fn get_slope_commit_ref(&self, is_left_eye: bool) -> &Vec<C> {
150 if is_left_eye {
151 &self.slope_left_iris_code
152 } else {
153 &self.slope_right_iris_code
154 }
155 }
156
157 pub fn serialize(&self) -> Vec<u8> {
158 bincode::serialize(self).unwrap()
159 }
160
161 pub fn deserialize(bytes: &[u8]) -> Self {
162 bincode::deserialize(bytes).unwrap()
163 }
164}
165
166#[derive(Clone, Debug, Serialize, Deserialize)]
229#[serde(bound = "F: Field")]
230pub struct MPCCircuitConstData<F: Field> {
231 pub encoding_matrix: MultilinearExtension<F>,
232 pub evaluation_points: MultilinearExtension<F>,
233 pub lookup_table_values: MultilinearExtension<F>,
234 pub lookup_table_values_2_19: MultilinearExtension<F>,
235}
236
237#[derive(Clone, Debug, Serialize, Deserialize)]
239#[serde(bound = "F: Field")]
240pub struct MPCCircuitsAndConstData<F: Field> {
241 pub mpc_circuit: Circuit<F>,
242 pub encoding_matrix: MultilinearExtension<F>,
243 pub evaluation_points: [MultilinearExtension<F>; 3],
244}
245
246#[derive(Serialize, Deserialize)]
247pub struct MPCProver {
248 #[serde(skip)]
249 #[serde(default = "MPCProver::default_committer")]
250 committer: PedersenCommitter<Bn256Point>,
251
252 #[serde(skip)]
253 #[serde(default = "VandermondeInverse::new")]
254 converter: VandermondeInverse<Scalar>,
255
256 slope_commitments: [HyraxProverInputCommitment<Bn256Point>; 2],
257
258 prover_config: GKRCircuitProverConfig,
259 mpc_circuit_and_const_mles_all_3_parties: MPCCircuitsAndConstData<Fr>,
260
261 left_eye_proofs_all_3_parties: Option<Vec<HyraxProof<Bn256Point>>>,
262 right_eye_proofs_all_3_parties: Option<Vec<HyraxProof<Bn256Point>>>,
263}
264
265impl MPCProver {
266 fn generate_secure_shamir_secret_share_slopes_and_commitments<C: PrimeOrderCurve>(
272 num_vars: usize,
273 log_num_cols: usize,
274 pedersen_committer: &PedersenCommitter<C>,
275 rng: &mut impl Rng,
276 ) -> HyraxProverInputCommitment<C> {
277 let slopes_mle = MultilinearExtension::new(
279 (0..IRISCODE_LEN)
280 .map(|_idx| C::Scalar::from(rng.gen_range(0..GR4_MODULUS)))
281 .collect_vec(),
282 );
283
284 commit_to_input_values(num_vars, log_num_cols, &slopes_mle, pedersen_committer, rng)
285 }
286
287 pub fn default_committer() -> PedersenCommitter<Bn256Point> {
288 PedersenCommitter::new(1024, PUBLIC_STRING, None)
289 }
290
291 pub fn new(
292 prover_config: GKRCircuitProverConfig,
293 mpc_circuit_and_aux_mles_all_3_parties: MPCCircuitsAndConstData<Fr>,
294 rng: &mut (impl CryptoRng + RngCore),
295 ) -> Self {
296 let circuit = &mpc_circuit_and_aux_mles_all_3_parties.mpc_circuit;
304 assert!(!circuit
305 .input_layer_contains_data(MPC_AUXILIARY_LAYER)
306 .unwrap());
307 assert!(!circuit
308 .input_layer_contains_data(MPC_AUXILIARY_INVARIANT_LAYER)
309 .unwrap());
310 assert!(!circuit.input_layer_contains_data(MPC_SHARES_LAYER).unwrap());
311 assert!(!circuit.input_layer_contains_data(MPC_SLOPES_LAYER).unwrap());
312 assert!(!circuit
313 .input_layer_contains_data(MPC_IRISCODE_INPUT_LAYER)
314 .unwrap());
315 assert!(!circuit
316 .input_layer_contains_data(MPC_MASKCODE_INPUT_LAYER)
317 .unwrap());
318
319 let committer = Self::default_committer();
320
321 let slope_input_layer_description = &mpc_circuit_and_aux_mles_all_3_parties
322 .mpc_circuit
323 .get_input_layer_description_ref(MPC_SLOPES_LAYER)
324 .clone();
325
326 let slopes_precommitment_left_eye =
327 Self::generate_secure_shamir_secret_share_slopes_and_commitments(
328 slope_input_layer_description.num_vars,
329 SHAMIR_SECRET_SHARE_SLOPE_LOG_NUM_COLS,
330 &committer,
331 rng,
332 );
333 let slopes_precommitment_right_eye =
334 Self::generate_secure_shamir_secret_share_slopes_and_commitments(
335 slope_input_layer_description.num_vars,
336 SHAMIR_SECRET_SHARE_SLOPE_LOG_NUM_COLS,
337 &committer,
338 rng,
339 );
340
341 Self {
342 committer,
343 converter: VandermondeInverse::new(),
344 slope_commitments: [
345 slopes_precommitment_left_eye,
346 slopes_precommitment_right_eye,
347 ],
348 prover_config,
349 mpc_circuit_and_const_mles_all_3_parties: mpc_circuit_and_aux_mles_all_3_parties,
350 left_eye_proofs_all_3_parties: None,
351 right_eye_proofs_all_3_parties: None,
352 }
353 }
354
355 pub fn get_committer_ref(&self) -> &PedersenCommitter<Bn256Point> {
356 &self.committer
357 }
358
359 #[allow(clippy::too_many_arguments)]
360 pub fn prove_mpc_with_precommits(
361 mut mpc_provable_circuit: HyraxProvableCircuit<Bn256Point>,
362 iris_precommit: &HyraxProverInputCommitment<Bn256Point>,
363 mask_precommit: &HyraxProverInputCommitment<Bn256Point>,
364 slope_precommit: &HyraxProverInputCommitment<Bn256Point>,
365 committer: &PedersenCommitter<Bn256Point>,
366 blinding_rng: &mut (impl CryptoRng + RngCore),
367 converter: &mut VandermondeInverse<Scalar>,
368 ) -> HyraxProof<Bn256Point> {
369 mpc_provable_circuit
370 .set_pre_commitment(MPC_IRISCODE_INPUT_LAYER, iris_precommit.clone(), None)
371 .unwrap();
372 mpc_provable_circuit
373 .set_pre_commitment(MPC_MASKCODE_INPUT_LAYER, mask_precommit.clone(), None)
374 .unwrap();
375 mpc_provable_circuit
376 .set_pre_commitment(
377 MPC_SLOPES_LAYER,
378 slope_precommit.clone(),
379 Some(SHAMIR_SECRET_SHARE_SLOPE_LOG_NUM_COLS),
380 )
381 .unwrap();
382
383 let mut transcript: ECTranscript<Bn256Point, PoseidonSponge<Base>> =
385 ECTranscript::new("MPC Circuit Pipeline");
386
387 let (proof, _proof_config) =
389 mpc_provable_circuit.prove(committer, blinding_rng, converter, &mut transcript);
390
391 proof
392 }
393
394 pub fn prove(
395 &mut self,
396 is_left_eye: bool,
397 iris_code_precommit: HyraxProverInputCommitment<Bn256Point>,
398 mask_code_precommit: HyraxProverInputCommitment<Bn256Point>,
399 rng: &mut (impl CryptoRng + RngCore),
400 ) {
401 assert_eq!(
402 iris_code_precommit.blinding_factors_matrix.len(),
403 iris_code_precommit.commitment.len()
404 );
405
406 let iris_code_mle = &iris_code_precommit.mle;
407 let mask_code_mle = &mask_code_precommit.mle;
408 let slope_commitment = &self.slope_commitments[!is_left_eye as usize];
409
410 let encoding_matrix = &self
411 .mpc_circuit_and_const_mles_all_3_parties
412 .encoding_matrix;
413
414 let lookup_table_values =
415 MultilinearExtension::new((0..GR4_MODULUS).map(Fr::from).collect());
416 let lookup_table_values_2_19 =
417 MultilinearExtension::new((0..(1 << 19)).map(Fr::from).collect());
418
419 let proofs_all_3_parties: Vec<_> = (0..3)
420 .map(|party_idx| {
421 let mut circuit = self
422 .mpc_circuit_and_const_mles_all_3_parties
423 .mpc_circuit
424 .clone();
425
426 let evaluation_points = &self
427 .mpc_circuit_and_const_mles_all_3_parties
428 .evaluation_points[party_idx];
429
430 let input_data = gen_mpc_input_data::<Fr, MPC_NUM_IRIS_4_CHUNKS>(
431 iris_code_mle,
432 mask_code_mle,
433 &slope_commitment.mle,
434 encoding_matrix,
435 evaluation_points,
436 );
437 let const_data = MPCCircuitConstData {
438 encoding_matrix: encoding_matrix.clone(),
439 evaluation_points: evaluation_points.clone(),
440 lookup_table_values: lookup_table_values.clone(),
441 lookup_table_values_2_19: lookup_table_values_2_19.clone(),
442 };
443
444 mpc_attach_data(&mut circuit, const_data, input_data);
445
446 let provable_circuit = circuit
447 .gen_hyrax_provable_circuit()
448 .expect("Failed to finalize circuit");
449
450 Self::prove_mpc_with_precommits(
451 provable_circuit,
452 &iris_code_precommit,
453 &mask_code_precommit,
454 slope_commitment,
455 &self.committer,
456 rng,
457 &mut self.converter,
458 )
459 })
460 .collect();
461
462 self.set(is_left_eye, proofs_all_3_parties);
463 }
464
465 pub fn set(&mut self, is_left_eye: bool, proofs_all_3_parties: Vec<HyraxProof<Bn256Point>>) {
468 match is_left_eye {
469 false => self.set_right_proof(proofs_all_3_parties),
470 true => self.set_left_proof(proofs_all_3_parties),
471 }
472 }
473
474 pub fn set_left_proof(&mut self, proofs_all_3_parties: Vec<HyraxProof<Bn256Point>>) {
476 self.left_eye_proofs_all_3_parties = Some(proofs_all_3_parties)
477 }
478
479 pub fn set_right_proof(&mut self, proofs_all_3_parties: Vec<HyraxProof<Bn256Point>>) {
481 self.right_eye_proofs_all_3_parties = Some(proofs_all_3_parties)
482 }
483
484 pub fn is_set(&self, is_left_eye: bool) -> bool {
485 match is_left_eye {
486 true => {
487 self.left_eye_proofs_all_3_parties.is_some()
488 && self.left_eye_proofs_all_3_parties.as_ref().unwrap().len() == 3
489 }
490 false => {
491 self.right_eye_proofs_all_3_parties.is_some()
492 && self.right_eye_proofs_all_3_parties.as_ref().unwrap().len() == 3
493 }
494 }
495 }
496
497 fn is_ready_to_finalize(&self) -> bool {
500 self.is_set(true) && self.is_set(false)
501 }
502
503 pub fn finalize(&self) -> Result<MPCProof, MPCProofError> {
504 if self.is_ready_to_finalize() {
505 let proof_config = ProofConfig::new_from_prover_config(&self.prover_config);
506
507 Ok(MPCProof::new(
508 proof_config,
509 self.left_eye_proofs_all_3_parties.as_ref().unwrap().clone(),
510 self.right_eye_proofs_all_3_parties
511 .as_ref()
512 .unwrap()
513 .clone(),
514 ))
515 } else {
516 Err(MPCProofError::EmptyProofField)
517 }
518 }
519}
520
521#[derive(Serialize, Deserialize)]
525pub struct V3MPCProver {
526 v3_prover: V3Prover,
528
529 mpc_prover: MPCProver,
531
532 left_iris_commit: Option<HyraxProverInputCommitment<Bn256Point>>,
534 left_mask_commit: Option<HyraxProverInputCommitment<Bn256Point>>,
535 right_iris_commit: Option<HyraxProverInputCommitment<Bn256Point>>,
536 right_mask_commit: Option<HyraxProverInputCommitment<Bn256Point>>,
537}
538
539impl V3MPCProver {
540 pub fn new(
542 prover_config: GKRCircuitProverConfig,
543 iris_circuit: V3CircuitAndAuxData<Fr>,
544 mpc_circuits: MPCCircuitsAndConstData<Fr>,
545 rng: &mut (impl CryptoRng + RngCore),
546 ) -> Self {
547 Self {
548 v3_prover: V3Prover::new(prover_config.clone(), iris_circuit),
549 mpc_prover: MPCProver::new(prover_config, mpc_circuits, rng),
550
551 left_iris_commit: None,
552 left_mask_commit: None,
553 right_iris_commit: None,
554 right_mask_commit: None,
555 }
556 }
557
558 pub fn prove_v3(
559 &mut self,
560 is_mask: bool,
561 is_left_eye: bool,
562 image_bytes: Vec<u8>,
563 image_precommit: HyraxProverInputCommitment<Bn256Point>,
564 rng: &mut (impl CryptoRng + RngCore),
565 ) {
566 let code_commitment =
567 self.v3_prover
568 .prove(is_mask, is_left_eye, image_bytes, image_precommit, rng);
569
570 self.set_commit(is_mask, is_left_eye, code_commitment);
571
572 }
577
578 pub fn prove_mpc(&mut self, is_left_eye: bool, rng: &mut (impl CryptoRng + RngCore)) {
579 let iris_code_commitment = self.get_commit(false, is_left_eye).clone();
580 let mask_code_commitment = self.get_commit(true, is_left_eye).clone();
581
582 self.mpc_prover
583 .prove(is_left_eye, iris_code_commitment, mask_code_commitment, rng);
584
585 }
590
591 pub fn finalize(&self) -> Result<V3MPCProof, V3MPCProofError> {
592 let v3_proof = self.v3_prover.finalize()?;
593 let mpc_proof = self.mpc_prover.finalize()?;
594 let commitments = V3MPCCommitments::new(
595 self.get_commit_left_iris().commitment.clone(),
596 self.get_commit_left_mask().commitment.clone(),
597 self.get_commit_right_iris().commitment.clone(),
598 self.get_commit_right_mask().commitment.clone(),
599 self.mpc_prover.slope_commitments[0].commitment.clone(),
600 self.mpc_prover.slope_commitments[1].commitment.clone(),
601 );
602
603 Ok(V3MPCProof {
604 commitments,
605 v3_proof,
606 mpc_proof,
607 })
608 }
609
610 pub fn set_commit(
613 &mut self,
614 is_mask: bool,
615 is_left_eye: bool,
616 commitment: HyraxProverInputCommitment<Bn256Point>,
617 ) {
618 match (is_mask, is_left_eye) {
619 (false, false) => self.set_commit_right_iris(commitment),
620 (false, true) => self.set_commit_left_iris(commitment),
621 (true, false) => self.set_commit_right_mask(commitment),
622 (true, true) => self.set_commit_left_mask(commitment),
623 }
624 }
625
626 pub fn set_commit_left_iris(&mut self, commitment: HyraxProverInputCommitment<Bn256Point>) {
628 self.left_iris_commit = Some(commitment)
629 }
630
631 pub fn set_commit_left_mask(&mut self, commitment: HyraxProverInputCommitment<Bn256Point>) {
633 self.left_mask_commit = Some(commitment)
634 }
635
636 pub fn set_commit_right_iris(&mut self, commitment: HyraxProverInputCommitment<Bn256Point>) {
638 self.right_iris_commit = Some(commitment)
639 }
640
641 pub fn set_commit_right_mask(&mut self, commitment: HyraxProverInputCommitment<Bn256Point>) {
643 self.right_mask_commit = Some(commitment)
644 }
645
646 pub fn get_commit(
649 &mut self,
650 is_mask: bool,
651 is_left_eye: bool,
652 ) -> &HyraxProverInputCommitment<Bn256Point> {
653 match (is_mask, is_left_eye) {
654 (false, false) => self.get_commit_right_iris(),
655 (false, true) => self.get_commit_left_iris(),
656 (true, false) => self.get_commit_right_mask(),
657 (true, true) => self.get_commit_left_mask(),
658 }
659 }
660
661 pub fn get_commit_left_iris(&self) -> &HyraxProverInputCommitment<Bn256Point> {
663 self.left_iris_commit.as_ref().unwrap()
664 }
665
666 pub fn get_commit_left_mask(&self) -> &HyraxProverInputCommitment<Bn256Point> {
668 self.left_mask_commit.as_ref().unwrap()
669 }
670
671 pub fn get_commit_right_iris(&self) -> &HyraxProverInputCommitment<Bn256Point> {
673 self.right_iris_commit.as_ref().unwrap()
674 }
675
676 pub fn get_commit_right_mask(&self) -> &HyraxProverInputCommitment<Bn256Point> {
678 self.right_mask_commit.as_ref().unwrap()
679 }
680
681 pub fn serialize(&self) -> Vec<u8> {
682 bincode::serialize(self).expect("Failed to serialize V3MPCProver")
683 }
684
685 pub fn deserialize(bytes: &[u8]) -> Self {
686 bincode::deserialize(bytes).expect("Failed to deserialize V3MPCProver")
687 }
688}
689
690#[derive(Clone, Debug, Serialize, Deserialize)]
691pub struct MPCPartyProof {
692 #[serde(skip)]
693 #[serde(default = "MPCProver::default_committer")]
694 committer: PedersenCommitter<Bn256Point>,
695
696 proof_config: ProofConfig,
697 left_eye_proof: HyraxProof<Bn256Point>,
698 right_eye_proof: HyraxProof<Bn256Point>,
699}
700
701impl MPCPartyProof {
702 pub fn new(
703 proof_config: ProofConfig,
704 left_eye_proof: HyraxProof<Bn256Point>,
705 right_eye_proof: HyraxProof<Bn256Point>,
706 ) -> Self {
707 Self {
708 committer: MPCProver::default_committer(),
709 proof_config,
710 left_eye_proof,
711 right_eye_proof,
712 }
713 }
714
715 #[cfg(feature = "print-trace")]
716 pub fn print_size(&self) {
717 println!("Left eye proof stats:");
718 self.left_eye_proof.print_size();
719
720 println!("Right eye proof stats:");
721 self.right_eye_proof.print_size();
722 }
723
724 pub fn insert_aux_public_data_by_id(
725 &mut self,
726 is_left_eye: bool,
727 aux_mle: &MultilinearExtension<Fr>,
728 id_to_insert: LayerId,
729 ) {
730 if is_left_eye {
731 self.left_eye_proof
732 .insert_aux_public_data_by_id(aux_mle, id_to_insert);
733 } else {
734 self.right_eye_proof
735 .insert_aux_public_data_by_id(aux_mle, id_to_insert);
736 }
737 }
738
739 pub fn verify_mpc_proof(
740 &self,
741 is_left_eye: bool,
742 mpc_circuit: &HyraxVerifiableCircuit<Bn256Point>,
743 secret_share_mle_layer_id: LayerId,
744 ) -> Result<MultilinearExtension<Fr>, MPCError> {
745 let mut transcript: ECTranscript<Bn256Point, PoseidonSponge<Base>> =
747 ECTranscript::new("V3 Iriscode Circuit Pipeline");
748
749 let proof = if is_left_eye {
750 &self.left_eye_proof
751 } else {
752 &self.right_eye_proof
753 };
754
755 verify_hyrax_proof(
757 proof,
758 mpc_circuit,
759 &self.committer,
760 &mut transcript,
761 &self.proof_config,
762 );
763
764 let secret_share_mle_should_be_singleton = proof
766 .public_inputs
767 .iter()
768 .filter(|(input_layer_id, _)| *input_layer_id == secret_share_mle_layer_id)
769 .collect_vec();
770 if secret_share_mle_should_be_singleton.len() != 1 {
771 Err(MPCError::NoSharesInputLayerMle)
772 } else {
773 Ok(secret_share_mle_should_be_singleton[0].clone().1.unwrap())
774 }
775 }
776
777 pub fn get_proof_config_ref(&self) -> &ProofConfig {
778 &self.proof_config
779 }
780
781 pub fn get_left_eye_proof_ref(&self) -> &HyraxProof<Bn256Point> {
782 &self.left_eye_proof
783 }
784
785 pub fn get_right_eye_proof_ref(&self) -> &HyraxProof<Bn256Point> {
786 &self.right_eye_proof
787 }
788
789 pub fn serialize(&self) -> Vec<u8> {
790 bincode::serialize(self).unwrap()
791 }
792
793 pub fn deserialize(serialized_proof: &[u8]) -> Self {
794 bincode::deserialize(serialized_proof).unwrap()
795 }
796}
797
798#[derive(Clone, Debug, Serialize, Deserialize)]
799pub struct MPCProof {
800 party_proofs: [MPCPartyProof; 3],
801}
802
803impl MPCProof {
804 pub fn new(
805 proof_config: ProofConfig,
806 mut left_eye_proofs_all_3_parties: Vec<HyraxProof<Bn256Point>>,
807 mut right_eye_proofs_all_3_parties: Vec<HyraxProof<Bn256Point>>,
808 ) -> Self {
809 assert_eq!(left_eye_proofs_all_3_parties.len(), 3);
810 assert_eq!(right_eye_proofs_all_3_parties.len(), 3);
811
812 let party_2_proof = MPCPartyProof::new(
813 proof_config,
814 left_eye_proofs_all_3_parties.pop().unwrap(),
815 right_eye_proofs_all_3_parties.pop().unwrap(),
816 );
817 let party_1_proof = MPCPartyProof::new(
818 proof_config,
819 left_eye_proofs_all_3_parties.pop().unwrap(),
820 right_eye_proofs_all_3_parties.pop().unwrap(),
821 );
822 let party_0_proof = MPCPartyProof::new(
823 proof_config,
824 left_eye_proofs_all_3_parties.pop().unwrap(),
825 right_eye_proofs_all_3_parties.pop().unwrap(),
826 );
827
828 Self {
829 party_proofs: [party_0_proof, party_1_proof, party_2_proof],
830 }
831 }
832
833 pub fn get_party_proof_ref(&self, party_idx: usize) -> &MPCPartyProof {
834 assert!(party_idx < 3);
835 &self.party_proofs[party_idx]
836 }
837
838 pub fn get(&self, is_left_eye: bool) -> Vec<&HyraxProof<Bn256Point>> {
840 match is_left_eye {
841 true => self.get_left_proof_refs(),
842 false => self.get_right_proof_refs(),
843 }
844 }
845
846 pub fn get_proof_refs_for_party(
848 &self,
849 party_idx: usize,
850 ) -> (&HyraxProof<Bn256Point>, &HyraxProof<Bn256Point>) {
851 assert!(party_idx < 3);
852 (
853 self.party_proofs[party_idx].get_left_eye_proof_ref(),
854 self.party_proofs[party_idx].get_right_eye_proof_ref(),
855 )
856 }
857
858 pub fn get_left_proof_refs(&self) -> Vec<&HyraxProof<Bn256Point>> {
860 vec![
861 self.party_proofs[0].get_left_eye_proof_ref(),
862 self.party_proofs[1].get_left_eye_proof_ref(),
863 self.party_proofs[2].get_left_eye_proof_ref(),
864 ]
865 }
866
867 pub fn get_right_proof_refs(&self) -> Vec<&HyraxProof<Bn256Point>> {
869 vec![
870 self.party_proofs[0].get_right_eye_proof_ref(),
871 self.party_proofs[1].get_right_eye_proof_ref(),
872 self.party_proofs[2].get_right_eye_proof_ref(),
873 ]
874 }
875
876 pub fn serialize(&self) -> Vec<u8> {
878 bincode::serialize(self).unwrap()
879 }
880
881 pub fn deserialize(serialized_proof: &[u8]) -> Self {
883 bincode::deserialize(serialized_proof).unwrap()
884 }
885}
886
887#[derive(Clone, Debug, Serialize, Deserialize)]
888pub struct V3MPCProof {
889 commitments: V3MPCCommitments<Bn256Point>,
890 v3_proof: V3Proof,
891 mpc_proof: MPCProof,
892}
893
894impl V3MPCProof {
895 pub fn get_commitments_ref(&self) -> &V3MPCCommitments<Bn256Point> {
896 &self.commitments
897 }
898
899 pub fn get_v3_proof_ref(&self) -> &V3Proof {
900 &self.v3_proof
901 }
902
903 pub fn get_party_proof_ref(&self, party_idx: usize) -> &MPCPartyProof {
904 self.mpc_proof.get_party_proof_ref(party_idx)
905 }
906
907 pub fn serialize(&self) -> Vec<u8> {
909 bincode::serialize(self).unwrap()
910 }
911
912 pub fn deserialize(serialized_proof: &[u8]) -> Self {
914 bincode::deserialize(serialized_proof).unwrap()
915 }
916}
917
918#[derive(Clone, Debug, Serialize, Deserialize)]
919#[serde(bound = "F: Field")]
920pub struct V3MPCCircuitAndAuxMles<F: Field> {
921 pub v3_circuit_and_aux_data: V3CircuitAndAuxData<F>,
922 pub mpc_circuit_and_aux_mles_all_3_parties: MPCCircuitsAndConstData<F>,
923}
924
925impl<F: Field> V3MPCCircuitAndAuxMles<F> {
926 pub fn serialize(&self) -> Vec<u8> {
927 bincode::serialize(&self).expect("Failed to serialize CircuitAndAuxMles")
928 }
929
930 pub fn deserialize(bytes: &[u8]) -> Self {
931 bincode::deserialize(bytes).expect("Failed to deserialize CircuitAndAuxMles")
932 }
933}
934
935pub fn generate_mpc_circuit_and_aux_mles_all_3_parties<F: Field>() -> MPCCircuitsAndConstData<F> {
937 let mpc_circuit = build_circuit::<F, MPC_NUM_IRIS_4_CHUNKS>(LayerVisibility::Committed);
938
939 MPCCircuitsAndConstData {
940 mpc_circuit,
941 encoding_matrix: gen_mpc_encoding_matrix::<F, MPC_NUM_IRIS_4_CHUNKS>(),
942 evaluation_points: [
943 gen_mpc_evaluation_points::<F, MPC_NUM_IRIS_4_CHUNKS, 0>(),
944 gen_mpc_evaluation_points::<F, MPC_NUM_IRIS_4_CHUNKS, 1>(),
945 gen_mpc_evaluation_points::<F, MPC_NUM_IRIS_4_CHUNKS, 2>(),
946 ],
947 }
948}