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_AUXILIARY_INVARIANT_LAYER_2: &str = "Auxiliary Invariant 2";
26pub const MPC_SHARES_LAYER: &str = "Shares";
28pub const MPC_SLOPES_LAYER: &str = "Slopes";
30pub const MPC_IRISCODE_INPUT_LAYER: &str = "Iris Code Input";
33pub const MPC_MASKCODE_INPUT_LAYER: &str = "Mask Code Input";
36
37pub const MPC_IRISCODE_SHRED: &str = "Iris Code Input";
38pub const MPC_MASKCODE_SHRED: &str = "Mask Code Input";
39pub const MPC_SLOPES_SHRED: &str = "Slopes";
40pub const MPC_QUOTIENTS_SHRED: &str = "Quotients";
41pub const MPC_SHARES_SHRED: &str = "Shares Reduced Modulo GR4 Modulus";
42pub const MPC_MULTIPLICITIES_SHARES_SHRED: &str = "Multiplicities Shares";
43pub const MPC_MULTIPLICITIES_SLOPES_SHRED: &str = "Multiplicities Slopes";
44pub const MPC_MULTIPLICITIES_QUOTIENTS_SHRED: &str = "Multiplicities Quotients";
45pub const MPC_ENCODING_MATRIX_SHRED: &str = "Encoding Matrix";
46pub const MPC_EVALUATION_POINTS_SHRED: &str = "Evaluation Points";
47pub const MPC_LOOKUP_TABLE_VALUES_SHRED: &str = "Lookup Table Values";
48pub const MPC_LOOKUP_TABLE_VALUES_SHRED_2_19: &str = "Lookup Table Values 2^19";
49
50pub fn build_circuit<F: Field, const NUM_IRIS_4_CHUNKS: usize>(
60 layer_visibility: LayerVisibility,
61) -> Circuit<F> {
62 let mut builder = CircuitBuilder::<F>::new();
63
64 let num_vars_dataparallel = log2(NUM_IRIS_4_CHUNKS) as usize;
65 let num_vars = num_vars_dataparallel + 2;
68
69 let auxilary_input_layer_node = builder.add_input_layer(MPC_AUXILIARY_LAYER, layer_visibility);
70 let shares_input_layer_node =
71 builder.add_input_layer(MPC_SHARES_LAYER, LayerVisibility::Public);
72 let auxiliary_invariant_public_input_layer_node =
73 builder.add_input_layer(MPC_AUXILIARY_INVARIANT_LAYER, LayerVisibility::Public);
74 let auxiliary_invariant_public_input_layer_node_2 =
75 builder.add_input_layer(MPC_AUXILIARY_INVARIANT_LAYER_2, LayerVisibility::Public);
76 let slope_input_layer_node = builder.add_input_layer(MPC_SLOPES_LAYER, layer_visibility);
77 let iris_code_input_layer_node =
78 builder.add_input_layer(MPC_IRISCODE_INPUT_LAYER, layer_visibility);
79 let mask_code_input_layer_node =
80 builder.add_input_layer(MPC_MASKCODE_INPUT_LAYER, layer_visibility);
81
82 let iris_code =
83 builder.add_input_shred(MPC_IRISCODE_SHRED, num_vars, &iris_code_input_layer_node);
84 let mask_code =
85 builder.add_input_shred(MPC_MASKCODE_SHRED, num_vars, &mask_code_input_layer_node);
86 let slopes = builder.add_input_shred(MPC_SLOPES_SHRED, num_vars, &slope_input_layer_node);
87 let quotients =
88 builder.add_input_shred(MPC_QUOTIENTS_SHRED, num_vars, &auxilary_input_layer_node);
89 let shares_reduced_modulo_gr4_modulus =
90 builder.add_input_shred(MPC_SHARES_SHRED, num_vars, &shares_input_layer_node);
91 let multiplicities_shares = builder.add_input_shred(
92 MPC_MULTIPLICITIES_SHARES_SHRED,
93 GR4_ELEM_BIT_LENGTH as usize,
94 &auxilary_input_layer_node,
95 );
96 let multiplicities_slopes = builder.add_input_shred(
97 MPC_MULTIPLICITIES_SLOPES_SHRED,
98 GR4_ELEM_BIT_LENGTH as usize,
99 &auxilary_input_layer_node,
100 );
101 let multiplicities_quotients = builder.add_input_shred(
102 MPC_MULTIPLICITIES_QUOTIENTS_SHRED,
103 19,
104 &auxilary_input_layer_node,
105 );
106
107 let encoding_matrix = builder.add_input_shred(
108 MPC_ENCODING_MATRIX_SHRED,
109 ENCODING_MATRIX_NUM_VARS_ROWS + ENCODING_MATRIX_NUM_VARS_COLS,
110 &auxiliary_invariant_public_input_layer_node,
111 );
112 let evaluation_points = builder.add_input_shred(
113 MPC_EVALUATION_POINTS_SHRED,
114 num_vars,
115 &auxiliary_invariant_public_input_layer_node,
116 );
117
118 let lookup_table_values = builder.add_input_shred(
119 MPC_LOOKUP_TABLE_VALUES_SHRED,
120 GR4_ELEM_BIT_LENGTH as usize,
121 &auxiliary_invariant_public_input_layer_node,
122 );
123 let fiat_shamir_challenge_node = builder.add_fiat_shamir_challenge_node(1);
124 let lookup_table = builder.add_lookup_table(&lookup_table_values, &fiat_shamir_challenge_node);
125
126 let lookup_table_values_2_19 = builder.add_input_shred(
127 MPC_LOOKUP_TABLE_VALUES_SHRED_2_19,
128 19,
129 &auxiliary_invariant_public_input_layer_node_2,
130 );
131 let lookup_table_2_19 =
132 builder.add_lookup_table(&lookup_table_values_2_19, &fiat_shamir_challenge_node);
133
134 let masked_iris_code =
135 WorldcoinMpcComponents::masked_iris_code(&mut builder, &iris_code, &mask_code);
136 let encoded_masked_iris_code = builder.add_matmult_node(
138 &masked_iris_code,
139 (num_vars_dataparallel, ENCODING_MATRIX_NUM_VARS_ROWS),
140 &encoding_matrix,
141 (ENCODING_MATRIX_NUM_VARS_ROWS, ENCODING_MATRIX_NUM_VARS_COLS),
142 );
143
144 let evaluation_points_times_slopes = builder.add_gate_node(
146 &evaluation_points,
147 &slopes,
148 GR4_MULTIPLICATION_WIRINGS.to_vec(),
149 BinaryOperation::Mul,
150 Some(num_vars_dataparallel),
151 );
152
153 let computed_shares = WorldcoinMpcComponents::sum(
154 &mut builder,
155 &encoded_masked_iris_code,
156 &evaluation_points_times_slopes,
157 );
158
159 let _congruence = WorldcoinMpcComponents::congruence(
160 &mut builder,
161 "ients,
162 &computed_shares,
163 &shares_reduced_modulo_gr4_modulus,
164 );
165
166 let _lookup_constraint_shares = builder.add_lookup_constraint(
167 &lookup_table,
168 &shares_reduced_modulo_gr4_modulus,
169 &multiplicities_shares,
170 );
171
172 let _lookup_constraint_slopes =
173 builder.add_lookup_constraint(&lookup_table, &slopes, &multiplicities_slopes);
174
175 let _lookup_constraint_quotients =
176 builder.add_lookup_constraint(&lookup_table_2_19, "ients, &multiplicities_quotients);
177
178 builder.build_without_layer_combination().unwrap()
179}
180
181pub fn mpc_attach_data<F: Field>(
185 circuit: &mut Circuit<F>,
186 mpc_aux_data: MPCCircuitConstData<F>,
187 mpc_input_data: MPCCircuitInputData<F>,
188) {
189 circuit.set_input(MPC_IRISCODE_SHRED, mpc_input_data.iris_codes);
190 circuit.set_input(MPC_MASKCODE_SHRED, mpc_input_data.masks);
191 circuit.set_input(MPC_SLOPES_SHRED, mpc_input_data.slopes);
192 circuit.set_input(MPC_QUOTIENTS_SHRED, mpc_input_data.quotients);
193 circuit.set_input(
194 MPC_SHARES_SHRED,
195 mpc_input_data.shares_reduced_modulo_gr4_modulus,
196 );
197 circuit.set_input(
198 MPC_MULTIPLICITIES_SHARES_SHRED,
199 mpc_input_data.multiplicities_shares,
200 );
201 circuit.set_input(
202 MPC_MULTIPLICITIES_SLOPES_SHRED,
203 mpc_input_data.multiplicities_slopes,
204 );
205 circuit.set_input(
206 MPC_MULTIPLICITIES_QUOTIENTS_SHRED,
207 mpc_input_data.multiplicities_quotients,
208 );
209 circuit.set_input(MPC_ENCODING_MATRIX_SHRED, mpc_aux_data.encoding_matrix);
210 circuit.set_input(MPC_EVALUATION_POINTS_SHRED, mpc_aux_data.evaluation_points);
211 circuit.set_input(
212 MPC_LOOKUP_TABLE_VALUES_SHRED,
213 mpc_aux_data.lookup_table_values,
214 );
215 circuit.set_input(
216 MPC_LOOKUP_TABLE_VALUES_SHRED_2_19,
217 mpc_aux_data.lookup_table_values_2_19,
218 );
219}