@@ -84,20 +84,16 @@ template getClaimHiHv() {
8484 signal output hi;
8585 signal output hv;
8686
87- component hashHi = Poseidon(6 );
87+ component hashHi = Poseidon(4 );
8888 for (var i= 0 ; i< 4 ; i++ ) {
8989 hashHi.inputs[i] <== claim[0 * 4 + i];
9090 }
91- hashHi.inputs[4 ] <== 0 ;
92- hashHi.inputs[5 ] <== 0 ;
9391 hi <== hashHi.out;
9492
95- component hashHv = Poseidon(6 );
93+ component hashHv = Poseidon(4 );
9694 for (var i= 0 ; i< 4 ; i++ ) {
9795 hashHv.inputs[i] <== claim[1 * 4 + i];
9896 }
99- hashHv.inputs[4 ] <== 0 ;
100- hashHv.inputs[5 ] <== 0 ;
10197 hv <== hashHv.out;
10298}
10399
@@ -110,13 +106,10 @@ template getIdenState() {
110106
111107 signal output idenState;
112108
113- component calcIdState = Poseidon(6 );
109+ component calcIdState = Poseidon(3 );
114110 calcIdState.inputs[0 ] <== claimsTreeRoot;
115111 calcIdState.inputs[1 ] <== revTreeRoot;
116112 calcIdState.inputs[2 ] <== rootsTreeRoot;
117- for (var i= 3 ; i< 6 ; i++ ) {
118- calcIdState.inputs[i] <== 0 ;
119- }
120113
121114 idenState <== calcIdState.out;
122115}
@@ -138,8 +131,17 @@ template getRevNonceNoVerHiHv() {
138131 }
139132 hi <== hashHi.out;
140133
134+ component hashHv = Poseidon(6 );
135+ hashHv.inputs[0 ] <== 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ;
136+ for (var i= 1 ; i< 6 ; i++ ) {
137+ hashHv.inputs[i] <== 0 ;
138+ }
139+ hv <== hashHv.out;
140+
141141 // hv = Poseidon([0xffff_ffff, 0, 0, 0, 0)
142- hv <== 17142353815121200339963760108352696118925531835836661574604762966243856573359 ;
142+ // hv <== Poseidon([0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0, 0, 0, 0, 0])
143+ // hv <== 17142353815121200339963760108352696118925531835836661574604762966243856573359;
144+ // hv <== 8137207316649344643315856769015464323293372071975540252804619894838929375565; // new from go
143145}
144146
145147// getRootHiHv calculates the hashes Hi and Hv of the leaf used in the roots
@@ -157,36 +159,57 @@ template getRootHiHv() {
157159 }
158160 hi <== hashHi.out;
159161
160- // hv = Poseidon([0, 0, 0, 0, 0)
161- hv <== 951383894958571821976060584138905353883650994872035011055912076785884444545 ;
162+ component hashHv = Poseidon(6 );
163+ for (var i= 0 ; i< 6 ; i++ ) {
164+ hashHv.inputs[i] <== 0 ;
165+ }
166+ hv <== hashHv.out;
167+
168+ // hv <== Poseidon([0, 0, 0, 0, 0, 0])
169+ // hv <== 951383894958571821976060584138905353883650994872035011055912076785884444545;
170+ // hv <== 14408838593220040598588012778523101864903887657864399481915450526643617223637; // new from go
171+ }
172+
173+ // getClaimSchema gets the schema of a claim
174+ template getClaimSchema () {
175+ signal input claim[8 ];
176+
177+ signal output schema;
178+
179+ component i0Bits = Num2Bits(256 );
180+ i0Bits.in <== claim[0 * 4 + 0 ]
181+
182+ component schemaNum = Bits2Num(64 );
183+
184+ for (var i= 0 ; i< 64 ; i++ ) {
185+ schemaNum.in [i] <== i0Bits.out[i];
186+ }
187+ schema <== schemaNum.out;
162188}
163189
164190// proveCredentialOwnership proves ownership of an identity (found in `claim[1]`) which
165191// is contained in a claim (`claim`) issued by an identity that has a recent
166192// identity state (`isIdenState`), while proving that the claim has not been
167- // revoed as of the recent identity state.
193+ // revoked as of the recent identity state.
168194template proveCredentialOwnership (IdOwnershipLevels, IssuerLevels ) {
169- var idOwnershipLevels = IdOwnershipLevels + 1 ;
170- var issuerLevels = IssuerLevels + 1 ;
171-
172195 // A
173196 signal input claim[8 ];
174197
175198 // B. holder proof of claimKOp in the genesis
176199 signal input hoKOpSk;
177- signal input hoClaimKOpMtp[idOwnershipLevels ];
200+ signal input hoClaimKOpMtp[IdOwnershipLevels ];
178201 signal input hoClaimKOpClaimsTreeRoot;
179202 // signal input hoClaimKOpRevTreeRoot;
180203 // signal input hoClaimKOpRootsTreeRoot;
181204
182205 // C. issuer proof of claim existence
183- signal input isProofExistMtp[issuerLevels ];
206+ signal input isProofExistMtp[IssuerLevels ];
184207 signal input isProofExistClaimsTreeRoot;
185208 // signal input isProofExistRevTreeRoot;
186209 // signal input isProofExistRootsTreeRoot;
187210
188211 // D. issuer proof of claim validity
189- signal input isProofValidNotRevMtp[issuerLevels ];
212+ signal input isProofValidNotRevMtp[IssuerLevels ];
190213 signal input isProofValidNotRevMtpNoAux;
191214 signal input isProofValidNotRevMtpAuxHi;
192215 signal input isProofValidNotRevMtpAuxHv;
@@ -195,7 +218,7 @@ template proveCredentialOwnership(IdOwnershipLevels, IssuerLevels) {
195218 signal input isProofValidRootsTreeRoot;
196219
197220 // E. issuer proof of Root (ExistClaimsTreeRoot)
198- signal input isProofRootMtp[issuerLevels ];
221+ signal input isProofRootMtp[IssuerLevels ];
199222
200223 // F. issuer recent idenState
201224 signal input isIdenState;
@@ -225,22 +248,22 @@ template proveCredentialOwnership(IdOwnershipLevels, IssuerLevels) {
225248 //
226249 // B. Prove ownership of the kOpSk associated with the holder identity
227250 //
228- component idOwnership = IdOwnershipGenesis(idOwnershipLevels );
251+ component idOwnership = IdOwnershipGenesis(IdOwnershipLevels );
229252 idOwnership.id <== subjectOtherIden.id ;
230253 idOwnership.userPrivateKey <== hoKOpSk;
231- for (var i= 0 ; i< idOwnershipLevels ; i++ ) { idOwnership.siblings[i] <== hoClaimKOpMtp[i]; }
254+ for (var i= 0 ; i< IdOwnershipLevels ; i++ ) { idOwnership.siblings[i] <== hoClaimKOpMtp[i]; }
232255 idOwnership.claimsTreeRoot <== hoClaimKOpClaimsTreeRoot;
233256 // idOwnership.revTreeRoot <== hoClaimKOpRevTreeRoot;
234257 // idOwnership.rootsTreeRoot <== hoClaimKOpRootsTreeRoot;
235258
236259 //
237260 // C. Claim proof of existence (isProofExist)
238261 //
239- component smtClaimExists = SMTVerifier(issuerLevels );
262+ component smtClaimExists = SMTVerifier(IssuerLevels );
240263 smtClaimExists.enabled <== 1 ;
241264 smtClaimExists.fnc <== 0 ; // Inclusion
242265 smtClaimExists.root <== isProofExistClaimsTreeRoot;
243- for (var i= 0 ; i< issuerLevels ; i++ ) { smtClaimExists.siblings[i] <== isProofExistMtp[i]; }
266+ for (var i= 0 ; i< IssuerLevels ; i++ ) { smtClaimExists.siblings[i] <== isProofExistMtp[i]; }
244267 smtClaimExists.oldKey <== 0 ;
245268 smtClaimExists.oldValue <== 0 ;
246269 smtClaimExists.isOld0 <== 0 ;
@@ -259,34 +282,209 @@ template proveCredentialOwnership(IdOwnershipLevels, IssuerLevels) {
259282 component revNonceHiHv = getRevNonceNoVerHiHv();
260283 revNonceHiHv.revNonce <== claimRevNonce.revNonce;
261284
262- component smtClaimValid = SMTVerifier(issuerLevels);
285+ component smtClaimValid = SMTVerifier(IssuerLevels);
286+ smtClaimValid.enabled <== 1 ;
287+ smtClaimValid.fnc <== 1 ; // Non-inclusion
288+ smtClaimValid.root <== isProofValidRevTreeRoot;
289+ for (var i= 0 ; i< IssuerLevels; i++ ) { smtClaimValid.siblings[i] <== isProofValidNotRevMtp[i]; }
290+ smtClaimValid.oldKey <== isProofValidNotRevMtpAuxHi;
291+ smtClaimValid.oldValue <== isProofValidNotRevMtpAuxHv;
292+ smtClaimValid.isOld0 <== isProofValidNotRevMtpNoAux;
293+ smtClaimValid.key <== revNonceHiHv.hi;
294+ smtClaimValid.value <== 0 ;
295+
296+
297+ //
298+ // E. Claim proof of root
299+ //
300+ component rootHiHv = getRootHiHv();
301+ rootHiHv.root <== isProofExistClaimsTreeRoot;
302+
303+ component smtRootValid = SMTVerifier(IssuerLevels);
304+ smtRootValid.enabled <== 1 ;
305+ smtRootValid.fnc <== 0 ; // Inclusion
306+ smtRootValid.root <== isProofValidRootsTreeRoot;
307+ for (var i= 0 ; i< IssuerLevels; i++ ) { smtRootValid.siblings[i] <== isProofRootMtp[i]; }
308+ smtRootValid.oldKey <== 0 ;
309+ smtRootValid.oldValue <== 0 ;
310+ smtRootValid.isOld0 <== 0 ;
311+ smtRootValid.key <== rootHiHv.hi;
312+ smtRootValid.value <== rootHiHv.hv;
313+
314+ //
315+ // F. Verify ValidIdenState == isIdenState
316+ //
317+ component isProofValidIdenState = getIdenState();
318+ isProofValidIdenState.claimsTreeRoot <== isProofValidClaimsTreeRoot;
319+ isProofValidIdenState.revTreeRoot <== isProofValidRevTreeRoot;
320+ isProofValidIdenState.rootsTreeRoot <== isProofValidRootsTreeRoot;
321+ // out: isProofValidIdenState.idenState
322+
323+ isProofValidIdenState.idenState === isIdenState;
324+ }
325+
326+
327+
328+
329+
330+
331+ // verifyCredentialSubject verifies that claim is issued to a specified identity
332+ template verifyCredentialSubject () {
333+ signal input claim[8 ];
334+ signal input id;
335+
336+ //
337+ // A. Prove that the claim has subject OtherIden, and take the subject identity.
338+ //
339+ component header = getClaimHeader();
340+ for (var i= 0 ; i< 8 ; i++ ) { header.claim[i] <== claim[i]; }
341+ // out: header.claimType
342+ // out: header.claimFlags[32]
343+
344+ // TODO: add reading SubjectPos from claim (0 = index, 1 = value) and providing it to the following component
345+ component subjectOtherIden = getClaimSubjectOtherIden(0 );
346+ for (var i= 0 ; i< 8 ; i++ ) { subjectOtherIden.claim[i] <== claim[i]; }
347+ for (var i= 0 ; i< 32 ; i++ ) { subjectOtherIden.claimFlags[i] <== header.claimFlags[i]; }
348+ // out: subjectOtherIden.id
349+
350+ subjectOtherIden.id === id;
351+ }
352+
353+ // verifyCredentialSchema verifies that claim matches provided schema
354+ template verifyCredentialSchema () {
355+ signal input claim[8 ];
356+ signal input schema;
357+
358+ component claimSchema = getClaimHeader();
359+
360+ isProofValidIdenState.idenState === isIdenState;
361+ }
362+
363+ // verifyCredentialNotRevoked verifies that claim is not included into the revocation tree
364+ // TODO: how do we get all of these params and why do we need them at all?
365+ template verifyCredentialNotRevoked (IssuerLevels ) {
366+ signal input claim[8 ];
367+
368+ // D. issuer proof of claim validity
369+ signal input isProofValidNotRevMtp[IssuerLevels];
370+ signal input isProofValidNotRevMtpNoAux;
371+ signal input isProofValidNotRevMtpAuxHi;
372+ signal input isProofValidNotRevMtpAuxHv;
373+ signal input isProofValidRevTreeRoot;
374+
375+
376+ component claimRevNonce = getClaimRevNonce();
377+ for (var i= 0 ; i< 8 ; i++ ) { claimRevNonce.claim[i] <== claim[i]; }
378+ // out: claimRevNonce.revNonce
379+
380+ //
381+ // D. Claim proof of non revocation (validity)
382+ //
383+ component revNonceHiHv = getRevNonceNoVerHiHv();
384+ revNonceHiHv.revNonce <== claimRevNonce.revNonce;
385+
386+ component smtClaimValid = SMTVerifier(IssuerLevels);
263387 smtClaimValid.enabled <== 1 ;
264388 smtClaimValid.fnc <== 1 ; // Non-inclusion
265389 smtClaimValid.root <== isProofValidRevTreeRoot;
266- for (var i= 0 ; i< issuerLevels ; i++ ) { smtClaimValid.siblings[i] <== isProofValidNotRevMtp[i]; }
390+ for (var i= 0 ; i< IssuerLevels ; i++ ) { smtClaimValid.siblings[i] <== isProofValidNotRevMtp[i]; }
267391 smtClaimValid.oldKey <== isProofValidNotRevMtpAuxHi;
268392 smtClaimValid.oldValue <== isProofValidNotRevMtpAuxHv;
269393 smtClaimValid.isOld0 <== isProofValidNotRevMtpNoAux;
270394 smtClaimValid.key <== revNonceHiHv.hi;
271395 smtClaimValid.value <== 0 ;
396+ }
397+
398+ // verifyCredentialMtp verifies that claim is issued by the issuer and included into the claim tree root
399+ template verifyCredentialMtp (IssuerLevels ) {
400+ signal input claim[8 ];
401+
402+ // C. issuer proof of claim existence
403+ // TODO: rename signals
404+ signal input isProofExistMtp[IssuerLevels]; // issuerClaimMtp
405+ signal input isProofExistClaimsTreeRoot; // issuerClaimTreeRoot
406+ // signal input isProofExistRevTreeRoot; // issuerRevTreeRoot
407+ // signal input isProofExistRootsTreeRoot; // issuerRootsTreeRoot
408+
409+ component claimHiHv = getClaimHiHv();
410+ for (var i= 0 ; i< 8 ; i++ ) { claimHiHv.claim[i] <== claim[i]; }
411+ // out: claimHiHv.hi
412+ // out: claimHiHv.hv
413+
414+ //
415+ // C. Claim proof of existence (isProofExist)
416+ //
417+ component smtClaimExists = SMTVerifier(IssuerLevels);
418+ smtClaimExists.enabled <== 1 ;
419+ smtClaimExists.fnc <== 0 ; // Inclusion
420+ smtClaimExists.root <== isProofExistClaimsTreeRoot;
421+ for (var i= 0 ; i< IssuerLevels; i++ ) { smtClaimExists.siblings[i] <== isProofExistMtp[i]; }
422+ smtClaimExists.oldKey <== 0 ;
423+ smtClaimExists.oldValue <== 0 ;
424+ smtClaimExists.isOld0 <== 0 ;
425+ smtClaimExists.key <== claimHiHv.hi;
426+ smtClaimExists.value <== claimHiHv.hv;
427+ }
428+
429+ // verifyCredentialMtp verifies that claim is issued by the issuer and included into the claim tree root
430+ template verifyCredentialMtpHiHv (IssuerLevels ) {
431+ signal input hi;
432+ signal input hv;
433+
434+ signal input isProofExistMtp[IssuerLevels]; // issuerClaimMtp
435+ signal input isProofExistClaimsTreeRoot; // issuerClaimTreeRoot
436+ // signal input isProofExistRevTreeRoot; // issuerRevTreeRoot
437+ // signal input isProofExistRootsTreeRoot; // issuerRootsTreeRoot
272438
439+ component smtClaimExists = SMTVerifier(IssuerLevels);
440+ smtClaimExists.enabled <== 1 ;
441+ smtClaimExists.fnc <== 0 ; // Inclusion
442+ smtClaimExists.root <== isProofExistClaimsTreeRoot;
443+ for (var i= 0 ; i< IssuerLevels; i++ ) { smtClaimExists.siblings[i] <== isProofExistMtp[i]; }
444+ smtClaimExists.oldKey <== 0 ;
445+ smtClaimExists.oldValue <== 0 ;
446+ smtClaimExists.isOld0 <== 0 ;
447+ smtClaimExists.key <== hi;
448+ smtClaimExists.value <== hv;
449+ }
450+
451+ // verifyClaimsTreeRoot verifies that claim is issued by the issuer and included into the claim tree root
452+ // TODO: what is this check doing? Is it checking inclusion of claim tree root to the roots tree for indirect identities?
453+ // TODO: Or it should be included to the roots tree for direct identities too?
454+ template verifyClaimsTreeRoot (IssuerLevels ) {
455+ signal input isProofExistClaimsTreeRoot; // issuerClaimTreeRoot
456+ signal input isProofValidRootsTreeRoot;
457+
458+ // E. issuer proof of Root (ExistClaimsTreeRoot)
459+ signal input isProofRootMtp[IssuerLevels];
273460
274461 //
275462 // E. Claim proof of root
276463 //
277464 component rootHiHv = getRootHiHv();
278465 rootHiHv.root <== isProofExistClaimsTreeRoot;
279466
280- component smtRootValid = SMTVerifier(issuerLevels );
467+ component smtRootValid = SMTVerifier(IssuerLevels );
281468 smtRootValid.enabled <== 1 ;
282469 smtRootValid.fnc <== 0 ; // Inclusion
283470 smtRootValid.root <== isProofValidRootsTreeRoot;
284- for (var i= 0 ; i< issuerLevels ; i++ ) { smtRootValid.siblings[i] <== isProofRootMtp[i]; }
471+ for (var i= 0 ; i< IssuerLevels ; i++ ) { smtRootValid.siblings[i] <== isProofRootMtp[i]; }
285472 smtRootValid.oldKey <== 0 ;
286473 smtRootValid.oldValue <== 0 ;
287474 smtRootValid.isOld0 <== 0 ;
288475 smtRootValid.key <== rootHiHv.hi;
289476 smtRootValid.value <== rootHiHv.hv;
477+ }
478+
479+ // verifyCredentialExistence verifies that claim is issued by the issuer
480+ // is contained in a claim (`claim`) issued by an identity that has a recent
481+ // identity state (`isIdenState`), while proving that the claim has not been
482+ // revoked as of the recent identity state.
483+ template verifyIdenStateMatchesRoots () {
484+ signal input isProofValidClaimsTreeRoot;
485+ signal input isProofValidRevTreeRoot;
486+ signal input isProofValidRootsTreeRoot;
487+ signal input isIdenState;
290488
291489 //
292490 // F. Verify ValidIdenState == isIdenState
0 commit comments