ZK Query Language
The Atomic Query Signature V2 Circuit and Atomic Query MTP V2 Circuit circuits have been designed as generic circuits to do the ZK verification based on users' claims.
The Query Language sits on top of these circuits to provide a simple way for developers to design customized authentication requirements for someone's credentials. As long as the user holds a credential of a specific type, the Verifier can design a query based on 6 operators, for example:
- Must be a verified human to vote for a DAO specific proposal -
equals
(operator 1). - Must have been born before 2000-01-01 to access a specific website -
less-than
(operator 2). - Must have a monthly salary greater than $1000 to get a loan -
greater-than
(operator 3). - Must be an admin or a hacker of a DAO to enter a platform -
ìn
(operator 4). - Must not be a resident of a country in the list of blacklisted countries to operate on an exchange -
not-in
(operator 5). - Must not be a resident of a specific country -
not-equal
(operator 6).
The query is designed by the Verifier and presented to the user via a QR Code (or deep-linking). Starting from the proof generated by the user as a response to the query, the Verifier is easily able to check if the query is satisfied or not.
The Query Language follows the same rules whether the verification is implemented on-chain or off-chain, while the syntax to define these is a bit different. For each of the queries presented above, both the on-chain and off-chain way of designing will now be defined.
The entire scripts to set a query are available here: off-chain verification, on-chain verification
Equals - Operator 1
Credential Schema
The ProofOfHumanity
Schema encodes whether a user has been verified as a human or not. Here's the JSON-LD Context of the Schema Type.
You can create customized schemas, check out this tutorial!
Query
When presented with this query, the user must prove that he/she is a Person.
- off-chain
- on-chain
const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'ProofOfHumanity',
context: 'https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/proof-of-humanity/proof-of-humanity.jsonld',
credentialSubject: {
isHuman: {
$eq: 1,
},
},
},
};
// you can run https://go.dev/play/p/rnrRbxXTRY6 to get schema hash and claimPathKey using YOUR schema
const schemaBigInt = "324849518749029195374186444632030216125"
// merklized path to field in the W3C credential according to JSONLD schema
const schemaClaimPathKey = "14815366841010849835350402710291849818496586666144492189460088557509920034090"
const requestId = 1;
const query = {
schema: schemaBigInt,
claimPathKey : schemaClaimPathKey,
operator: 1,
value: [1, ...new Array(63).fill(0).map(i => 0)], // for operators 1,2,3,6 only first value matters
};
Corresponding QR Code
{
"id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"typ": "application/iden3comm-plain-json",
"type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
"thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"body": {
"reason": "airdrop participation",
"transaction_data": {
"contract address" : "<add your contract address here>", // replace with your contract address
"method_id": "b68967e2",
"chain_id": 80001,
"network": "polygon-mumbai"
},
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQuerySigV2OnChain",
"query": {
"allowedIssuers": [
"*"
],
"context": "https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/proof-of-humanity/proof-of-humanity.jsonld",
"credentialSubject": {
"isHuman": {
"$eq": 1
}
},
"type": "ProofOfHumanity"
}
}
]
}
}
Less-than - Operator 2
Credential Schema
The KYCAgeCredential
Schema encodes the date of birth of the credential subject. Here's the JSON-LD Context of the Schema Type.
Query
When presented with this query, the user must prove that he/she has been born before 2001/01/01.
- off-chain
- on-chain
const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'KYCAgeCredential',
context: 'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld',
credentialSubject: {
birthday: {
$lt: 20010101,
},
},
},
};
// you can run https://go.dev/play/p/rnrRbxXTRY6 to get schema hash and claimPathKey using YOUR schema
const schemaBigInt = "267831521922558027206082390043321796944"
// merklized path to field in the W3C credential according to JSONLD schema
const schemaClaimPathKey = "20376033832371109177683048456014525905119173674985843915445634726167450989630"
const requestId = 1;
const query = {
schema: schemaBigInt,
claimPathKey : schemaClaimPathKey,
operator: 1,
value: [1, ...new Array(63).fill(0).map(i => 0)], // for operators 1,2,3,6 only first value matters
};
Corresponding QR Code
{
"id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"typ": "application/iden3comm-plain-json",
"type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
"thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"body": {
"reason": "airdrop participation",
"transaction_data": {
"contract address" : "<add your contract address here>",
"method_id": "b68967e2",
"chain_id": 80001,
"network": "polygon-mumbai"
},
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQuerySigV2OnChain",
"query": {
"allowedIssuers": [
"*"
],
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld",
"credentialSubject": {
"birthday": {
"$lt": 20010101
}
},
"type": "KYCAgeCredential"
}
}
]
}
}
Greater-than - Operator 3
Credential Schema
The EmployeeData
Schema encodes the monthly salary of the credential subject. Here's the JSON-LD Context of the Schema Type.
Query
When presented with this query, the user must prove that his/her monthly salary is greater than $1000.
- off-chain
- on-chain
const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'EmployeeData',
context: 'https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/employee-data/employee-data.jsonld',
credentialSubject: {
monthlySalary: {
$gt: 1000,
},
},
},
};
// you can run https://go.dev/play/p/rnrRbxXTRY6 to get schema hash and claimPathKey using YOUR schema
const schemaBigInt = "215529050624769177581695011121804343416"
// merklized path to field in the W3C credential according to JSONLD schema
const schemaClaimPathKey = "18323209396655941018370955962714740724727867245625378697671016248362870463698"
const requestId = 1;
const query = {
schema: schemaBigInt,
claimPathKey : schemaClaimPathKey,
operator: 3, // operator
value: [1000, ...new Array(63).fill(0).map(i => 0)],
};
Corresponding QR Code
{
"id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"typ": "application/iden3comm-plain-json",
"type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
"thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"body": {
"reason": "airdrop participation",
"transaction_data": {
"contract address" : "<add your contract address here>",
"method_id": "b68967e2",
"chain_id": 80001,
"network": "polygon-mumbai"
},
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQuerySigV2OnChain",
"query": {
"allowedIssuers": [
"*"
],
"context": "https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/employee-data/employee-data.jsonld",
"credentialSubject": {
"monthlySalary": {
"$gt": 1000
}
},
"type": "EmployeeData"
}
}
]
}
}
In - Operator 4
Credential Schema
The ProofOfDaoRole
Schema encodes the role of someone inside a DAO. Each role is identified by a code as described in the Schema Vocab.
Here's the JSON-LD Context of the Schema Type.
Query
When presented with this query, the user must prove that he/she is either an Admin or a Hacker of a DAO (which corresponds to values 4 and 5).
- off-chain
- on-chain
const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'ProofOfDaoRole',
context: 'https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/proof-of-dao-role/proof-of-dao-role.jsonld',
credentialSubject: {
role: {
$in: [4, 5],
},
},
},
};
// you can run https://go.dev/play/p/rnrRbxXTRY6 to get schema hash and claimPathKey using YOUR schema
const schemaBigInt = "80689572245316684375295691372009959153"
// merklized path to field in the W3C credential according to JSONLD schema
const schemaClaimPathKey = "19483179179477598314891505360164348442915562939736565831310034495973163044179"
const requestId = 1;
const query = {
schema: schemaBigInt,
claimPathKey : schemaClaimPathKey,
operator: 4, // operator
value: [4, 5, ...new Array(62).fill(0).map(i => 0)],
};
Corresponding QR Code
{
"id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"typ": "application/iden3comm-plain-json",
"type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
"thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"body": {
"reason": "airdrop participation",
"transaction_data": {
"contract address" : "<add your contract address here>",
"method_id": "b68967e2",
"chain_id": 80001,
"network": "polygon-mumbai"
},
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQuerySigV2OnChain",
"query": {
"allowedIssuers": [
"*"
],
"context": "https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/proof-of-dao-role/proof-of-dao-role.jsonld",
"credentialSubject": {
"role": {
"$in": [4, 5]
}
},
"type": "ProofOfDaoRole"
}
}
]
}
}
Not-in - Operator 5
Credential Schema
The KYCCountryOfResidenceCredential
Schema encodes the countryCode of residence of the credential subject according to the ISO Standard. Here's the JSON-LD Context of the Schema Type.
Query
When presented with this query, the user must prove that he/she is not a resident of the countries 840, 120, 340, 509
identified by the ISO Standard.
- off-chain
- on-chain
const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'KYCCountryOfResidenceCredential',
context: 'https://github.com/iden3/claim-schema-vocab/blob/main/schemas/json-ld/kyc-v4.jsonld',
credentialSubject: {
countryCode: {
$nin: [840, 120, 340, 509],
},
},
},
};
// you can run https://go.dev/play/p/rnrRbxXTRY6 to get schema hash and claimPathKey using YOUR schema
const schemaBigInt = "201134713754279235117373236841506344285"
// merklized path to field in the W3C credential according to JSONLD schema
const schemaClaimPathKey = "17002437119434618783545694633038537380726339994244684348913844923422470806844"
const requestId = 1;
const query = {
schema: schemaBigInt,
claimPathKey : schemaClaimPathKey,
operator: 5, // operator
value: [840, 120, 340, 509, ...new Array(60).fill(0).map(i => 0)],
};
Corresponding QR Code
{
"id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"typ": "application/iden3comm-plain-json",
"type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
"thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"body": {
"reason": "airdrop participation",
"transaction_data": {
"contract address" : "<add your contract address here>",
"method_id": "b68967e2",
"chain_id": 80001,
"network": "polygon-mumbai"
},
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQuerySigV2OnChain",
"query": {
"allowedIssuers": [
"*"
],
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld",
"credentialSubject": {
"countryCode": {
"$nin": [840, 120, 340, 509]
}
},
"type": "KYCCountryOfResidenceCredential"
}
}
]
}
}
Not-equal - Operator 6
Credential Schema
The KYCCountryOfResidenceCredential
Schema encodes the countryCode of residence of the credential subject according to the ISO Standard. Here's the JSON-LD Context of the Schema Type.
Query
When presented with this query, the user must prove that he/she is not a resident of the country 840
identified by the ISO Standard.
- off-chain
- on-chain
const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'KYCCountryOfResidenceCredential',
context: 'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld',
credentialSubject: {
countryCode: {
$ne: 840
},
},
},
};
// you can run https://go.dev/play/p/rnrRbxXTRY6 to get schema hash and claimPathKey using YOUR schema
const schemaBigInt = "201134713754279235117373236841506344285"
// merklized path to field in the W3C credential according to JSONLD schema
const schemaClaimPathKey = "17002437119434618783545694633038537380726339994244684348913844923422470806844"
const requestId = 1;
const query = {
schema: schemaBigInt,
claimPathKey : schemaClaimPathKey,
operator: 6,
value: [840, ...new Array(63).fill(0).map(i => 0)], // for operators 1,2,3,6 only first value matters
};
Corresponding QR Code
{
"id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"typ": "application/iden3comm-plain-json",
"type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
"thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"body": {
"reason": "airdrop participation",
"transaction_data": {
"contract address" : "<add your contract address here>",
"method_id": "b68967e2",
"chain_id": 80001,
"network": "polygon-mumbai"
},
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQuerySigV2OnChain",
"query": {
"allowedIssuers": [
"*"
],
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld",
"credentialSubject": {
"countryCode": {
"$ne": 840
}
},
"type": "KYCCountryOfResidenceCredential"
}
}
]
}
}
Selective Disclosure
Selective Disclosure is a feature that enables requests for specific data from the ID Holder. Using a similar approach to the ZK language equal operation, the Verifier sends a verification request for a piece of the Holder's identity. As seen below, the way to make this request is by sending an empty object as a value.
Query
In the example below, the verifier requests the Holder's country code.
const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'KYCCountryOfResidenceCredential',
context: 'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld',
credentialSubject: {
countryCode: {},
},
},
};
When we use *
in the "allowed issuers" segment (allowedIssuers: ['*']
), we mean that we accept any entity that might have provided the credential. Even though this seems to be convenient for testing purposes, it may also be considered risky. Applying due diligence by actually choosing trusted specific issuers should be the best approach. Only in rare cases, a verifier would accept any issuer, so we advise not to use *
.