Skip to content

Commit

Permalink
Move common code for processing query and modifiers on claim to a sep…
Browse files Browse the repository at this point in the history
…arate template
  • Loading branch information
OBrezhniev committed Dec 6, 2023
1 parent 33290f8 commit d9563d1
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 103 deletions.
88 changes: 88 additions & 0 deletions circuits/lib/query/processQueryWithModifiers.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
pragma circom 2.1.1;

include "../../../node_modules/circomlib/circuits/comparators.circom";
include "query.circom";
include "modifiers.circom";
include "../utils/claimUtils.circom";

template ProcessQueryWithModifiers(claimLevels, valueArraySize){
signal input claimPathNotExists; // 0 for inclusion, 1 for non-inclusion
signal input claimPathMtp[claimLevels];
signal input claimPathMtpNoAux; // 1 if aux node is empty, 0 if non-empty or for inclusion proofs
signal input claimPathMtpAuxHi; // 0 for inclusion proof
signal input claimPathMtpAuxHv; // 0 for inclusion proof
signal input claimPathKey; // hash of path in merklized json-ld document
signal input claimPathValue; // value in this path in merklized json-ld document
signal input slotIndex;
signal input operator;
signal input value[valueArraySize];

signal input issuerClaim[8];
signal input merklized;
signal input merklizedRoot;

// Modifier/Computation Operator output ($sd)
signal output operatorOutput;

// check path/in node exists in merkletree specified by jsonldRoot
SMTVerifier(claimLevels)(
enabled <== merklized, // if merklize flag 0 skip MTP verification
fnc <== claimPathNotExists, // inclusion
root <== merklizedRoot,
siblings <== claimPathMtp,
oldKey <== claimPathMtpAuxHi,
oldValue <== claimPathMtpAuxHv,
isOld0 <== claimPathMtpNoAux,
key <== claimPathKey,
value <== claimPathValue
); // 9585 constraints

// select value from claim by slot index (0-7)
signal slotValue <== getValueByIndex()(issuerClaim, slotIndex);

// select value for query verification,
// if claim is merklized merklizeFlag = `1|2`, take claimPathValue
// if not merklized merklizeFlag = `0`, take value from selected slot
signal fieldValue <== Mux1()(
[slotValue, claimPathValue],
merklized
);

/////////////////////////////////////////////////////////////////
// Query Operator Processing
/////////////////////////////////////////////////////////////////

// verify query
// 1756 constraints (Query+LessThan+ForceEqualIfEnabled)
signal querySatisfied <== Query(valueArraySize)(
in <== fieldValue,
value <== value,
operator <== operator
);

signal isQueryOp <== LessThan(5)([operator, 16]);
ForceEqualIfEnabled()(
isQueryOp,
[querySatisfied, 1]
);

/////////////////////////////////////////////////////////////////
// Modifier/Computation Operators Processing
/////////////////////////////////////////////////////////////////

// selective disclosure
// no need to calc anything, fieldValue is just passed as an output

/////////////////////////////////////////////////////////////////
// Modifier Operator Validation & Output Preparation
/////////////////////////////////////////////////////////////////

// output value only if modifier operation was selected
operatorOutput <== modifierValidatorOutputSelector()(
operator <== operator,
modifierOutputs <== [
fieldValue, // 16 - selective disclosure (16-16 = index 0)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 17-31 - not used
]
);
}
80 changes: 15 additions & 65 deletions circuits/linked/multiQuery.circom
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
pragma circom 2.1.5;

