ZK Query Language
The Atomic Query Signature Circuit
and Atomic Query MTP
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 way for developers to design customised requirements based on someone's claims.
Platforms can implement queries for user authentication/verification in a flexible way using the Query Language operators, for example:
- Must be an admin inside PolygonDAO to vote for a specific proposal -
equals
. - Must have been born before 2000-01-01 to access an adult content website -
less-than
. - Must have a monthly salary greater than $1000 to get a loan -
greater-than
. - Must have one game item across a list of items to enter a tournament -
ìn
. - Must not be a resident of a country in the list of countries to operate on an exchange -
not-in
.
Starting from the proof generated by the user, the Verifier is easily able to check if the query is satisfied or not. The Verifier doesn't get access to any user's data.
As long as the user holds a claim of a specific type, the Verifier can design a query related to the claim based on these 5 operators.
The data structure of the claim described below is simplified. More details about the actual claim structure can be found here.
Equals
Claim
PolygonDAOMember {
"role": "5" // 5 corresponds to Dao Admin. Each role has a code associated
}
Query
const proofRequest: protocol.ZKPRequest = {
id: 1, // request id
circuit_id: 'credentialAtomicQuerySig',
rules: {
query: {
allowedIssuers: ['11A4eeoCN7Xdy5FZSd3BDxUS9yeA7FGGCCmpKPNhNP'], // ID of the trusted issuer
schema: {
type: 'PolygonDAOMember',
url: 'https://schema.polygonid.com/jsonld/dao.json-ld',
},
req: {
role: {
$eq: 5, // the role must be 5 = Group Admin
},
},
},
},
};
Less-than
Claim
AgeCredential {
"birthDay": "19701230" //yymmdd
}
Query
const proofRequest: protocol.ZKPRequest = {
id: 1, // request id
circuit_id: 'credentialAtomicQuerySig',
rules: {
query: {
allowedIssuers: ['113T3p9mwkNbRwsREgBwdjMdNJehAW5p6HcJSBpPjQ', '111DLXZwaj5Ag4hBneVgfb8FAy5EiyxjSkayVpqKj'], // ID of the trusted issuers
schema: {
type: 'AgeCredential',
url: 'https://schema.polygonid.com/jsonld/kyc.json-ld',
},
req: {
birthDay: {
$lt: 20000101, // birthDay field less then 2000/01/01
},
},
},
},
};
Greater-than
Claim
EmployeeData {
"monthlySalary": "1650", //denominated in $$
"employedSince": "20151230"
}
Query
const proofRequest: protocol.ZKPRequest = {
id: 1, // request id
circuit_id: 'credentialAtomicQuerySig',
rules: {
query: {
allowedIssuers: ['*'],
schema: {
type: 'EmployeeData',
url: 'https://schema.com/...employeedata',
},
req: {
monthlySalary: {
$gt: 1000, // monthlySalary must be over $1000
},
},
},
},
};
Schema type yet to be defined
In
Claim
UserGameItems {
"item": "52", // 52 identifies a specific in-game item
}
Query
const proofRequest: protocol.ZKPRequest = {
id: 1, // request id
circuit_id: 'credentialAtomicQuerySig',
rules: {
query: {
allowedIssuers: ['*'],
schema: {
type: 'UserGameItems',
url: 'https://schema.com/...usergameitems',
},
req: {
item: {
$in: [47, 52, 112, 145], // accept users that have an item included in the list
},
},
},
},
};
Schema type yet to be defined
Not-in
Claim
CountryOfResidenceCredential {
"countryCode": "840"
}
Query
const proofRequest: protocol.ZKPRequest = {
id: 1, // request id
circuit_id: 'credentialAtomicQuerySig',
rules: {
query: {
allowedIssuers: ['11BL1tHEwMR1tuCERfnaYbw4m5QPf45PKfFKZTL2Ep'], // ID of the trusted issuer
schema: {
type: 'CountryOfResidenceCredential',
url: 'https://schema.polygonid.com/jsonld/kyc.json-ld',
},
req: {
countryCode: {
$nin: [840, 120, 340, 509], // accepted any country not in the list
},
},
},
},
};
When designing a query, filling the req
field is not mandatory. For instance, a platform can just ask the user to have an AgeCredential claim as a way to identify unique humans without any requirements related to the date of birth. In that case, the Veriifer should simply not fill the req
field inside the proofRequest.