Skip to content

Circuits

Template Docs Example

Let's understand how circuits and templates can be described by their graphs. Just compare the following .circom code with its visual graph displayed underneath.

The code:

template Example () {
signal input input1;
signal input input2;
signal input input3;
signal input input4;
signal input input5;

    component template1 = Template1();
    template1.in1 = input1;
    template1.in2 = input2;
    template1.in3 = input3;

    component template2 = Template2();
    template2.in1 = input3;
    template2.in2 = input4;
}

The graph:

graph TB Input1 --> Template1 Input2 --> Template1 Input3 --> Template1 Input3 --> Template2 Input4 --> Template2 classDef inputStyle fill:#ecb3ff class Input1,Input2,Input3,Input4,Input5,Input6,Input7,Input8,Input9 inputStyle classDef circuitStyle fill:#b3ffd4,stroke-width:3px; class Template1,Template2,Template3 circuitStyle;

Basic Templates

Basic templates are not used independently to create circuits but are used as the building blocks for other templates.

checkClaimExists

This circuit checks if a claim exists in the sparse Merkle tree. By "exists", we mean that a value Hv (hash of all values slots) is located by path Hi (hash of all index slots) in the tree.

graph TB claim --> getClaimHiHv getClaimHiHv -- key --> SMTVerifier[SMTVerifier] getClaimHiHv -- value --> SMTVerifier claimMTP -- siblings --> SMTVerifier treeRoot -- root --> SMTVerifier 1 -- enabled --> SMTVerifier zero1[0] -- fnc --> SMTVerifier zero2[0] -- oldKey --> SMTVerifier zero3[0] -- oldValue --> SMTVerifier zero4[0] -- isOld0 --> SMTVerifier classDef inputStyle fill:#ecb3ff class claim,claimMTP,treeRoot inputStyle classDef circuitStyle fill:#b3ffd4,stroke-width:3px; class getClaimHiHv,SMTVerifier circuitStyle;

checkClaimNonRev

The circuit checks that the claim does not exist in the sparse Merkle tree. That means that the tree leaf is empty by a path, which is defined by the claim nonce.

graph TB claim --> getNonce getNonce -- key --> SMTVerifier[SMTVerifier] 0 -- value --> SMTVerifier claimMTP -- siblings --> SMTVerifier treeRoot -- root --> SMTVerifier 1 -- enabled --> SMTVerifier zero1[1] -- fnc --> SMTVerifier noAux -- isOld0 --> SMTVerifier auxHi -- oldKey --> SMTVerifier auxHv -- oldValue --> SMTVerifier classDef inputStyle fill:#ecb3ff class claim,claimMTP,treeRoot,noAux,auxHi,auxHv inputStyle classDef circuitStyle fill:#b3ffd4,stroke-width:3px; class getNonce,SMTVerifier circuitStyle;

checkChallengeSignature

This circuit checks if the challenge signature is correct. The public key for verification is extracted from the claim.

graph TB claim --> getPubKeyFromClaim getPubKeyFromClaim -- Ax --> EdDSAPoseidonVerifier getPubKeyFromClaim -- Ay --> EdDSAPoseidonVerifier signatureS -- S --> EdDSAPoseidonVerifier signatureR8X -- R8X --> EdDSAPoseidonVerifier signatureR8Y -- R8Y --> EdDSAPoseidonVerifier challenge -- M --> EdDSAPoseidonVerifier classDef inputStyle fill:#ecb3ff class claim,getPubKey,signatureS,signatureR8Y,signatureR8X,challenge inputStyle classDef circuitStyle fill:#b3ffd4,stroke-width:3px class getPubKeyFromClaim,EdDSAPoseidonVerifier circuitStyle

verifyIdenStateMatchesRoot

The circuit calculates the identity state from the three Merkle tree roots and checks if it is equal to the expected state.

graph TB claimsTreeRoot --> calcRoot revTreeRoot --> calcRoot rootsTreeRoot --> calcRoot calcRoot --> equal[=] expectedState ---> equal classDef inputStyle fill:#ecb3ff class claimsTreeRoot,revTreeRoot,rootsTreeRoot,expectedState inputStyle classDef circuitStyle fill:#b3ffd4,stroke-width:3px class calcRoot,equal circuitStyle

Query

This circuit checks that an expression within an operator and its value are true.

For example in="1", operator="4", value=["5","2","3"] is true because "4" is "not in" operator and "1" is not in the ["5","2","3"] array.

See all the operators in the circuit comments. The circuit graph is not represented here due to complexity.

Functional Templates

These are the templates that the Iden3 system mostly uses to generate and verify proofs directly. A functional template may use other functional templates as its building blocks.

idOwnershipBySignature

This circuit checks the ownership of a specific identity in the following way:

  1. The claim with the public key should exist in the claims tree.
  2. The claim with the public key should not be revoked.
  3. The signature of a challenge should be valid.
  4. The state should be equal to "expected" from the blockchain.

The above criteria enable a verifier to check that the challenge is signed by an identity, which state is timestamped on the blockchain and if it includes the non-revoked claim with the relevant public key.

CredentialAtomicQueryMTP

This circuit checks that an issuer has issued a claim for identity and validates the ownership of that identity in the following manner:

  1. Checks the identity ownership by idOwnershipBySignature template
  2. Verifies the claim subject, the schema and the expiration time.
  3. Checks if the issuer claim exists in the issuer claims tree.
  4. Checks if the issuer claim is not revoked by an issuer.
  5. Checks if the issuer claim satisfies a query.

CredentialAtomicQuerySig

This circuit checks that an issuer has issued a claim for identity and validates ownership of that identity in the following manner:

  1. Checks the identity ownership by idOwnershipBySignature template.
  2. Verifies the claim subject, the schema and the expiration time
  3. Checks if the issuer claim exists in the issuer claims tree.
  4. Verifies the claim signature by the issuer.
  5. Verifies if the issuer state matches with the one from the blockchain as the public input.
  6. Checks if the issuer claim satisfies a query.