1#![allow(clippy::type_complexity)]
2use ark_std::log2;
3use shared_types::Field;
4
5use crate::{
6 hyrax_worldcoin_mpc::mpc_prover::MPCCircuitConstData,
7 layouter::builder::{Circuit, CircuitBuilder, LayerVisibility},
8 worldcoin_mpc::{
9 components::WorldcoinMpcComponents,
10 parameters::{GR4_ELEM_BIT_LENGTH, GR4_MULTIPLICATION_WIRINGS},
11 },
12};
13use remainder::layer::gate::BinaryOperation;
14
15use super::{
16 data::MPCCircuitInputData,
17 parameters::{ENCODING_MATRIX_NUM_VARS_COLS, ENCODING_MATRIX_NUM_VARS_ROWS},
18};
19
20pub const MPC_AUXILIARY_LAYER: &str = "Auxiliary"; pub const MPC_AUXILIARY_INVARIANT_LAYER: &str = "Auxiliary Invariant";
25pub const MPC_SHARES_LAYER: &str = "Shares";
27pub const MPC_SLOPES_LAYER: &str = "Slopes";
29pub const MPC_IRISCODE_INPUT_LAYER: &str = "Iris Code Input";
32pub const MPC_MASKCODE_INPUT_LAYER: &str = "Mask Code Input";
35
36pub const MPC_IRISCODE_SHRED: &str = "Iris Code Input";
37pub const MPC_MASKCODE_SHRED: &str = "Mask Code Input";
38pub const MPC_SLOPES_SHRED: &str = "Slopes";
39pub const MPC_QUOTIENTS_SHRED: &str = "Quotients";
40pub const MPC_SHARES_SHRED: &str = "Shares Reduced Modulo GR4 Modulus";
41pub const MPC_MULTIPLICITIES_SHARES_SHRED: &str = "Multiplicities Shares";
42pub const MPC_MULTIPLICITIES_SLOPES_SHRED: &str = "Multiplicities Slopes";
43pub const MPC_ENCODING_MATRIX_SHRED: &str = "Encoding Matrix";
44pub const MPC_EVALUATION_POINTS_SHRED: &str = "Evaluation Points";
45pub const MPC_LOOKUP_TABLE_VALUES_SHRED: &str = "Lookup Table Values";
46
47pub fn build_circuit<F: Field, const NUM_IRIS_4_CHUNKS: usize>(
57 layer_visibility: LayerVisibility,
58) -> Circuit<F> {
59 let mut builder = CircuitBuilder::<F>::new();
60
61 let num_vars_dataparallel = log2(NUM_IRIS_4_CHUNKS) as usize;
62 let num_vars = num_vars_dataparallel + 2;
65
66 let auxilary_input_layer_node = builder.add_input_layer(MPC_AUXILIARY_LAYER, layer_visibility);
67 let shares_input_layer_node =
68 builder.add_input_layer(MPC_SHARES_LAYER, LayerVisibility::Public);
69 let auxiliary_invariant_public_input_layer_node =
70 builder.add_input_layer(MPC_AUXILIARY_INVARIANT_LAYER, LayerVisibility::Public);
71 let slope_input_layer_node = builder.add_input_layer(MPC_SLOPES_LAYER, layer_visibility);
72 let iris_code_input_layer_node =
73 builder.add_input_layer(MPC_IRISCODE_INPUT_LAYER, layer_visibility);
74 let mask_code_input_layer_node =
75 builder.add_input_layer(MPC_MASKCODE_INPUT_LAYER, layer_visibility);
76
77 let iris_code =
78 builder.add_input_shred(MPC_IRISCODE_SHRED, num_vars, &iris_code_input_layer_node);
79 let mask_code =
80 builder.add_input_shred(MPC_MASKCODE_SHRED, num_vars, &mask_code_input_layer_node);
81 let slopes = builder.add_input_shred(MPC_SLOPES_SHRED, num_vars, &slope_input_layer_node);
82 let quotients =
83 builder.add_input_shred(MPC_QUOTIENTS_SHRED, num_vars, &auxilary_input_layer_node);
84 let shares_reduced_modulo_gr4_modulus =
85 builder.add_input_shred(MPC_SHARES_SHRED, num_vars, &shares_input_layer_node);
86 let multiplicities_shares = builder.add_input_shred(
87 MPC_MULTIPLICITIES_SHARES_SHRED,
88 GR4_ELEM_BIT_LENGTH as usize,
89 &auxilary_input_layer_node,
90 );
91 let multiplicities_slopes = builder.add_input_shred(
92 MPC_MULTIPLICITIES_SLOPES_SHRED,
93 GR4_ELEM_BIT_LENGTH as usize,
94 &auxilary_input_layer_node,
95 );
96
97 let encoding_matrix = builder.add_input_shred(
98 MPC_ENCODING_MATRIX_SHRED,
99 ENCODING_MATRIX_NUM_VARS_ROWS + ENCODING_MATRIX_NUM_VARS_COLS,
100 &auxiliary_invariant_public_input_layer_node,
101 );
102 let evaluation_points = builder.add_input_shred(
103 MPC_EVALUATION_POINTS_SHRED,
104 num_vars,
105 &auxiliary_invariant_public_input_layer_node,
106 );
107
108 let lookup_table_values = builder.add_input_shred(
109 MPC_LOOKUP_TABLE_VALUES_SHRED,
110 GR4_ELEM_BIT_LENGTH as usize,
111 &auxiliary_invariant_public_input_layer_node,
112 );
113 let fiat_shamir_challenge_node = builder.add_fiat_shamir_challenge_node(1);
114 let lookup_table = builder.add_lookup_table(&lookup_table_values, &fiat_shamir_challenge_node);
115
116 let masked_iris_code =
117 WorldcoinMpcComponents::masked_iris_code(&mut builder, &iris_code, &mask_code);
118 let encoded_masked_iris_code = builder.add_matmult_node(
120 &masked_iris_code,
121 (num_vars_dataparallel, ENCODING_MATRIX_NUM_VARS_ROWS),
122 &encoding_matrix,
123 (ENCODING_MATRIX_NUM_VARS_ROWS, ENCODING_MATRIX_NUM_VARS_COLS),
124 );
125
126 let evaluation_points_times_slopes = builder.add_gate_node(
128 &evaluation_points,
129 &slopes,
130 GR4_MULTIPLICATION_WIRINGS.to_vec(),
131 BinaryOperation::Mul,
132 Some(num_vars_dataparallel),
133 );
134
135 let computed_shares = WorldcoinMpcComponents::sum(
136 &mut builder,
137 &encoded_masked_iris_code,
138 &evaluation_points_times_slopes,
139 );
140
141 let _congruence = WorldcoinMpcComponents::congruence(
142 &mut builder,
143 "ients,
144 &computed_shares,
145 &shares_reduced_modulo_gr4_modulus,
146 );
147
148 let _lookup_constraint_shares = builder.add_lookup_constraint(
149 &lookup_table,
150 &shares_reduced_modulo_gr4_modulus,
151 &multiplicities_shares,
152 );
153
154 let _lookup_constraint_slopes =
155 builder.add_lookup_constraint(&lookup_table, &slopes, &multiplicities_slopes);
156
157 builder.build_without_layer_combination().unwrap()
158}
159
160pub fn mpc_attach_data<F: Field>(
164 circuit: &mut Circuit<F>,
165 mpc_aux_data: MPCCircuitConstData<F>,
166 mpc_input_data: MPCCircuitInputData<F>,
167) {
168 circuit.set_input(MPC_IRISCODE_SHRED, mpc_input_data.iris_codes);
169 circuit.set_input(MPC_MASKCODE_SHRED, mpc_input_data.masks);
170 circuit.set_input(MPC_SLOPES_SHRED, mpc_input_data.slopes);
171 circuit.set_input(MPC_QUOTIENTS_SHRED, mpc_input_data.quotients);
172 circuit.set_input(
173 MPC_SHARES_SHRED,
174 mpc_input_data.shares_reduced_modulo_gr4_modulus,
175 );
176 circuit.set_input(
177 MPC_MULTIPLICITIES_SHARES_SHRED,
178 mpc_input_data.multiplicities_shares,
179 );
180 circuit.set_input(
181 MPC_MULTIPLICITIES_SLOPES_SHRED,
182 mpc_input_data.multiplicities_slopes,
183 );
184 circuit.set_input(MPC_ENCODING_MATRIX_SHRED, mpc_aux_data.encoding_matrix);
185 circuit.set_input(MPC_EVALUATION_POINTS_SHRED, mpc_aux_data.evaluation_points);
186 circuit.set_input(
187 MPC_LOOKUP_TABLE_VALUES_SHRED,
188 mpc_aux_data.lookup_table_values,
189 );
190}