Skip to content

Commit

Permalink
exists with true/false
Browse files Browse the repository at this point in the history
  • Loading branch information
volodymyr-basiuk committed Feb 23, 2024
1 parent 71eddfc commit ef8e494
Show file tree
Hide file tree
Showing 11 changed files with 88 additions and 84 deletions.
2 changes: 1 addition & 1 deletion circuits/lib/query/processQueryWithModifiers.circom
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ template ProcessQueryWithModifiers(claimLevels, maxValueArraySize){
signal operatorNotNoop <== NOT()(IsZero()(operator));
signal merklizedAndEnabled <== AND()(enabled, merklized);

signal claimPathNotExists <== IsEqual()([operator, 12]); // for non-exist operator 1, else 0
signal claimPathNotExists <== AND()(IsZero()(value[0]), IsEqual()([operator, 11])); // for exist and value 0 operator 1, else 0

// check path/in node exists in merkletree specified by jsonldRoot
SMTVerifier(claimLevels)(
Expand Down
5 changes: 2 additions & 3 deletions circuits/lib/query/query.circom
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ include "comparators.circom";
9 - between
10 - not between
11 - exist
12 - not exist
Modifier/computation operators:
16 - selective disclosure (16 = 10000 binary)
*/
Expand Down Expand Up @@ -78,8 +77,8 @@ template Query (maxValueArraySize) {
queryOpSatisfied.c[8] <== gte; // gte === !lt
queryOpSatisfied.c[9] <== between; // between
queryOpSatisfied.c[10] <== NOT()(between); // not between
queryOpSatisfied.c[11] <== 1; // exist; skip execution
queryOpSatisfied.c[12] <== 1; // not exist; skip execution
queryOpSatisfied.c[11] <== 1; // exists;
queryOpSatisfied.c[12] <== 0; // not used
queryOpSatisfied.c[13] <== 0; // not used
queryOpSatisfied.c[14] <== 0; // not used
queryOpSatisfied.c[15] <== 0; // not used
Expand Down
7 changes: 3 additions & 4 deletions circuits/lib/utils/arraySizeValidator.circom
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ include "../query/comparators.circom";
8 - greater than or equal - 1 element
9 - between - 2 elements
10 - not between - 2 elements
11 - exist - 0 elements
12 - not exist - 0 elements
11 - exists - 1 elements (true/false)
Modifier/computation operators:
16 - selective disclosure (16 = 10000 binary) - 0 elements
17-31 - 0 elements
Expand Down Expand Up @@ -64,8 +63,8 @@ template ArraySizeValidator (maxValueArraySize) {
mux.c[8] <== sizeEqOne; // gte
mux.c[9] <== sizeEqTwo; // between
mux.c[10] <== sizeEqTwo; // not between
mux.c[11] <== sizeEqZero; // exist
mux.c[12] <== sizeEqZero; // not exist
mux.c[11] <== sizeEqOne; // exist
mux.c[12] <== sizeEqZero; // not used
mux.c[13] <== sizeEqZero; // not used
mux.c[14] <== sizeEqZero; // not used
mux.c[15] <== sizeEqZero; // not used
Expand Down
5 changes: 3 additions & 2 deletions circuits/lib/utils/queryHash.circom
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ template QueryHash(maxValueArraySize) {
signal input slotIndex;
signal input operator;
signal input claimPathKey;
signal input claimPathNotExists;
signal input valueArraySize;
signal input merklized;
signal input verifierID;
Expand All @@ -16,6 +15,8 @@ template QueryHash(maxValueArraySize) {

signal output out;

signal claimPathNotExists <== AND()(IsZero()(value[0]), IsEqual()([operator, 11]));

/////////////////////////////////////////////////////////////////
// Calculate query hash
/////////////////////////////////////////////////////////////////
Expand All @@ -34,8 +35,8 @@ template QueryHash(maxValueArraySize) {
firstPartQueryHash,
valueArraySize,
merklized,
verifierID,
isRevocationChecked,
verifierID,
nullifierSessionID
]);
}
3 changes: 0 additions & 3 deletions circuits/linked/multiQuery.circom
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ template LinkedMultiQuery(N, claimLevels, maxValueArraySize) {


signal operatorNotNoop[N];
signal claimPathNotExists[N];
/////////////////////////////////////////////////////////////////
// Query Processing Loop
/////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -92,14 +91,12 @@ template LinkedMultiQuery(N, claimLevels, maxValueArraySize) {
// Calculate query hash
/////////////////////////////////////////////////////////////////
// 4950 constraints (SpongeHash+Poseidon)
claimPathNotExists[i] <== IsEqual()([operator[i], 12]); // for non-exist operator 1, else 0
circuitQueryHash[i] <== QueryHash(maxValueArraySize)(
value[i],
claimSchema,
slotIndex[i],
operator[i],
claimPathKey[i],
claimPathNotExists[i],
valueArraySize[i],
merklized,
0,
Expand Down
1 change: 0 additions & 1 deletion circuits/onchain/credentialAtomicQueryV3OnChain.circom
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ template credentialAtomicQueryV3OnChain(issuerLevels, claimLevels, maxValueArray
/////////////////////////////////////////////////////////////////
// Verify query hash matches
/////////////////////////////////////////////////////////////////
signal claimPathNotExists <== IsEqual()([operator, 12]); // for non-exist operator 1, else 0

circuitQueryHash <== QueryHash(maxValueArraySize)(
value,
Expand Down
2 changes: 1 addition & 1 deletion test/onchain/credentialAtomicQueryV3OnChain.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe("Test credentialAtomicQueryV3OnChain.circom", function () {
require(`${sigBasePath}/auth_check_disabled.json`),
require(`${sigBasePath}/noop_operator.json`),

// mtp
// // mtp
require(`${mtpBasePath}/claimIssuedOnProfileID.json`),
require(`${mtpBasePath}/claimIssuedOnProfileID2.json`),
require(`${mtpBasePath}/claimIssuedOnUserID.json`),
Expand Down
2 changes: 1 addition & 1 deletion test/query/query.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1250,7 +1250,7 @@ describe("Test query", function () {
});

describe("#Invalid Query Ops", function () {
for (let op = 10; op < 32; op++) {
for (let op = 12; op < 32; op++) {
it("#Invalid Query Op " + op + " (false)", async () => {
const w = await circuit.calculateWitness({
in: "0",
Expand Down
114 changes: 64 additions & 50 deletions testvectorgen/credentials/onchain/v3/v3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,12 @@ type Inputs struct {

// Query
// JSON path
ClaimPathNotExists string `json:"claimPathNotExists"` // 0 for inclusion, 1 for non-inclusion
ClaimPathMtp []string `json:"claimPathMtp"`
ClaimPathMtpNoAux string `json:"claimPathMtpNoAux"` // 1 if aux node is empty, 0 if non-empty or for inclusion proofs
ClaimPathMtpAuxHi string `json:"claimPathMtpAuxHi"` // 0 for inclusion proof
ClaimPathMtpAuxHv string `json:"claimPathMtpAuxHv"` // 0 for inclusion proof
ClaimPathKey string `json:"claimPathKey"` // hash of path in merklized json-ld document
ClaimPathValue string `json:"claimPathValue"` // value in this path in merklized json-ld document
ClaimPathMtp []string `json:"claimPathMtp"`
ClaimPathMtpNoAux string `json:"claimPathMtpNoAux"` // 1 if aux node is empty, 0 if non-empty or for inclusion proofs
ClaimPathMtpAuxHi string `json:"claimPathMtpAuxHi"` // 0 for inclusion proof
ClaimPathMtpAuxHv string `json:"claimPathMtpAuxHv"` // 0 for inclusion proof
ClaimPathKey string `json:"claimPathKey"` // hash of path in merklized json-ld document
ClaimPathValue string `json:"claimPathValue"` // value in this path in merklized json-ld document

Operator int `json:"operator"`
SlotIndex int `json:"slotIndex"`
Expand Down Expand Up @@ -121,7 +120,7 @@ type Inputs struct {
VerifierID string `json:"verifierID"`
NullifierSessionID string `json:"nullifierSessionID"`

AuthEnabled int `json:"authEnabled"`
IsBJJAuthEnabled int `json:"isBJJAuthEnabled"`
}

type Outputs struct {
Expand All @@ -134,15 +133,12 @@ type Outputs struct {
Timestamp string `json:"timestamp"`
Merklized string `json:"merklized"`
ProofType string `json:"proofType"` // 1 for sig, 2 for mtp
IsRevocationChecked string `json:"isRevocationChecked"`
Challenge string `json:"challenge"`
IssuerState string `json:"issuerState"`
LinkID string `json:"linkID"`
VerifierID string `json:"verifierID"`
NullifierSessionID string `json:"nullifierSessionID"`
OperatorOutput string `json:"operatorOutput"`
Nullifier string `json:"nullifier"`
AuthEnabled string `json:"authEnabled"`
IsBJJAuthEnabled string `json:"isBJJAuthEnabled"`
}

type TestData struct {
Expand Down Expand Up @@ -300,8 +296,8 @@ func generateRevokedTestData(t *testing.T, desc string, isUserIDProfile, isSubje
}

func generateTestDataWithOperator(t *testing.T, desc string, isUserIDProfile, isSubjectIDProfile bool,
linkNonce string, fileName string, operator int, value *[]string, proofType ProofType, authEnabled int) {
generateTestDataWithOperatorAndRevCheck(t, desc, isUserIDProfile, isSubjectIDProfile, linkNonce, "0", fileName, operator, value, false, 1, false, proofType, authEnabled)
linkNonce string, fileName string, operator int, value *[]string, proofType ProofType, isBJJAuthEnabled int) {
generateTestDataWithOperatorAndRevCheck(t, desc, isUserIDProfile, isSubjectIDProfile, linkNonce, "0", fileName, operator, value, false, 1, false, proofType, isBJJAuthEnabled)
}

func generateJSONLDTestData(t *testing.T, desc string, isUserIDProfile, isSubjectIDProfile bool, fileName string, proofType ProofType) {
Expand All @@ -310,7 +306,7 @@ func generateJSONLDTestData(t *testing.T, desc string, isUserIDProfile, isSubjec

func generateTestDataWithOperatorAndRevCheck(t *testing.T, desc string, isUserIDProfile, isSubjectIDProfile bool,
linkNonce, nullifierSessionID, fileName string, operator int, value *[]string, isRevoked bool, isRevocationChecked int, isJSONLD bool, testProofType ProofType,
authEnabled int) {
isBJJAuthEnabled int) {
var err error

valueInput := []string{"10"}
Expand Down Expand Up @@ -521,7 +517,6 @@ func generateTestDataWithOperatorAndRevCheck(t *testing.T, desc string, isUserID
IssuerClaimNonRevMtpAuxHv: issuerClaimNonRevAux.Value,
IssuerClaimNonRevMtpNoAux: issuerClaimNonRevAux.NoAux,
ClaimSchema: "180410020913331409885634153623124536270",
ClaimPathNotExists: "0", // 0 for inclusion, 1 for non-inclusion
ClaimPathMtp: claimPathMtp,
ClaimPathMtpNoAux: claimPathMtpNoAux,
ClaimPathMtpAuxHi: claimPathMtpAuxHi,
Expand Down Expand Up @@ -555,38 +550,27 @@ func generateTestDataWithOperatorAndRevCheck(t *testing.T, desc string, isUserID

VerifierID: "21929109382993718606847853573861987353620810345503358891473103689157378049",
NullifierSessionID: nullifierSessionID,
AuthEnabled: authEnabled,
IsBJJAuthEnabled: isBJJAuthEnabled,
}

valuesHash, err := utils.PoseidonHashValue(utils.FromStringArrayToBigIntArray(inputs.Value))
require.NoError(t, err)
claimSchemaInt, ok := big.NewInt(0).SetString(inputs.ClaimSchema, 10)
require.True(t, ok)
circuitQueryHash, err := poseidon.Hash([]*big.Int{
claimSchemaInt,
big.NewInt(int64(inputs.SlotIndex)),
big.NewInt(int64(inputs.Operator)),
pathKey,
big.NewInt(0),
valuesHash,
})
require.NoError(t, err)

linkID, err := utils.CalculateLinkID(linkNonce, claim)
require.NoError(t, err)

operatorOutput := "0"
nullifier := "0"
verifierID, ok := big.NewInt(0).SetString(inputs.VerifierID, 10)
require.True(t, ok)
nullifierSessionID_, ok := big.NewInt(0).SetString(inputs.NullifierSessionID, 10)
require.True(t, ok)
if inputs.NullifierSessionID != "0" {
claimSchema, ok := big.NewInt(0).SetString(inputs.ClaimSchema, 10)
require.True(t, ok)

verifierID, ok := big.NewInt(0).SetString(inputs.VerifierID, 10)
require.True(t, ok)

nullifierSessionID_, ok := big.NewInt(0).SetString(inputs.NullifierSessionID, 10)
require.True(t, ok)

nullifier, err = utils.CalculateNullify(
user.ID.BigInt(),
nonceSubject,
Expand All @@ -597,6 +581,27 @@ func generateTestDataWithOperatorAndRevCheck(t *testing.T, desc string, isUserID
require.NoError(t, err)
}

firstPartQueryHash, err := poseidon.Hash([]*big.Int{
claimSchemaInt,
big.NewInt(int64(inputs.SlotIndex)),
big.NewInt(int64(inputs.Operator)),
pathKey,
big.NewInt(0),
valuesHash,
})
require.NoError(t, err)
merklizedBigInt, ok := big.NewInt(0).SetString(merklized, 10)
require.True(t, ok)
circuitQueryHash, err := poseidon.Hash([]*big.Int{
firstPartQueryHash,
big.NewInt(int64(valueArraySize)),
merklizedBigInt,
big.NewInt(int64(isRevocationChecked)),
verifierID,
nullifierSessionID_,
})
require.NoError(t, err)

if operator == utils.SD {
operatorOutput = big.NewInt(10).String()
}
Expand All @@ -620,15 +625,12 @@ func generateTestDataWithOperatorAndRevCheck(t *testing.T, desc string, isUserID
Merklized: merklized,
Challenge: challenge.String(),
GistRoot: gistRoot.BigInt().String(),
IsRevocationChecked: strconv.Itoa(isRevocationChecked),
ProofType: proofType,
IssuerState: issuerState,
LinkID: linkID,
OperatorOutput: operatorOutput,
VerifierID: inputs.VerifierID,
NullifierSessionID: inputs.NullifierSessionID,
Nullifier: nullifier,
AuthEnabled: strconv.Itoa(authEnabled),
IsBJJAuthEnabled: strconv.Itoa(isBJJAuthEnabled),
}

jsonData, err := json.Marshal(TestData{
Expand Down Expand Up @@ -673,6 +675,7 @@ func generateJSONLD_NON_INCLUSION_TestData(t *testing.T, isUserIDProfile, isSubj
require.NoError(t, err)

jsonP, _, err := mz.Proof(context.Background(), path)
require.NoError(t, err)

claimJSONLDProof, claimJSONLDProofAux := utils.PrepareProof(jsonP, utils.ClaimLevels)

Expand Down Expand Up @@ -758,16 +761,15 @@ func generateJSONLD_NON_INCLUSION_TestData(t *testing.T, isUserIDProfile, isSubj
IssuerAuthState: issuer.State(t).String(),
ClaimSchema: "180410020913331409885634153623124536270",

ClaimPathNotExists: "1", // 0 for inclusion, 1 for non-inclusion
ClaimPathMtp: claimJSONLDProof,
ClaimPathMtpNoAux: claimJSONLDProofAux.NoAux, // 1 if aux node is empty, 0 if non-empty or for inclusion proofs
ClaimPathMtpAuxHi: claimJSONLDProofAux.Key, // 0 for inclusion proof
ClaimPathMtpAuxHv: claimJSONLDProofAux.Value, // 0 for inclusion proof
ClaimPathKey: pathKey.String(), // hash of path in merklized json-ld document
ClaimPathValue: "0", // value in this path in merklized json-ld document
ClaimPathMtp: claimJSONLDProof,
ClaimPathMtpNoAux: claimJSONLDProofAux.NoAux, // 1 if aux node is empty, 0 if non-empty or for inclusion proofs
ClaimPathMtpAuxHi: claimJSONLDProofAux.Key, // 0 for inclusion proof
ClaimPathMtpAuxHv: claimJSONLDProofAux.Value, // 0 for inclusion proof
ClaimPathKey: pathKey.String(), // hash of path in merklized json-ld document
ClaimPathValue: "0", // value in this path in merklized json-ld document
// value in this path in merklized json-ld document

Operator: utils.NOOP,
Operator: utils.NOT_EXISTS,
SlotIndex: 0,
Timestamp: timestamp,
IsRevocationChecked: 1,
Expand All @@ -788,7 +790,7 @@ func generateJSONLD_NON_INCLUSION_TestData(t *testing.T, isUserIDProfile, isSubj
VerifierID: "21929109382993718606847853573861987353620810345503358891473103689157378049",
NullifierSessionID: "0",

AuthEnabled: 1,
IsBJJAuthEnabled: 1,
}

issuerAuthState := issuer.State(t)
Expand All @@ -797,7 +799,8 @@ func generateJSONLD_NON_INCLUSION_TestData(t *testing.T, isUserIDProfile, isSubj
require.NoError(t, err)
claimSchemaInt, ok := big.NewInt(0).SetString(inputs.ClaimSchema, 10)
require.True(t, ok)
circuitQueryHash, err := poseidon.Hash([]*big.Int{

firstPartQueryHash, err := poseidon.Hash([]*big.Int{
claimSchemaInt,
big.NewInt(int64(inputs.SlotIndex)),
big.NewInt(int64(inputs.Operator)),
Expand All @@ -806,6 +809,20 @@ func generateJSONLD_NON_INCLUSION_TestData(t *testing.T, isUserIDProfile, isSubj
valuesHash,
})
require.NoError(t, err)
verifierID, ok := big.NewInt(0).SetString(inputs.VerifierID, 10)
require.True(t, ok)
nullifierSessionID_, ok := big.NewInt(0).SetString(inputs.NullifierSessionID, 10)
require.True(t, ok)

circuitQueryHash, err := poseidon.Hash([]*big.Int{
firstPartQueryHash,
big.NewInt(int64(valueArraySize)),
big.NewInt(1),
big.NewInt(1),
verifierID,
nullifierSessionID_,
})
require.NoError(t, err)

out := Outputs{
RequestID: requestID.String(),
Expand All @@ -818,14 +835,11 @@ func generateJSONLD_NON_INCLUSION_TestData(t *testing.T, isUserIDProfile, isSubj
Challenge: challenge.String(),
GistRoot: gistRoot.BigInt().String(),
IssuerState: issuerAuthState.String(),
IsRevocationChecked: "1",
ProofType: "1",
LinkID: "0",
VerifierID: inputs.VerifierID,
NullifierSessionID: inputs.NullifierSessionID,
OperatorOutput: "0",
Nullifier: "0",
AuthEnabled: "1",
IsBJJAuthEnabled: "1",
}

jsonData, err := json.Marshal(TestData{
Expand Down
Loading

0 comments on commit ef8e494

Please sign in to comment.