1use std::collections::HashMap;
6
7use eddsa_babyjubjub::EdDSASignature;
8use groth16_material::circom::ProofInput;
9use ruint::aliases::U256;
10
11use world_id_primitives::{
12 AuthenticatorPublicKeySet, FieldElement, MAX_AUTHENTICATOR_KEYS, merkle::MerkleInclusionProof,
13};
14
15type BaseField = ark_babyjubjub::Fq;
16type ScalarField = ark_babyjubjub::Fr;
17type Affine = ark_babyjubjub::EdwardsAffine;
18
19#[inline]
20pub(crate) fn fq_to_u256_vec(f: ark_babyjubjub::Fq) -> Vec<U256> {
21 vec![f.into()]
22}
23
24#[inline]
25pub(crate) fn fq_seq_to_u256_vec(fs: &[ark_babyjubjub::Fq]) -> Vec<U256> {
26 fs.iter().copied().map(Into::into).collect()
27}
28
29#[inline]
30pub(crate) fn fr_to_u256_vec(f: ark_babyjubjub::Fr) -> Vec<U256> {
31 vec![f.into()]
32}
33
34#[inline]
35pub(crate) fn affine_to_u256_vec(p: ark_babyjubjub::EdwardsAffine) -> Vec<U256> {
36 vec![p.x.into(), p.y.into()]
37}
38
39#[inline]
40pub(crate) fn affine_seq_to_u256_vec(ps: &[ark_babyjubjub::EdwardsAffine]) -> Vec<U256> {
41 ps.iter()
42 .copied()
43 .flat_map(|p| [p.x.into(), p.y.into()])
44 .collect()
45}
46
47#[derive(Debug, Clone)]
51pub struct QueryProofCircuitInput<const MAX_DEPTH: usize> {
52 pub pk: [Affine; MAX_AUTHENTICATOR_KEYS],
54 pub pk_index: BaseField,
56 pub s: ScalarField,
58 pub r: Affine,
60 pub merkle_root: BaseField,
62 pub depth: BaseField,
64 pub mt_index: BaseField,
68 pub siblings: [BaseField; MAX_DEPTH],
70 pub beta: ScalarField,
72 pub rp_id: BaseField,
76 pub action: BaseField,
78 pub nonce: BaseField,
80}
81
82impl<const MAX_DEPTH: usize> ProofInput for QueryProofCircuitInput<MAX_DEPTH> {
83 fn prepare_input(&self) -> HashMap<String, Vec<U256>> {
84 let mut map = HashMap::new();
85 map.insert("pk".to_owned(), affine_seq_to_u256_vec(&self.pk));
86 map.insert("pk_index".to_owned(), fq_to_u256_vec(self.pk_index));
87 map.insert("s".to_owned(), fr_to_u256_vec(self.s));
88 map.insert("r".to_owned(), affine_to_u256_vec(self.r));
89 map.insert("merkle_root".to_owned(), fq_to_u256_vec(self.merkle_root));
90 map.insert("depth".to_owned(), fq_to_u256_vec(self.depth));
91 map.insert("mt_index".to_owned(), fq_to_u256_vec(self.mt_index));
92 map.insert("siblings".to_owned(), fq_seq_to_u256_vec(&self.siblings));
93 map.insert("beta".to_owned(), fr_to_u256_vec(self.beta));
94 map.insert("rp_id".to_owned(), fq_to_u256_vec(self.rp_id));
95 map.insert("action".to_owned(), fq_to_u256_vec(self.action));
96 map.insert("nonce".to_owned(), fq_to_u256_vec(self.nonce));
97 map
98 }
99}
100
101#[derive(Debug, Clone)]
105pub struct NullifierProofCircuitInput<const MAX_DEPTH: usize> {
106 pub query_input: QueryProofCircuitInput<MAX_DEPTH>,
108
109 pub issuer_schema_id: BaseField,
114 pub cred_pk: Affine,
116 pub cred_hashes: [BaseField; 2],
119 pub cred_genesis_issued_at: BaseField,
121 pub cred_expires_at: BaseField,
123 pub cred_s: ScalarField,
125 pub cred_r: Affine,
127 pub current_timestamp: BaseField,
129 pub cred_genesis_issued_at_min: BaseField,
131 pub cred_sub_blinding_factor: BaseField,
133 pub cred_id: BaseField,
138
139 pub id_commitment_r: BaseField,
144
145 pub id_commitment: BaseField,
150
151 pub dlog_e: BaseField,
154 pub dlog_s: ScalarField,
156 pub oprf_pk: Affine,
158 pub oprf_response_blinded: Affine,
160 pub oprf_response: Affine,
162
163 pub signal_hash: BaseField,
166}
167
168impl<const MAX_DEPTH: usize> ProofInput for NullifierProofCircuitInput<MAX_DEPTH> {
169 fn prepare_input(&self) -> std::collections::HashMap<String, Vec<ruint::aliases::U256>> {
170 let mut map = self.query_input.prepare_input();
171 map.insert(
172 "issuer_schema_id".to_owned(),
173 fq_to_u256_vec(self.issuer_schema_id),
174 );
175 map.insert("cred_pk".to_owned(), affine_to_u256_vec(self.cred_pk));
176 map.insert(
177 "cred_hashes".to_owned(),
178 fq_seq_to_u256_vec(&self.cred_hashes),
179 );
180 map.insert(
181 "cred_genesis_issued_at".to_owned(),
182 fq_to_u256_vec(self.cred_genesis_issued_at),
183 );
184 map.insert(
185 "cred_genesis_issued_at_min".to_owned(),
186 fq_to_u256_vec(self.cred_genesis_issued_at_min),
187 );
188 map.insert(
189 "cred_expires_at".to_owned(),
190 fq_to_u256_vec(self.cred_expires_at),
191 );
192 map.insert("cred_id".to_owned(), fq_to_u256_vec(self.cred_id));
193 map.insert(
194 "cred_user_id_r".to_owned(),
195 fq_to_u256_vec(self.cred_sub_blinding_factor),
196 );
197 map.insert("cred_s".to_owned(), fr_to_u256_vec(self.cred_s));
198 map.insert("cred_r".to_owned(), affine_to_u256_vec(self.cred_r));
199
200 map.insert(
201 "id_commitment_r".to_owned(),
202 fq_to_u256_vec(self.id_commitment_r),
203 );
204 map.insert(
205 "id_commitment".to_owned(),
206 fq_to_u256_vec(self.id_commitment),
207 );
208
209 map.insert("dlog_e".to_owned(), fq_to_u256_vec(self.dlog_e));
210 map.insert("dlog_s".to_owned(), fr_to_u256_vec(self.dlog_s));
211 map.insert("oprf_pk".to_owned(), affine_to_u256_vec(self.oprf_pk));
212 map.insert(
213 "oprf_response_blinded".to_owned(),
214 affine_to_u256_vec(self.oprf_response_blinded),
215 );
216 map.insert(
217 "oprf_response".to_owned(),
218 affine_to_u256_vec(self.oprf_response),
219 );
220 map.insert("signal_hash".to_owned(), fq_to_u256_vec(self.signal_hash));
221 map.insert(
222 "current_timestamp".to_owned(),
223 fq_to_u256_vec(self.current_timestamp),
224 );
225
226 map
227 }
228}
229
230#[derive(Debug, Clone)]
232pub struct OwnershipProofCircuitInput<const MAX_DEPTH: usize> {
233 pub key_index: u64,
235 pub key_set: AuthenticatorPublicKeySet,
237 pub inclusion_proof: MerkleInclusionProof<MAX_DEPTH>,
239 pub nonce: FieldElement,
241 pub signature: EdDSASignature,
243 pub commitment_blinder: FieldElement,
245}