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}
235
236#[derive(Clone, Debug, Serialize, Deserialize)]
238#[serde(bound = "F: Field")]
239pub struct MPCCircuitsAndConstData<F: Field> {
240 pub mpc_circuit: Circuit<F>,
241 pub encoding_matrix: MultilinearExtension<F>,
242 pub evaluation_points: [MultilinearExtension<F>; 3],
243}
244
245#[derive(Serialize, Deserialize)]
246pub struct MPCProver {
247 #[serde(skip)]
248 #[serde(default = "V3Prover::default_committer")]
249 committer: PedersenCommitter<Bn256Point>,
250
251 #[serde(skip)]
252 #[serde(default = "VandermondeInverse::new")]
253 converter: VandermondeInverse<Scalar>,
254
255 slope_commitments: [HyraxProverInputCommitment<Bn256Point>; 2],
256
257 prover_config: GKRCircuitProverConfig,
258 mpc_circuit_and_const_mles_all_3_parties: MPCCircuitsAndConstData<Fr>,
259
260 left_eye_proofs_all_3_parties: Option<Vec<HyraxProof<Bn256Point>>>,
261 right_eye_proofs_all_3_parties: Option<Vec<HyraxProof<Bn256Point>>>,
262}
263
264impl MPCProver {
265 fn generate_secure_shamir_secret_share_slopes_and_commitments<C: PrimeOrderCurve>(
271 num_vars: usize,
272 log_num_cols: usize,
273 pedersen_committer: &PedersenCommitter<C>,
274 rng: &mut impl Rng,
275 ) -> HyraxProverInputCommitment<C> {
276 let slopes_mle = MultilinearExtension::new(
278 (0..IRISCODE_LEN)
279 .map(|_idx| C::Scalar::from(rng.gen_range(0..GR4_MODULUS)))
280 .collect_vec(),
281 );
282
283 commit_to_input_values(num_vars, log_num_cols, &slopes_mle, pedersen_committer, rng)
284 }
285
286 pub fn default_committer() -> PedersenCommitter<Bn256Point> {
287 PedersenCommitter::new(512, PUBLIC_STRING, None)
288 }
289
290 pub fn new(
291 prover_config: GKRCircuitProverConfig,
292 mpc_circuit_and_aux_mles_all_3_parties: MPCCircuitsAndConstData<Fr>,
293 rng: &mut (impl CryptoRng + RngCore),
294 ) -> Self {
295 let circuit = &mpc_circuit_and_aux_mles_all_3_parties.mpc_circuit;
303 assert!(!circuit
304 .input_layer_contains_data(MPC_AUXILIARY_LAYER)
305 .unwrap());
306 assert!(!circuit
307 .input_layer_contains_data(MPC_AUXILIARY_INVARIANT_LAYER)
308 .unwrap());
309 assert!(!circuit.input_layer_contains_data(MPC_SHARES_LAYER).unwrap());
310 assert!(!circuit.input_layer_contains_data(MPC_SLOPES_LAYER).unwrap());
311 assert!(!circuit
312 .input_layer_contains_data(MPC_IRISCODE_INPUT_LAYER)
313 .unwrap());
314 assert!(!circuit
315 .input_layer_contains_data(MPC_MASKCODE_INPUT_LAYER)
316 .unwrap());
317
318 let committer = Self::default_committer();
319
320 let slope_input_layer_description = &mpc_circuit_and_aux_mles_all_3_parties
321 .mpc_circuit
322 .get_input_layer_description_ref(MPC_SLOPES_LAYER)
323 .clone();
324
325 let slopes_precommitment_left_eye =
326 Self::generate_secure_shamir_secret_share_slopes_and_commitments(
327 slope_input_layer_description.num_vars,
328 SHAMIR_SECRET_SHARE_SLOPE_LOG_NUM_COLS,
329 &committer,
330 rng,
331 );
332 let slopes_precommitment_right_eye =
333 Self::generate_secure_shamir_secret_share_slopes_and_commitments(
334 slope_input_layer_description.num_vars,
335 SHAMIR_SECRET_SHARE_SLOPE_LOG_NUM_COLS,
336 &committer,
337 rng,
338 );
339
340 Self {
341 committer,
342 converter: VandermondeInverse::new(),
343 slope_commitments: [
344 slopes_precommitment_left_eye,
345 slopes_precommitment_right_eye,
346 ],
347 prover_config,
348 mpc_circuit_and_const_mles_all_3_parties: mpc_circuit_and_aux_mles_all_3_parties,
349 left_eye_proofs_all_3_parties: None,
350 right_eye_proofs_all_3_parties: None,
351 }
352 }
353
354 pub fn get_committer_ref(&self) -> &PedersenCommitter<Bn256Point> {
355 &self.committer
356 }
357
358 #[allow(clippy::too_many_arguments)]
359 pub fn prove_mpc_with_precommits(
360 mut mpc_provable_circuit: HyraxProvableCircuit<Bn256Point>,
361 iris_precommit: &HyraxProverInputCommitment<Bn256Point>,
362 mask_precommit: &HyraxProverInputCommitment<Bn256Point>,
363 slope_precommit: &HyraxProverInputCommitment<Bn256Point>,
364 committer: &PedersenCommitter<Bn256Point>,
365 blinding_rng: &mut (impl CryptoRng + RngCore),
366 converter: &mut VandermondeInverse<Scalar>,
367 ) -> HyraxProof<Bn256Point> {
368 mpc_provable_circuit
369 .set_pre_commitment(MPC_IRISCODE_INPUT_LAYER, iris_precommit.clone(), None)
370 .unwrap();
371 mpc_provable_circuit
372 .set_pre_commitment(MPC_MASKCODE_INPUT_LAYER, mask_precommit.clone(), None)
373 .unwrap();
374 mpc_provable_circuit
375 .set_pre_commitment(
376 MPC_SLOPES_LAYER,
377 slope_precommit.clone(),
378 Some(SHAMIR_SECRET_SHARE_SLOPE_LOG_NUM_COLS),
379 )
380 .unwrap();
381
382 let mut transcript: ECTranscript<Bn256Point, PoseidonSponge<Base>> =
384 ECTranscript::new("MPC Circuit Pipeline");
385
386 let (proof, _proof_config) =
388 mpc_provable_circuit.prove(committer, blinding_rng, converter, &mut transcript);
389
390 proof
391 }
392
393 pub fn prove(
394 &mut self,
395 is_left_eye: bool,
396 iris_code_precommit: HyraxProverInputCommitment<Bn256Point>,
397 mask_code_precommit: HyraxProverInputCommitment<Bn256Point>,
398 rng: &mut (impl CryptoRng + RngCore),
399 ) {
400 assert_eq!(
401 iris_code_precommit.blinding_factors_matrix.len(),
402 iris_code_precommit.commitment.len()
403 );
404
405 let iris_code_mle = &iris_code_precommit.mle;
406 let mask_code_mle = &mask_code_precommit.mle;
407 let slope_commitment = &self.slope_commitments[!is_left_eye as usize];
408
409 let encoding_matrix = &self
410 .mpc_circuit_and_const_mles_all_3_parties
411 .encoding_matrix;
412
413 let lookup_table_values =
414 MultilinearExtension::new((0..GR4_MODULUS).map(Fr::from).collect());
415
416 let proofs_all_3_parties: Vec<_> = (0..3)
417 .map(|party_idx| {
418 let mut circuit = self
419 .mpc_circuit_and_const_mles_all_3_parties
420 .mpc_circuit
421 .clone();
422
423 let evaluation_points = &self
424 .mpc_circuit_and_const_mles_all_3_parties
425 .evaluation_points[party_idx];
426
427 let input_data = gen_mpc_input_data::<Fr, MPC_NUM_IRIS_4_CHUNKS>(
428 iris_code_mle,
429 mask_code_mle,
430 &slope_commitment.mle,
431 encoding_matrix,
432 evaluation_points,
433 );
434 let const_data = MPCCircuitConstData {
435 encoding_matrix: encoding_matrix.clone(),
436 evaluation_points: evaluation_points.clone(),
437 lookup_table_values: lookup_table_values.clone(),
438 };
439
440 mpc_attach_data(&mut circuit, const_data, input_data);
441
442 let provable_circuit = circuit
443 .gen_hyrax_provable_circuit()
444 .expect("Failed to finalize circuit");
445
446 Self::prove_mpc_with_precommits(
447 provable_circuit,
448 &iris_code_precommit,
449 &mask_code_precommit,
450 slope_commitment,
451 &self.committer,
452 rng,
453 &mut self.converter,
454 )
455 })
456 .collect();
457
458 self.set(is_left_eye, proofs_all_3_parties);
459 }
460
461 pub fn set(&mut self, is_left_eye: bool, proofs_all_3_parties: Vec<HyraxProof<Bn256Point>>) {
464 match is_left_eye {
465 false => self.set_right_proof(proofs_all_3_parties),
466 true => self.set_left_proof(proofs_all_3_parties),
467 }
468 }
469
470 pub fn set_left_proof(&mut self, proofs_all_3_parties: Vec<HyraxProof<Bn256Point>>) {
472 self.left_eye_proofs_all_3_parties = Some(proofs_all_3_parties)
473 }
474
475 pub fn set_right_proof(&mut self, proofs_all_3_parties: Vec<HyraxProof<Bn256Point>>) {
477 self.right_eye_proofs_all_3_parties = Some(proofs_all_3_parties)
478 }
479
480 pub fn is_set(&self, is_left_eye: bool) -> bool {
481 match is_left_eye {
482 true => {
483 self.left_eye_proofs_all_3_parties.is_some()
484 && self.left_eye_proofs_all_3_parties.as_ref().unwrap().len() == 3
485 }
486 false => {
487 self.right_eye_proofs_all_3_parties.is_some()
488 && self.right_eye_proofs_all_3_parties.as_ref().unwrap().len() == 3
489 }
490 }
491 }
492
493 fn is_ready_to_finalize(&self) -> bool {
496 self.is_set(true) && self.is_set(false)
497 }
498
499 pub fn finalize(&self) -> Result<MPCProof, MPCProofError> {
500 if self.is_ready_to_finalize() {
501 let proof_config = ProofConfig::new_from_prover_config(&self.prover_config);
502
503 Ok(MPCProof::new(
504 proof_config,
505 self.left_eye_proofs_all_3_parties.as_ref().unwrap().clone(),
506 self.right_eye_proofs_all_3_parties
507 .as_ref()
508 .unwrap()
509 .clone(),
510 ))
511 } else {
512 Err(MPCProofError::EmptyProofField)
513 }
514 }
515}
516
517#[derive(Serialize, Deserialize)]
521pub struct V3MPCProver {
522 v3_prover: V3Prover,
524
525 mpc_prover: MPCProver,
527
528 left_iris_commit: Option<HyraxProverInputCommitment<Bn256Point>>,
530 left_mask_commit: Option<HyraxProverInputCommitment<Bn256Point>>,
531 right_iris_commit: Option<HyraxProverInputCommitment<Bn256Point>>,
532 right_mask_commit: Option<HyraxProverInputCommitment<Bn256Point>>,
533}
534
535impl V3MPCProver {
536 pub fn new(
538 prover_config: GKRCircuitProverConfig,
539 iris_circuit: V3CircuitAndAuxData<Fr>,
540 mpc_circuits: MPCCircuitsAndConstData<Fr>,
541 rng: &mut (impl CryptoRng + RngCore),
542 ) -> Self {
543 Self {
544 v3_prover: V3Prover::new(prover_config.clone(), iris_circuit),
545 mpc_prover: MPCProver::new(prover_config, mpc_circuits, rng),
546
547 left_iris_commit: None,
548 left_mask_commit: None,
549 right_iris_commit: None,
550 right_mask_commit: None,
551 }
552 }
553
554 pub fn prove_v3(
555 &mut self,
556 is_mask: bool,
557 is_left_eye: bool,
558 image_bytes: Vec<u8>,
559 image_precommit: HyraxProverInputCommitment<Bn256Point>,
560 rng: &mut (impl CryptoRng + RngCore),
561 ) {
562 let code_commitment =
563 self.v3_prover
564 .prove(is_mask, is_left_eye, image_bytes, image_precommit, rng);
565
566 self.set_commit(is_mask, is_left_eye, code_commitment);
567
568 }
573
574 pub fn prove_mpc(&mut self, is_left_eye: bool, rng: &mut (impl CryptoRng + RngCore)) {
575 let iris_code_commitment = self.get_commit(false, is_left_eye).clone();
576 let mask_code_commitment = self.get_commit(true, is_left_eye).clone();
577
578 self.mpc_prover
579 .prove(is_left_eye, iris_code_commitment, mask_code_commitment, rng);
580
581 }
586
587 pub fn finalize(&self) -> Result<V3MPCProof, V3MPCProofError> {
588 let v3_proof = self.v3_prover.finalize()?;
589 let mpc_proof = self.mpc_prover.finalize()?;
590 let commitments = V3MPCCommitments::new(
591 self.get_commit_left_iris().commitment.clone(),
592 self.get_commit_left_mask().commitment.clone(),
593 self.get_commit_right_iris().commitment.clone(),
594 self.get_commit_right_mask().commitment.clone(),
595 self.mpc_prover.slope_commitments[0].commitment.clone(),
596 self.mpc_prover.slope_commitments[1].commitment.clone(),
597 );
598
599 Ok(V3MPCProof {
600 commitments,
601 v3_proof,
602 mpc_proof,
603 })
604 }
605
606 pub fn set_commit(
609 &mut self,
610 is_mask: bool,
611 is_left_eye: bool,
612 commitment: HyraxProverInputCommitment<Bn256Point>,
613 ) {
614 match (is_mask, is_left_eye) {
615 (false, false) => self.set_commit_right_iris(commitment),
616 (false, true) => self.set_commit_left_iris(commitment),
617 (true, false) => self.set_commit_right_mask(commitment),
618 (true, true) => self.set_commit_left_mask(commitment),
619 }
620 }
621
622 pub fn set_commit_left_iris(&mut self, commitment: HyraxProverInputCommitment<Bn256Point>) {
624 self.left_iris_commit = Some(commitment)
625 }
626
627 pub fn set_commit_left_mask(&mut self, commitment: HyraxProverInputCommitment<Bn256Point>) {
629 self.left_mask_commit = Some(commitment)
630 }
631
632 pub fn set_commit_right_iris(&mut self, commitment: HyraxProverInputCommitment<Bn256Point>) {
634 self.right_iris_commit = Some(commitment)
635 }
636
637 pub fn set_commit_right_mask(&mut self, commitment: HyraxProverInputCommitment<Bn256Point>) {
639 self.right_mask_commit = Some(commitment)
640 }
641
642 pub fn get_commit(
645 &mut self,
646 is_mask: bool,
647 is_left_eye: bool,
648 ) -> &HyraxProverInputCommitment<Bn256Point> {
649 match (is_mask, is_left_eye) {
650 (false, false) => self.get_commit_right_iris(),
651 (false, true) => self.get_commit_left_iris(),
652 (true, false) => self.get_commit_right_mask(),
653 (true, true) => self.get_commit_left_mask(),
654 }
655 }
656
657 pub fn get_commit_left_iris(&self) -> &HyraxProverInputCommitment<Bn256Point> {
659 self.left_iris_commit.as_ref().unwrap()
660 }
661
662 pub fn get_commit_left_mask(&self) -> &HyraxProverInputCommitment<Bn256Point> {
664 self.left_mask_commit.as_ref().unwrap()
665 }
666
667 pub fn get_commit_right_iris(&self) -> &HyraxProverInputCommitment<Bn256Point> {
669 self.right_iris_commit.as_ref().unwrap()
670 }
671
672 pub fn get_commit_right_mask(&self) -> &HyraxProverInputCommitment<Bn256Point> {
674 self.right_mask_commit.as_ref().unwrap()
675 }
676
677 pub fn serialize(&self) -> Vec<u8> {
678 bincode::serialize(self).expect("Failed to serialize V3MPCProver")
679 }
680
681 pub fn deserialize(bytes: &[u8]) -> Self {
682 bincode::deserialize(bytes).expect("Failed to deserialize V3MPCProver")
683 }
684}
685
686#[derive(Clone, Debug, Serialize, Deserialize)]
687pub struct MPCPartyProof {
688 #[serde(skip)]
689 #[serde(default = "V3Prover::default_committer")]
690 committer: PedersenCommitter<Bn256Point>,
691
692 proof_config: ProofConfig,
693 left_eye_proof: HyraxProof<Bn256Point>,
694 right_eye_proof: HyraxProof<Bn256Point>,
695}
696
697impl MPCPartyProof {
698 pub fn new(
699 proof_config: ProofConfig,
700 left_eye_proof: HyraxProof<Bn256Point>,
701 right_eye_proof: HyraxProof<Bn256Point>,
702 ) -> Self {
703 Self {
704 committer: V3Prover::default_committer(),
705 proof_config,
706 left_eye_proof,
707 right_eye_proof,
708 }
709 }
710
711 #[cfg(feature = "print-trace")]
712 pub fn print_size(&self) {
713 println!("Left eye proof stats:");
714 self.left_eye_proof.print_size();
715
716 println!("Right eye proof stats:");
717 self.right_eye_proof.print_size();
718 }
719
720 pub fn insert_aux_public_data_by_id(
721 &mut self,
722 is_left_eye: bool,
723 aux_mle: &MultilinearExtension<Fr>,
724 id_to_insert: LayerId,
725 ) {
726 if is_left_eye {
727 self.left_eye_proof
728 .insert_aux_public_data_by_id(aux_mle, id_to_insert);
729 } else {
730 self.right_eye_proof
731 .insert_aux_public_data_by_id(aux_mle, id_to_insert);
732 }
733 }
734
735 pub fn verify_mpc_proof(
736 &self,
737 is_left_eye: bool,
738 mpc_circuit: &HyraxVerifiableCircuit<Bn256Point>,
739 secret_share_mle_layer_id: LayerId,
740 ) -> Result<MultilinearExtension<Fr>, MPCError> {
741 let mut transcript: ECTranscript<Bn256Point, PoseidonSponge<Base>> =
743 ECTranscript::new("V3 Iriscode Circuit Pipeline");
744
745 let proof = if is_left_eye {
746 &self.left_eye_proof
747 } else {
748 &self.right_eye_proof
749 };
750
751 verify_hyrax_proof(
753 proof,
754 mpc_circuit,
755 &self.committer,
756 &mut transcript,
757 &self.proof_config,
758 );
759
760 let secret_share_mle_should_be_singleton = proof
762 .public_inputs
763 .iter()
764 .filter(|(input_layer_id, _)| *input_layer_id == secret_share_mle_layer_id)
765 .collect_vec();
766 if secret_share_mle_should_be_singleton.len() != 1 {
767 Err(MPCError::NoSharesInputLayerMle)
768 } else {
769 Ok(secret_share_mle_should_be_singleton[0].clone().1.unwrap())
770 }
771 }
772
773 pub fn get_proof_config_ref(&self) -> &ProofConfig {
774 &self.proof_config
775 }
776
777 pub fn get_left_eye_proof_ref(&self) -> &HyraxProof<Bn256Point> {
778 &self.left_eye_proof
779 }
780
781 pub fn get_right_eye_proof_ref(&self) -> &HyraxProof<Bn256Point> {
782 &self.right_eye_proof
783 }
784
785 pub fn serialize(&self) -> Vec<u8> {
786 bincode::serialize(self).unwrap()
787 }
788
789 pub fn deserialize(serialized_proof: &[u8]) -> Self {
790 bincode::deserialize(serialized_proof).unwrap()
791 }
792}
793
794#[derive(Clone, Debug, Serialize, Deserialize)]
795pub struct MPCProof {
796 party_proofs: [MPCPartyProof; 3],
797}
798
799impl MPCProof {
800 pub fn new(
801 proof_config: ProofConfig,
802 mut left_eye_proofs_all_3_parties: Vec<HyraxProof<Bn256Point>>,
803 mut right_eye_proofs_all_3_parties: Vec<HyraxProof<Bn256Point>>,
804 ) -> Self {
805 assert_eq!(left_eye_proofs_all_3_parties.len(), 3);
806 assert_eq!(right_eye_proofs_all_3_parties.len(), 3);
807
808 let party_2_proof = MPCPartyProof::new(
809 proof_config,
810 left_eye_proofs_all_3_parties.pop().unwrap(),
811 right_eye_proofs_all_3_parties.pop().unwrap(),
812 );
813 let party_1_proof = MPCPartyProof::new(
814 proof_config,
815 left_eye_proofs_all_3_parties.pop().unwrap(),
816 right_eye_proofs_all_3_parties.pop().unwrap(),
817 );
818 let party_0_proof = MPCPartyProof::new(
819 proof_config,
820 left_eye_proofs_all_3_parties.pop().unwrap(),
821 right_eye_proofs_all_3_parties.pop().unwrap(),
822 );
823
824 Self {
825 party_proofs: [party_0_proof, party_1_proof, party_2_proof],
826 }
827 }
828
829 pub fn get_party_proof_ref(&self, party_idx: usize) -> &MPCPartyProof {
830 assert!(party_idx < 3);
831 &self.party_proofs[party_idx]
832 }
833
834 pub fn get(&self, is_left_eye: bool) -> Vec<&HyraxProof<Bn256Point>> {
836 match is_left_eye {
837 true => self.get_left_proof_refs(),
838 false => self.get_right_proof_refs(),
839 }
840 }
841
842 pub fn get_proof_refs_for_party(
844 &self,
845 party_idx: usize,
846 ) -> (&HyraxProof<Bn256Point>, &HyraxProof<Bn256Point>) {
847 assert!(party_idx < 3);
848 (
849 self.party_proofs[party_idx].get_left_eye_proof_ref(),
850 self.party_proofs[party_idx].get_right_eye_proof_ref(),
851 )
852 }
853
854 pub fn get_left_proof_refs(&self) -> Vec<&HyraxProof<Bn256Point>> {
856 vec![
857 self.party_proofs[0].get_left_eye_proof_ref(),
858 self.party_proofs[1].get_left_eye_proof_ref(),
859 self.party_proofs[2].get_left_eye_proof_ref(),
860 ]
861 }
862
863 pub fn get_right_proof_refs(&self) -> Vec<&HyraxProof<Bn256Point>> {
865 vec![
866 self.party_proofs[0].get_right_eye_proof_ref(),
867 self.party_proofs[1].get_right_eye_proof_ref(),
868 self.party_proofs[2].get_right_eye_proof_ref(),
869 ]
870 }
871
872 pub fn serialize(&self) -> Vec<u8> {
874 bincode::serialize(self).unwrap()
875 }
876
877 pub fn deserialize(serialized_proof: &[u8]) -> Self {
879 bincode::deserialize(serialized_proof).unwrap()
880 }
881}
882
883#[derive(Clone, Debug, Serialize, Deserialize)]
884pub struct V3MPCProof {
885 commitments: V3MPCCommitments<Bn256Point>,
886 v3_proof: V3Proof,
887 mpc_proof: MPCProof,
888}
889
890impl V3MPCProof {
891 pub fn get_commitments_ref(&self) -> &V3MPCCommitments<Bn256Point> {
892 &self.commitments
893 }
894
895 pub fn get_v3_proof_ref(&self) -> &V3Proof {
896 &self.v3_proof
897 }
898
899 pub fn get_party_proof_ref(&self, party_idx: usize) -> &MPCPartyProof {
900 self.mpc_proof.get_party_proof_ref(party_idx)
901 }
902
903 pub fn serialize(&self) -> Vec<u8> {
905 bincode::serialize(self).unwrap()
906 }
907
908 pub fn deserialize(serialized_proof: &[u8]) -> Self {
910 bincode::deserialize(serialized_proof).unwrap()
911 }
912}
913
914#[derive(Clone, Debug, Serialize, Deserialize)]
915#[serde(bound = "F: Field")]
916pub struct V3MPCCircuitAndAuxMles<F: Field> {
917 pub v3_circuit_and_aux_data: V3CircuitAndAuxData<F>,
918 pub mpc_circuit_and_aux_mles_all_3_parties: MPCCircuitsAndConstData<F>,
919}
920
921impl<F: Field> V3MPCCircuitAndAuxMles<F> {
922 pub fn serialize(&self) -> Vec<u8> {
923 bincode::serialize(&self).expect("Failed to serialize CircuitAndAuxMles")
924 }
925
926 pub fn deserialize(bytes: &[u8]) -> Self {
927 bincode::deserialize(bytes).expect("Failed to deserialize CircuitAndAuxMles")
928 }
929}
930
931pub fn generate_mpc_circuit_and_aux_mles_all_3_parties<F: Field>() -> MPCCircuitsAndConstData<F> {
933 let mpc_circuit = build_circuit::<F, MPC_NUM_IRIS_4_CHUNKS>(LayerVisibility::Committed);
934
935 MPCCircuitsAndConstData {
936 mpc_circuit,
937 encoding_matrix: gen_mpc_encoding_matrix::<F, MPC_NUM_IRIS_4_CHUNKS>(),
938 evaluation_points: [
939 gen_mpc_evaluation_points::<F, MPC_NUM_IRIS_4_CHUNKS, 0>(),
940 gen_mpc_evaluation_points::<F, MPC_NUM_IRIS_4_CHUNKS, 1>(),
941 gen_mpc_evaluation_points::<F, MPC_NUM_IRIS_4_CHUNKS, 2>(),
942 ],
943 }
944}