include "../../node_modules/circomlib/circuits/comparators.circom";
include "../lib/query/query.circom";
include "../lib/query/modifiers.circom";
include "../lib/query/processQueryWithModifiers.circom";
include "../lib/linked/linkId.circom";
include "../lib/utils/claimUtils.circom";
include "../lib/utils/safeOne.circom";
Expand Down Expand Up @@ -66,70 +65,21 @@ template LinkedMultiQuery(N, claimLevels, valueArraySize) {
/////////////////////////////////////////////////////////////////
for (var i=0; i<N; i++) {

/////////////////////////////////////////////////////////////////
// Field Path and Value Verification
/////////////////////////////////////////////////////////////////

// check path/in node exists in merkletree specified by jsonldRoot
SMTVerifier(claimLevels)(
enabled <== merklize.flag, // if merklize flag 0 skip MTP verification
fnc <== claimPathNotExists[i], // inclusion
root <== merklize.out,
siblings <== claimPathMtp[i],
oldKey <== claimPathMtpAuxHi[i],
oldValue <== claimPathMtpAuxHv[i],
isOld0 <== claimPathMtpNoAux[i],
key <== claimPathKey[i],
value <== claimPathValue[i]
); // 9585 constraints

// select value from claim by slot index (0-7)
slotValue[i] <== getValueByIndex()(issuerClaim, slotIndex[i]);

// select value for query verification,
// if claim is merklized merklizeFlag = `1|2`, take claimPathValue
// if not merklized merklizeFlag = `0`, take value from selected slot
fieldValue[i] <== Mux1()(
[slotValue[i], claimPathValue[i]],
merklize.flag
);

/////////////////////////////////////////////////////////////////
// Query Operator Processing
/////////////////////////////////////////////////////////////////

// verify query
// 1756 constraints (Query+LessThan+ForceEqualIfEnabled)
querySatisfied[i] <== Query(valueArraySize)(
in <== fieldValue[i],
value <== value[i],
operator <== operator[i]
);

isQueryOp[i] <== LessThan(5)([operator[i], 16]);
ForceEqualIfEnabled()(
isQueryOp[i],
[querySatisfied[i], 1]
);

/////////////////////////////////////////////////////////////////
// Modifier/Computation Operators Processing
/////////////////////////////////////////////////////////////////

// selective disclosure
// no need to calc anything, fieldValue is just passed as an output

/////////////////////////////////////////////////////////////////
// Modifier Operator Validation & Output Preparation
/////////////////////////////////////////////////////////////////

// output value only if modifier operation was selected
operatorOutput[i] <== modifierValidatorOutputSelector()(
operator <== operator[i],
modifierOutputs <== [
fieldValue[i], // 16 - selective disclosure (16-16 = index 0)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 17-31 - not used
]
operatorOutput[i] <== ProcessQueryWithModifiers(claimLevels, valueArraySize)(
claimPathNotExists[i],
claimPathMtp[i],
claimPathMtpNoAux[i],
claimPathMtpAuxHi[i],
claimPathMtpAuxHv[i],
claimPathKey[i],
claimPathValue[i],
slotIndex[i],
operator[i],
value[i],
issuerClaim,
merklized,
merklize.out
);

/////////////////////////////////////////////////////////////////
Expand Down
55 changes: 17 additions & 38 deletions circuits/offchain/credentialAtomicQueryV3OffChain.circom
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ include "../../node_modules/circomlib/circuits/bitify.circom";
include "../../node_modules/circomlib/circuits/comparators.circom";
include "../auth/authV2.circom";
include "../lib/linked/linkId.circom";
include "../lib/query/comparators.circom";
include "../lib/query/modifiers.circom";
include "../lib/query/query.circom";
include "../lib/query/processQueryWithModifiers.circom";
include "../lib/utils/nullify.circom";
include "../lib/utils/idUtils.circom";
include "../lib/utils/safeOne.circom";
Expand Down Expand Up @@ -50,7 +48,6 @@ template credentialAtomicQueryV3OffChain(issuerLevels, claimLevels, valueArraySi
signal input claimPathMtpAuxHv; // 0 for inclusion proof
signal input claimPathKey; // hash of path in merklized json-ld document
signal input claimPathValue; // value in this path in merklized json-ld document

signal input slotIndex;
signal input operator;
signal input value[valueArraySize];
Expand Down Expand Up @@ -231,30 +228,25 @@ template credentialAtomicQueryV3OffChain(issuerLevels, claimLevels, valueArraySi
);

/////////////////////////////////////////////////////////////////
// Query Operator Processing
// Process Query with Modifiers
/////////////////////////////////////////////////////////////////

// verify query
// 1756 constraints (Query+LessThan+ForceEqualIfEnabled)
signal querySatisfied <== Query(valueArraySize)(
in <== fieldValue,
value <== value,
operator <== operator
);

signal isQueryOp <== LessThan(5)([operator, 16]);
ForceEqualIfEnabled()(
isQueryOp,
[querySatisfied, 1]
// output value only if modifier operation was selected
operatorOutput <== ProcessQueryWithModifiers(claimLevels, valueArraySize)(
claimPathNotExists,
claimPathMtp,
claimPathMtpNoAux,
claimPathMtpAuxHi,
claimPathMtpAuxHv,
claimPathKey,
claimPathValue,
slotIndex,
operator,
value,
issuerClaim,
merklized,
merklize.out
);

/////////////////////////////////////////////////////////////////
// Modifier/Computation Operators Processing
/////////////////////////////////////////////////////////////////

// selective disclosure
// no need to calc anything, fieldValue is just passed as an output

// nullifier calculation
nullifier <== Nullify()(
userGenesisID,
Expand All @@ -264,19 +256,6 @@ template credentialAtomicQueryV3OffChain(issuerLevels, claimLevels, valueArraySi
nullifierSessionID
); // 330 constraints

/////////////////////////////////////////////////////////////////
// Modifier Operator Validation & Output Preparation
/////////////////////////////////////////////////////////////////

// output value only if modifier operation was selected
operatorOutput <== modifierValidatorOutputSelector()(
operator <== operator,
modifierOutputs <== [
fieldValue, // 16 - selective disclosure (16-16 = index 0)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 17-31 - not used
]
);

/////////////////////////////////////////////////////////////////
// ProfileID calculation
/////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit d9563d1

Please sign in to comment.