From 24e0ccd2c54190cf9a6a8f3f824771269e995ff5 Mon Sep 17 00:00:00 2001 From: daveroga Date: Fri, 30 Jan 2026 17:13:47 +0100 Subject: [PATCH 1/2] update contract data proofs and readme --- .gitignore | 2 +- README.md | 38 +- compile-circuit.sh | 2 +- testvectorgen/auth/authV3_test.go | 8 +- .../v3-16-16-64-16-32/v3_test.go | 759 ++++++++++++++++++ .../contract_data/{ => v3}/v3_test.go | 32 +- .../credentials/onchain/v3/v3_test.go | 10 +- testvectorgen/utils/constants.go | 14 +- testvectorgen/utils/identity.go | 51 +- ...-contract-data-v3-stable-16-16-64-16-32.js | 48 ++ .../update-contract-data-v3-stable.js | 47 ++ .../update-contract-data-v3.js | 14 +- .../update-contract-data.js | 16 +- 13 files changed, 983 insertions(+), 58 deletions(-) create mode 100644 testvectorgen/contract_data/v3-16-16-64-16-32/v3_test.go rename testvectorgen/contract_data/{ => v3}/v3_test.go (96%) create mode 100644 update-contract-data/update-contract-data-v3-stable-16-16-64-16-32.js create mode 100644 update-contract-data/update-contract-data-v3-stable.js rename update-contract-data-v3.js => update-contract-data/update-contract-data-v3.js (75%) rename update-contract-data.js => update-contract-data/update-contract-data.js (79%) diff --git a/.gitignore b/.gitignore index 78d053ff..52f57eab 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,5 @@ build .idea .vscode .DS_Store -powersOfTau28_hez_final_17.ptau +powersOfTau28_hez_final_*.ptau testvectorgen/**/testdata \ No newline at end of file diff --git a/README.md b/README.md index 0118d5ea..335fdd4f 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,19 @@ The circuits of this repository are compatible with the [go-iden3-core implement # Building and trusted setup -First install the npm dependencies: +1. Install the npm dependencies: ```bash npm ci ``` -Then build the circuit and do the "trusted" setup: +2. Download corresponding powersOfTau file to be able to compile circuits: + +```bash +wget https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_18.ptau +``` + +3. Then build the circuit and do the "trusted" setup: ```bash ./compile-circuit.sh CIRCUIT_PATH PTAU_FILE_PATH @@ -21,8 +27,8 @@ Then build the circuit and do the "trusted" setup: Examples: ```bash -./compile-circuit.sh circuits/auth.circom build/powersOfTau28_hez_final_16.ptau -./compile-circuit.sh circuits/stateTransition.circom build/powersOfTau28_hez_final_16.ptau +./compile-circuit.sh circuits/auth.circom build/powersOfTau28_hez_final_18.ptau +./compile-circuit.sh circuits/stateTransition.circom build/powersOfTau28_hez_final_18.ptau ``` ## Work with `s3_util.js` script @@ -78,5 +84,29 @@ node s3_util.js rm v1 ... ``` +## Generate data folders with JSON files with proofs for contracts repo validators testing + +Scripts for generating the data with proofs for contracts repo for testing are placed in folders `testvectorgen` and `update-contract-data`. +Example: Generate data for v3 tests in contracts repo (you should have the repo cloned in local) + +1. Go to folder `testvectorgen/contract_data/v3` + ```bash + cd testvectorgen/contract_data/v3 + ``` +2. Generate executable for v3 + ```bash + go test -c -o v3_test + ``` +3. Execute inputs data generation for generating proofs + ```bash + ./v3_test + ``` +4. You will see a folder `testdata` generated in the same folder with files with inputs for generating the different proofs. +5. In root folder of the repo you can execute the Node script to generate the JSON files with proofs that will be copied to contracts repo + ```bash + node update-contract-data/update-contract-data-v3-stable.js + ``` +6. You will see in your `../contracts/test/validators/v3/data` and `../contracts/test/validators/common-data` the JSON files generated with the proofs needed for the validators tests in contracts. + ## Security Audits 1. [Trail of Bits](https://github.com/trailofbits/publications/tree/master/reviews) has performed a security audit of our circuits and compiled a report on May 3, 2024: [2024-05-polygonlabs-iden3circuits-securityreview.pdf](https://raw.githubusercontent.com/iden3/audits/adc81d1bce9a7bde9577eb4389998d60cfac9619/circuits/2024-05-polygonlabs-iden3circuits-securityreview.pdf) \ No newline at end of file diff --git a/compile-circuit.sh b/compile-circuit.sh index d47535a5..4ad37b55 100755 --- a/compile-circuit.sh +++ b/compile-circuit.sh @@ -51,7 +51,7 @@ compile_and_ts() { if [ "$#" -ne 2 ] then echo "Usage: $0 CIRCUIT_PATH $1 PTAU_PATH">&2 - echo "Example: ./compile-circuit.sh example.circom powersOfTau28_hez_final_15.ptau" >&2 + echo "Example: ./compile-circuit.sh example.circom powersOfTau28_hez_final_18.ptau" >&2 exit 1 fi diff --git a/testvectorgen/auth/authV3_test.go b/testvectorgen/auth/authV3_test.go index 5585068a..bd7b1920 100644 --- a/testvectorgen/auth/authV3_test.go +++ b/testvectorgen/auth/authV3_test.go @@ -102,8 +102,8 @@ func generateAuthTestData(t *testing.T, profile, genesis, isSecondAuthClaim bool nonce := big.NewInt(0) - challenge := big.NewInt(12345) - + challenge, ok := new(big.Int).SetString("5212973139745638668633720237501954966656555739014896868936311397139229290378", 10) + require.True(t, ok) user := utils.NewIdentity(t, userPK) var err error @@ -117,7 +117,7 @@ func generateAuthTestData(t *testing.T, profile, genesis, isSecondAuthClaim bool gisTree, err := merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), 40) require.Nil(t, err) - gisTree.Add(context.Background(), big.NewInt(1), big.NewInt(1)) + //gisTree.Add(context.Background(), big.NewInt(1), big.NewInt(1)) if genesis == false { // extract pubKey @@ -154,7 +154,7 @@ func generateAuthTestData(t *testing.T, profile, genesis, isSecondAuthClaim bool require.NoError(t, err) gistRoot := gisTree.Root() - gistProof, gistNodAux := utils.PrepareProof(gistProofRaw, utils.GistLevels) + gistProof, gistNodAux := utils.PrepareProof(gistProofRaw, utils.OnChainLevels) inputs := AuthV3Inputs{ UserGenesisID: user.ID.BigInt().String(), diff --git a/testvectorgen/contract_data/v3-16-16-64-16-32/v3_test.go b/testvectorgen/contract_data/v3-16-16-64-16-32/v3_test.go new file mode 100644 index 00000000..36049fb1 --- /dev/null +++ b/testvectorgen/contract_data/v3-16-16-64-16-32/v3_test.go @@ -0,0 +1,759 @@ +package contractdata + +import ( + "context" + "encoding/json" + "math/big" + "strconv" + "testing" + + "test/utils" + + "github.com/ethereum/go-ethereum/common" + core "github.com/iden3/go-iden3-core/v2" + "github.com/iden3/go-iden3-crypto/babyjub" + "github.com/iden3/go-iden3-crypto/poseidon" + "github.com/iden3/go-merkletree-sql/v2" + "github.com/iden3/go-merkletree-sql/v2/db/memory" + "github.com/iden3/go-schema-processor/v2/merklize" + "github.com/iden3/go-schema-processor/v2/verifiable" + "github.com/stretchr/testify/require" +) + +const ( + ethAddress = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + UserPK = "28156abe7fe2fd433dc9df969286b96666489bac508612d0e16593e944c4f69e" + IssuerPK = "28156abe7fe2fd433dc9df969286b96666489bac508612d0e16593e944c4f69d" + timestamp = "1642074362" + requestID = "32" +) + +type StateTransitionInputs struct { + AuthClaim *core.Claim `json:"authClaim"` + AuthClaimMtp []string `json:"authClaimMtp"` + AuthClaimNonRevMtp []string `json:"authClaimNonRevMtp"` + AuthClaimNonRevMtpAuxHi string `json:"authClaimNonRevMtpAuxHi"` + AuthClaimNonRevMtpAuxHv string `json:"authClaimNonRevMtpAuxHv"` + AuthClaimNonRevMtpNoAux string `json:"authClaimNonRevMtpNoAux"` + ClaimsTreeRoot string `json:"claimsTreeRoot"` + IsOldStateGenesis string `json:"isOldStateGenesis"` + NewUserState string `json:"newUserState"` + OldUserState string `json:"oldUserState"` + RevTreeRoot string `json:"revTreeRoot"` + RootsTreeRoot string `json:"rootsTreeRoot"` + SignatureR8X string `json:"signatureR8x"` + SignatureR8Y string `json:"signatureR8y"` + SignatureS string `json:"signatureS"` + UserID string `json:"userID"` + NewAuthClaimMtp []string `json:"newAuthClaimMtp"` + NewClaimsTreeRoot string `json:"newClaimsTreeRoot"` + NewRevTreeRoot string `json:"newRevTreeRoot"` + NewRootsTreeRoot string `json:"newRootsTreeRoot"` +} + +type StateTransitionOutputs struct { + ID string `json:"userID"` + NewUserState string `json:"newUserState"` + OldUserState string `json:"oldUserState"` + IsOldStateGenesis string `json:"isOldStateGenesis"` +} + +type TestDataStateTransition struct { + Desc string `json:"desc"` + In StateTransitionInputs `json:"inputs"` + Out StateTransitionOutputs `json:"expOut"` +} + +type gistData struct { + id *big.Int + state *big.Int +} + +func Test_Generate_Test_CasesV3(t *testing.T) { + + // genesis => first => second + issuerId, issuerFirstState := generateStateTransitionData(t, false, IssuerPK, UserPK, "Issuer from genesis to first state transition", "v3-16-16-64-16-32/issuer_from_genesis_state_to_first_transition_v3", true, false) + userId, userFirstState := generateStateTransitionData(t, false, UserPK, IssuerPK, "User from genesis transition", "v3-16-16-64-16-32/user_from_genesis_state_to_first_transition_v3", false, false) + + _, issuerSecondState := generateStateTransitionData(t, true, IssuerPK, UserPK, "Issuer from first to second transition", "v3-16-16-64-16-32/issuer_from_first_state_to_second_transition_v3", true, false) + _, userSecondState := generateStateTransitionData(t, true, UserPK, IssuerPK, "User from first to second transition", "v3-16-16-64-16-32/user_from_first_state_to_second_transition_v3", false, false) + + _, issuerAuthDisabledFirstState := generateStateTransitionData(t, false, IssuerPK, UserPK, "Issuer from genesis to first state transition auth disabled", "v3-16-16-64-16-32/issuer_from_genesis_state_to_first_auth_disabled_transition_v3", false, true) + + generateData(t, "BJJ: Issuer first state / user - genesis state", []*gistData{ + {issuerId, issuerFirstState}, + }, false, false, false, false, "v3-16-16-64-16-32/valid_bjj_user_genesis_v3", verifiable.BJJSignatureProofType, 1) + + generateData(t, "BJJ: Issuer first state / user first state - valid proof", []*gistData{ + {issuerId, issuerFirstState}, + {userId, userFirstState}, + }, true, false, false, false, "v3-16-16-64-16-32/valid_bjj_user_first_v3", verifiable.BJJSignatureProofType, 1) + + generateData(t, "BJJ: Issuer second state / user first state - valid proof", []*gistData{ + {userId, userFirstState}, + {issuerId, issuerSecondState}, + }, true, false, false, true, "v3-16-16-64-16-32/valid_bjj_user_first_issuer_second_v3", verifiable.BJJSignatureProofType, 1) + + generateData(t, "BJJ: Issuer first state / user second state - valid proof", []*gistData{ + {userId, userSecondState}, + {issuerId, issuerSecondState}, + }, true, true, false, false, "v3-16-16-64-16-32/valid_bjj_user_second_issuer_first_v3", verifiable.BJJSignatureProofType, 1) + + generateData(t, "BJJ: Issuer first state / user - genesis state - Auth Disabled", []*gistData{ + {issuerId, issuerAuthDisabledFirstState}, + }, false, false, false, false, "v3-16-16-64-16-32/valid_bjj_user_genesis_auth_disabled_v3", verifiable.BJJSignatureProofType, 0) + + // MTP Data: + generateData(t, "MTP: Issuer first state / user - genesis state", []*gistData{ + {issuerId, issuerFirstState}, + }, false, false, false, false, "v3-16-16-64-16-32/valid_mtp_user_genesis_v3", verifiable.Iden3SparseMerkleTreeProofType, 1) + + generateData(t, "MTP: Issuer first state / user first state - valid proof", []*gistData{ + {issuerId, issuerFirstState}, + {userId, userFirstState}, + }, true, false, false, false, "v3-16-16-64-16-32/valid_mtp_user_first_v3", verifiable.Iden3SparseMerkleTreeProofType, 1) + + generateData(t, "MTP: Issuer second state / user first state - valid proof", []*gistData{ + {userId, userFirstState}, + {issuerId, issuerSecondState}, + }, true, false, false, true, "v3-16-16-64-16-32/valid_mtp_user_first_issuer_second_v3", verifiable.Iden3SparseMerkleTreeProofType, 1) + + generateData(t, "MTP: Issuer first state / user second state - valid proof", []*gistData{ + {userId, userSecondState}, + {issuerId, issuerSecondState}, + }, true, true, false, false, "v3-16-16-64-16-32/valid_mtp_user_second_issuer_first_v3", verifiable.Iden3SparseMerkleTreeProofType, 1) + + generateData(t, "MTP: Issuer first state / user - genesis state - Auth Disabled", []*gistData{ + {issuerId, issuerAuthDisabledFirstState}, + }, false, false, false, false, "v3-16-16-64-16-32/valid_mtp_user_genesis_auth_disabled_v3", verifiable.Iden3SparseMerkleTreeProofType, 0) + + generateData(t, "BJJ: Issuer genesis state / user - first state", []*gistData{ + {userId, userFirstState}, + }, true, false, true, false, "v3-16-16-64-16-32/valid_bjj_user_first_issuer_genesis_v3", verifiable.BJJSignatureProofType, 1) +} + +func generateStateTransitionData(t *testing.T, nextState bool, primaryPK, secondaryPK, desc, fileName string, isSubjectIDProfile bool, isEthBased bool) (*big.Int, *big.Int) { + + var err error + primaryEntity := utils.NewIdentity(t, primaryPK) + + var secondaryEntity *utils.IdentityTest + + if !isEthBased { + secondaryEntity = utils.NewIdentity(t, secondaryPK) + } else { + // generate onchain identity + secondaryEntity = utils.NewEthereumBasedIdentity(t, ethAddress) + } + + isGenesis := "1" + // user + authMTProof := primaryEntity.AuthMTPStrign(t) + + authNonRevMTProof, nodeAuxNonRev := primaryEntity.ClaimRevMTPLevels(t, primaryEntity.AuthClaim, utils.IdOwnershipLevels2) + + oldState := primaryEntity.State(t) // old state is genesis + oldCltRoot := primaryEntity.Clt.Root().BigInt().String() + oldRevRoot := primaryEntity.Ret.Root().BigInt().String() + oldRotRoot := primaryEntity.Rot.Root().BigInt().String() + + //if genesis == false { + // extract pubKey + + subjectID := secondaryEntity.ID + if isSubjectIDProfile { + nonceSubject := big.NewInt(999) + subjectID, err = core.ProfileID(secondaryEntity.ID, nonceSubject) + require.NoError(t, err) + } + + _, secondaryEntityClaim := utils.DefaultJSONNormalUserClaim(t, subjectID) + primaryEntity.AddClaim(t, secondaryEntityClaim) + + if nextState { + isGenesis = "0" + // add claim just to change the state + + oldState = primaryEntity.State(t) // old state is genesis + oldCltRoot = primaryEntity.Clt.Root().BigInt().String() + oldRevRoot = primaryEntity.Ret.Root().BigInt().String() + oldRotRoot = primaryEntity.Rot.Root().BigInt().String() + authMTProof = primaryEntity.AuthMTPStrign(t) + + authNonRevMTProof, nodeAuxNonRev = primaryEntity.ClaimRevMTPLevels(t, primaryEntity.AuthClaim, utils.IdOwnershipLevels2) + primaryEntityClaim := utils.DefaultUserClaim(t, primaryEntity.ID, nil) + primaryEntity.AddClaim(t, primaryEntityClaim) + } + + hashOldAndNewStates, err := poseidon.Hash( + []*big.Int{oldState, primaryEntity.State(t)}) + require.NoError(t, err) + + sig := primaryEntity.Sign(hashOldAndNewStates) + require.NoError(t, err) + + newAuthMTProof := primaryEntity.AuthMTPStrign(t) + newCltRoot := primaryEntity.Clt.Root().BigInt().String() + newRevRoot := primaryEntity.Ret.Root().BigInt().String() + newRotRoot := primaryEntity.Rot.Root().BigInt().String() + + inputs := StateTransitionInputs{ + AuthClaim: primaryEntity.AuthClaim, + AuthClaimMtp: authMTProof, + AuthClaimNonRevMtp: authNonRevMTProof, + AuthClaimNonRevMtpAuxHi: nodeAuxNonRev.Key, + AuthClaimNonRevMtpAuxHv: nodeAuxNonRev.Value, + AuthClaimNonRevMtpNoAux: nodeAuxNonRev.NoAux, + ClaimsTreeRoot: oldCltRoot, + RevTreeRoot: oldRevRoot, + RootsTreeRoot: oldRotRoot, + IsOldStateGenesis: isGenesis, + NewUserState: primaryEntity.State(t).String(), + OldUserState: oldState.String(), + SignatureR8X: sig.R8.X.String(), + SignatureR8Y: sig.R8.Y.String(), + SignatureS: sig.S.String(), + UserID: primaryEntity.ID.BigInt().String(), + NewAuthClaimMtp: newAuthMTProof, + NewClaimsTreeRoot: newCltRoot, + NewRevTreeRoot: newRevRoot, + NewRootsTreeRoot: newRotRoot, + } + + out := StateTransitionOutputs{ + ID: primaryEntity.ID.BigInt().String(), + NewUserState: primaryEntity.State(t).String(), + OldUserState: oldState.String(), + IsOldStateGenesis: isGenesis, + } + + json_, err := json.Marshal(TestDataStateTransition{ + Desc: desc, + In: inputs, + Out: out, + }) + require.NoError(t, err) + + utils.SaveTestVector(t, fileName, string(json_)) + + return primaryEntity.ID.BigInt(), primaryEntity.State(t) +} + +func generateData(t *testing.T, desc string, gistData []*gistData, userFirstState bool, userSecondState bool, issuetGenesisState bool, issuerSecondState bool, fileName string, testProofType verifiable.ProofType, isBJJAuthEnabled int) { + + var linkNonce = "18" + var nullifierSessionID string = "1234569" + operator := utils.LT + isRevocationChecked := 1 // checked + isJSONLD := true // merklized for now + var err error + + const isRevoked = false + const isSubjectIDProfile = true + + valueInput := utils.PrepareStrArray([]string{"20010101"}, utils.MaxValueArraySize2) + + var user *utils.IdentityTest + + if isBJJAuthEnabled == 1 { + user = utils.NewIdentity(t, UserPK) + } else { + // generate onchain identity + user = utils.NewEthereumBasedIdentity(t, ethAddress) + nullifierSessionID = "0" + } + issuer := utils.NewIdentity(t, IssuerPK) + + userProfileID := user.ID + nonce := big.NewInt(0) + + subjectID := user.ID + + var nonceSubject = new(big.Int) + if isSubjectIDProfile && isBJJAuthEnabled == 1 { + nonceSubject = big.NewInt(999) + subjectID, err = core.ProfileID(user.ID, nonceSubject) + require.NoError(t, err) + } + + var claim *core.Claim + var mz *merklize.Merklizer + var claimPathMtp []string + var claimPathMtpNoAux, claimPathMtpAuxHi, claimPathMtpAuxHv, claimPathKey, claimPathValue, merklized string + var pathKey *big.Int + var slotIndex int + + if isJSONLD { + mz, claim = utils.DefaultJSONNormalUserClaim(t, subjectID) + path, err := merklize.NewPath( + "https://www.w3.org/2018/credentials#credentialSubject", + "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#birthday") + require.NoError(t, err) + jsonP, value, err := mz.Proof(context.Background(), path) + require.NoError(t, err) + valueKey, err := value.MtEntry() + require.NoError(t, err) + claimPathValue = valueKey.String() + + var claimJSONLDProofAux utils.NodeAuxValue + claimPathMtp, claimJSONLDProofAux = utils.PrepareProof(jsonP, utils.ClaimLevels2) + claimPathMtpNoAux = claimJSONLDProofAux.NoAux + claimPathMtpAuxHi = claimJSONLDProofAux.Key + claimPathMtpAuxHv = claimJSONLDProofAux.Value + pathKey, err = path.MtEntry() + require.NoError(t, err) + claimPathKey = pathKey.String() + slotIndex = 0 + + //valueInput = utils.PrepareStrArray([]string{claimPathValue}, 64) + merklized = "1" + + } else { + claim = utils.DefaultUserClaim(t, subjectID, nil) + claimPathMtp = utils.PrepareStrArray([]string{}, utils.ClaimLevels2) + claimPathMtpNoAux = "0" + claimPathMtpAuxHi = "0" + claimPathMtpAuxHv = "0" + claimPathKey = "0" + claimPathValue = "0" + merklized = "0" + slotIndex = 2 + pathKey = big.NewInt(0) + } + + if userFirstState { + _, claim1 := utils.DefaultJSONNormalUserClaim(t, issuer.ID) + user.AddClaim(t, claim1) + + if userSecondState { + claim2 := utils.DefaultUserClaim(t, user.ID, nil) + user.AddClaim(t, claim2) + } + } + + if isRevoked { + revNonce := claim.GetRevocationNonce() + revNonceBigInt := new(big.Int).SetUint64(revNonce) + issuer.Ret.Add(context.Background(), revNonceBigInt, big.NewInt(0)) + } + + var issuerClaimMtp, issuerAuthClaimMtp, issuerAuthClaimNonRevMtp []string + var issuerClaimClaimsTreeRoot, issuerClaimRevTreeRoot, issuerClaimRootsTreeRoot *merkletree.Hash + var issuerClaimSignatureR8X, issuerClaimSignatureR8Y, issuerClaimSignatureS, + issuerAuthClaimNonRevMtpAuxHi, issuerAuthClaimNonRevMtpAuxHv, issuerAuthClaimNonRevMtpNoAux, + issuerClaimIdenState, proofType string + + var issuerAuthClaimsTreeRoot, issuerAuthRevTreeRoot, issuerAuthRootsTreeRoot string + var issuerAuthState string + var issuerAuthClaim *core.Claim + + issuerAuthClaimsTreeRoot = issuer.Clt.Root().BigInt().String() + issuerAuthRevTreeRoot = issuer.Ret.Root().BigInt().String() + issuerAuthRootsTreeRoot = issuer.Rot.Root().BigInt().String() + + issuerAuthState = issuer.State(t).String() + + issuerAuthClaimMtp, _ = issuer.ClaimMTPLevels(t, issuer.AuthClaim, utils.IssuerLevels2) + + if !issuetGenesisState { + issuer.AddClaim(t, claim) + } + + issuerClaimMtp, _ = issuer.ClaimMTPLevels(t, claim, utils.IssuerLevels2) + require.NoError(t, err) + issuerClaimIdenState = issuer.State(t).String() + + issuerClaimClaimsTreeRoot = issuer.Clt.Root() + issuerClaimRevTreeRoot = issuer.Ret.Root() + issuerClaimRootsTreeRoot = issuer.Rot.Root() + + // add another claim to issuer if it is a second state + if issuerSecondState { + primaryEntityClaim := utils.DefaultUserClaim(t, issuer.ID, nil) + issuer.AddClaim(t, primaryEntityClaim) + } + + // prove revocation on latest state of the issuer + issuerClaimNonRevMtp, issuerClaimNonRevAux := issuer.ClaimRevMTPLevels(t, claim, utils.IssuerLevels2) + + issuerAuthClaimNonRevMtp, issuerAuthClaimNodeAux := issuer.ClaimRevMTPLevels(t, issuer.AuthClaim, utils.IssuerLevels2) + issuerAuthClaimNonRevMtpNoAux = issuerAuthClaimNodeAux.NoAux + issuerAuthClaimNonRevMtpAuxHi = issuerAuthClaimNodeAux.Key + issuerAuthClaimNonRevMtpAuxHv = issuerAuthClaimNodeAux.Value + + if testProofType == verifiable.BJJSignatureProofType { + // Sig claim + claimSig := issuer.SignClaim(t, claim) + + issuerClaimSignatureR8X = claimSig.R8.X.String() + issuerClaimSignatureR8Y = claimSig.R8.Y.String() + issuerClaimSignatureS = claimSig.S.String() + + issuerAuthClaim = issuer.AuthClaim + + proofType = "1" + } else { + + issuerClaimSignatureR8X = "0" + issuerClaimSignatureR8Y = "0" + issuerClaimSignatureS = "0" + + issuerAuthClaimNonRevMtpAuxHi = "0" + issuerAuthClaimNonRevMtpAuxHv = "0" + issuerAuthClaimNonRevMtpNoAux = "0" + + issuerAuthClaimMtp = utils.PrepareStrArray([]string{}, utils.IssuerLevels2) + + issuerAuthClaim = &core.Claim{} + + issuerAuthClaimsTreeRoot = (&merkletree.HashZero).BigInt().String() + issuerAuthRevTreeRoot = (&merkletree.HashZero).BigInt().String() + issuerAuthRootsTreeRoot = (&merkletree.HashZero).BigInt().String() + + issuerAuthState = "0" + + slotIndex = 2 + proofType = "2" + } + + gisTree, err := merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), utils.OnChainLevels2) + require.Nil(t, err) + + for _, data := range gistData { + idPoseidonHash, _ := poseidon.Hash([]*big.Int{data.id}) + err = gisTree.Add(context.Background(), idPoseidonHash, data.state) + require.Nil(t, err) + } + + var authMTProof []string + var challenge *big.Int + var userAuthNonRevMTProof []string + var userNodeAuxNonRev utils.NodeAuxValue + var sig *babyjub.Signature + var gistRoot *merkletree.Hash + var gistProof []string + var gistNodeAux utils.NodeAuxValue + + addr := common.HexToAddress(ethAddress) + challenge = new(big.Int).SetBytes(merkletree.SwapEndianness(addr.Bytes())) + + // user + if isBJJAuthEnabled == 1 { + authMTProof = user.AuthMTPStrignLevels(t, utils.IdOwnershipLevels2) + userAuthNonRevMTProof, userNodeAuxNonRev = user.ClaimRevMTPLevels(t, user.AuthClaim, utils.IdOwnershipLevels2) + sig = user.Sign(challenge) + gistProofRaw, _, err := gisTree.GenerateProof(context.Background(), user.IDHash(t), nil) + require.NoError(t, err) + gistRoot = gisTree.Root() + gistProof, gistNodeAux = utils.PrepareProof(gistProofRaw, utils.OnChainLevels2) + + } else { + + emptyArr := make([]*merkletree.Hash, 0) + authMTProof = utils.PrepareSiblingsStr(emptyArr, utils.IssuerLevels2) + userAuthNonRevMTProof = utils.PrepareSiblingsStr(emptyArr, utils.IssuerLevels2) + userNodeAuxNonRev = utils.NodeAuxValue{ + Key: merkletree.HashZero.String(), + Value: merkletree.HashZero.String(), + NoAux: "0", + } + sig = &babyjub.Signature{ + R8: &babyjub.Point{ + X: new(big.Int), + Y: new(big.Int), + }, + S: new(big.Int), + } + + gistRoot = &merkletree.HashZero + gistProof = utils.PrepareSiblingsStr(emptyArr, utils.OnChainLevels2) + gistNodeAux = utils.NodeAuxValue{ + Key: merkletree.HashZero.String(), + Value: merkletree.HashZero.String(), + NoAux: "0", + } + + user.AuthClaim = &core.Claim{} + } + t.Log(issuer.State(t).String()) + valueArraySize := utils.GetValueArraySizeForOperator(operator) + + inputs := Inputs{ + RequestID: requestID, + UserGenesisID: user.ID.BigInt().String(), + ProfileNonce: nonce.String(), + UserAuthClaim: user.AuthClaim, + UserAuthClaimMtp: authMTProof, + UserAuthClaimNonRevMtp: userAuthNonRevMTProof, + UserAuthClaimNonRevMtpAuxHi: userNodeAuxNonRev.Key, + UserAuthClaimNonRevMtpAuxHv: userNodeAuxNonRev.Value, + UserAuthClaimNonRevMtpNoAux: userNodeAuxNonRev.NoAux, + Challenge: challenge.String(), + ChallengeSignatureR8X: sig.R8.X.String(), + ChallengeSignatureR8Y: sig.R8.Y.String(), + ChallengeSignatureS: sig.S.String(), + UserClaimsTreeRoot: user.Clt.Root().BigInt().String(), + UserRevTreeRoot: user.Ret.Root().BigInt().String(), + UserRootsTreeRoot: user.Rot.Root().BigInt().String(), + UserState: user.State(t).String(), + GistRoot: gistRoot.BigInt().String(), + GistMtp: gistProof, + GistMtpAuxHi: gistNodeAux.Key, + GistMtpAuxHv: gistNodeAux.Value, + GistMtpNoAux: gistNodeAux.NoAux, + ClaimSubjectProfileNonce: nonceSubject.String(), + IssuerID: issuer.ID.BigInt().String(), + IssuerClaim: claim, + IssuerClaimMtp: issuerClaimMtp, + IssuerClaimClaimsTreeRoot: issuerClaimClaimsTreeRoot, + IssuerClaimRevTreeRoot: issuerClaimRevTreeRoot, + IssuerClaimRootsTreeRoot: issuerClaimRootsTreeRoot, + IssuerClaimIdenState: issuerClaimIdenState, + IssuerClaimNonRevClaimsTreeRoot: issuer.Clt.Root(), + IssuerClaimNonRevRevTreeRoot: issuer.Ret.Root(), + IssuerClaimNonRevRootsTreeRoot: issuer.Rot.Root(), + IssuerClaimNonRevState: issuer.State(t).String(), + IssuerClaimNonRevMtp: issuerClaimNonRevMtp, + IssuerClaimNonRevMtpAuxHi: issuerClaimNonRevAux.Key, + IssuerClaimNonRevMtpAuxHv: issuerClaimNonRevAux.Value, + IssuerClaimNonRevMtpNoAux: issuerClaimNonRevAux.NoAux, + ClaimSchema: "267831521922558027206082390043321796944", + ClaimPathMtp: claimPathMtp, + ClaimPathMtpNoAux: claimPathMtpNoAux, + ClaimPathMtpAuxHi: claimPathMtpAuxHi, + ClaimPathMtpAuxHv: claimPathMtpAuxHv, + ClaimPathKey: claimPathKey, + ClaimPathValue: claimPathValue, + IsRevocationChecked: isRevocationChecked, + Operator: operator, + SlotIndex: slotIndex, + Timestamp: timestamp, + Value: valueInput, + ValueArraySize: valueArraySize, + IssuerClaimSignatureR8X: issuerClaimSignatureR8X, + IssuerClaimSignatureR8Y: issuerClaimSignatureR8Y, + IssuerClaimSignatureS: issuerClaimSignatureS, + IssuerAuthClaim: issuerAuthClaim, + IssuerAuthClaimMtp: issuerAuthClaimMtp, + IssuerAuthClaimNonRevMtp: issuerAuthClaimNonRevMtp, + IssuerAuthClaimNonRevMtpAuxHi: issuerAuthClaimNonRevMtpAuxHi, + IssuerAuthClaimNonRevMtpAuxHv: issuerAuthClaimNonRevMtpAuxHv, + IssuerAuthClaimNonRevMtpNoAux: issuerAuthClaimNonRevMtpNoAux, + IssuerAuthClaimsTreeRoot: issuerAuthClaimsTreeRoot, + IssuerAuthRevTreeRoot: issuerAuthRevTreeRoot, + IssuerAuthRootsTreeRoot: issuerAuthRootsTreeRoot, + IssuerAuthState: issuerAuthState, + + LinkNonce: linkNonce, + + ProofType: proofType, + + VerifierID: "21929109382993718606847853573861987353620810345503358891473103689157378049", + NullifierSessionID: nullifierSessionID, + 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) + + 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) + + nullifier, err = utils.CalculateNullify( + user.ID.BigInt(), + nonceSubject, + claimSchema, + verifierID, + nullifierSessionID_, + ) + require.NoError(t, err) + } + merklizedBigInt, ok := big.NewInt(0).SetString(merklized, 10) + + firstPartQueryHash, err := poseidon.Hash([]*big.Int{ + claimSchemaInt, + big.NewInt(int64(inputs.SlotIndex)), + big.NewInt(int64(inputs.Operator)), + pathKey, + merklizedBigInt, + valuesHash, + }) + require.NoError(t, err) + require.True(t, ok) + circuitQueryHash, err := poseidon.Hash([]*big.Int{ + firstPartQueryHash, + big.NewInt(int64(valueArraySize)), + big.NewInt(int64(isRevocationChecked)), + verifierID, + nullifierSessionID_, + new(big.Int), + }) + require.NoError(t, err) + + if operator == utils.SD { + operatorOutput = big.NewInt(10).String() + } + + var issuerState string + if proofType == "1" { + // sig + issuerState = issuerAuthState + } else { + // mtp + issuerState = issuerClaimIdenState + } + + out := Outputs{ + RequestID: requestID, + UserID: userProfileID.BigInt().String(), + IssuerID: issuer.ID.BigInt().String(), + IssuerClaimNonRevState: issuer.State(t).String(), + CircuitQueryHash: circuitQueryHash.String(), + Timestamp: timestamp, + Merklized: merklized, + Challenge: challenge.String(), + GistRoot: gistRoot.BigInt().String(), + ProofType: proofType, + IssuerState: issuerState, + LinkID: linkID, + OperatorOutput: operatorOutput, + Nullifier: nullifier, + IsBJJAuthEnabled: strconv.Itoa(isBJJAuthEnabled), + } + + jsonData, err := json.Marshal(TestData{ + desc, + inputs, + out, + }) + require.NoError(t, err) + + utils.SaveTestVector(t, fileName, string(jsonData)) +} + +type Inputs struct { + RequestID string `json:"requestID"` + + // user data + UserGenesisID string `json:"userGenesisID"` // + ProfileNonce string `json:"profileNonce"` // + ClaimSubjectProfileNonce string `json:"claimSubjectProfileNonce"` // + + UserAuthClaim *core.Claim `json:"authClaim"` + UserAuthClaimMtp []string `json:"authClaimIncMtp"` + UserAuthClaimNonRevMtp []string `json:"authClaimNonRevMtp"` + UserAuthClaimNonRevMtpAuxHi string `json:"authClaimNonRevMtpAuxHi"` + UserAuthClaimNonRevMtpAuxHv string `json:"authClaimNonRevMtpAuxHv"` + UserAuthClaimNonRevMtpNoAux string `json:"authClaimNonRevMtpNoAux"` + Challenge string `json:"challenge"` + ChallengeSignatureR8X string `json:"challengeSignatureR8x"` + ChallengeSignatureR8Y string `json:"challengeSignatureR8y"` + ChallengeSignatureS string `json:"challengeSignatureS"` + UserClaimsTreeRoot string `json:"userClaimsTreeRoot"` + UserRevTreeRoot string `json:"userRevTreeRoot"` + UserRootsTreeRoot string `json:"userRootsTreeRoot"` + UserState string `json:"userState"` + GistRoot string `json:"gistRoot"` + GistMtp []string `json:"gistMtp"` + GistMtpAuxHi string `json:"gistMtpAuxHi"` + GistMtpAuxHv string `json:"gistMtpAuxHv"` + GistMtpNoAux string `json:"gistMtpNoAux"` + + IssuerID string `json:"issuerID"` + // Claim + IssuerClaim *core.Claim `json:"issuerClaim"` + // Inclusion + IssuerClaimMtp []string `json:"issuerClaimMtp"` + IssuerClaimClaimsTreeRoot *merkletree.Hash `json:"issuerClaimClaimsTreeRoot"` + IssuerClaimRevTreeRoot *merkletree.Hash `json:"issuerClaimRevTreeRoot"` + IssuerClaimRootsTreeRoot *merkletree.Hash `json:"issuerClaimRootsTreeRoot"` + IssuerClaimIdenState string `json:"issuerClaimIdenState"` + + IsRevocationChecked int `json:"isRevocationChecked"` + IssuerClaimNonRevClaimsTreeRoot *merkletree.Hash `json:"issuerClaimNonRevClaimsTreeRoot"` + IssuerClaimNonRevRevTreeRoot *merkletree.Hash `json:"issuerClaimNonRevRevTreeRoot"` + IssuerClaimNonRevRootsTreeRoot *merkletree.Hash `json:"issuerClaimNonRevRootsTreeRoot"` + IssuerClaimNonRevState string `json:"issuerClaimNonRevState"` + IssuerClaimNonRevMtp []string `json:"issuerClaimNonRevMtp"` + IssuerClaimNonRevMtpAuxHi string `json:"issuerClaimNonRevMtpAuxHi"` + IssuerClaimNonRevMtpAuxHv string `json:"issuerClaimNonRevMtpAuxHv"` + IssuerClaimNonRevMtpNoAux string `json:"issuerClaimNonRevMtpNoAux"` + + ClaimSchema string `json:"claimSchema"` + + // Query + // JSON path + 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 + ClaimPathValue string `json:"claimPathValue"` // value in this path in merklized json-ld document + ClaimPathKey string `json:"claimPathKey"` // hash of path in merklized json-ld document + + Operator int `json:"operator"` + SlotIndex int `json:"slotIndex"` + Timestamp string `json:"timestamp"` + Value []string `json:"value"` + ValueArraySize int `json:"valueArraySize"` + + // additional sig inputs + IssuerClaimSignatureR8X string `json:"issuerClaimSignatureR8x"` + IssuerClaimSignatureR8Y string `json:"issuerClaimSignatureR8y"` + IssuerClaimSignatureS string `json:"issuerClaimSignatureS"` + IssuerAuthClaim *core.Claim `json:"issuerAuthClaim"` + IssuerAuthClaimMtp []string `json:"issuerAuthClaimMtp"` + IssuerAuthClaimNonRevMtp []string `json:"issuerAuthClaimNonRevMtp"` + IssuerAuthClaimNonRevMtpAuxHi string `json:"issuerAuthClaimNonRevMtpAuxHi"` + IssuerAuthClaimNonRevMtpAuxHv string `json:"issuerAuthClaimNonRevMtpAuxHv"` + IssuerAuthClaimNonRevMtpNoAux string `json:"issuerAuthClaimNonRevMtpNoAux"` + IssuerAuthClaimsTreeRoot string `json:"issuerAuthClaimsTreeRoot"` + IssuerAuthRevTreeRoot string `json:"issuerAuthRevTreeRoot"` + IssuerAuthRootsTreeRoot string `json:"issuerAuthRootsTreeRoot"` + IssuerAuthState string `json:"issuerAuthState"` + + ProofType string `json:"proofType"` // 1 for sig, 2 for mtp + + // Private random nonce, used to generate LinkID + LinkNonce string `json:"linkNonce"` + + VerifierID string `json:"verifierID"` + NullifierSessionID string `json:"nullifierSessionID"` + + IsBJJAuthEnabled int `json:"isBJJAuthEnabled"` +} + +type Outputs struct { + RequestID string `json:"requestID"` + UserID string `json:"userID"` + IssuerID string `json:"issuerID"` + IssuerClaimNonRevState string `json:"issuerClaimNonRevState"` + CircuitQueryHash string `json:"circuitQueryHash"` + GistRoot string `json:"gistRoot"` + Timestamp string `json:"timestamp"` + Merklized string `json:"merklized"` + ProofType string `json:"proofType"` // 1 for sig, 2 for mtp + Challenge string `json:"challenge"` + IssuerState string `json:"issuerState"` + LinkID string `json:"linkID"` + OperatorOutput string `json:"operatorOutput"` + Nullifier string `json:"nullifier"` + IsBJJAuthEnabled string `json:"isBJJAuthEnabled"` +} + +type TestData struct { + Desc string `json:"desc"` + In Inputs `json:"inputs"` + Out Outputs `json:"expOut"` +} diff --git a/testvectorgen/contract_data/v3_test.go b/testvectorgen/contract_data/v3/v3_test.go similarity index 96% rename from testvectorgen/contract_data/v3_test.go rename to testvectorgen/contract_data/v3/v3_test.go index 45b9d8b4..36d7afcb 100644 --- a/testvectorgen/contract_data/v3_test.go +++ b/testvectorgen/contract_data/v3/v3_test.go @@ -150,7 +150,7 @@ func generateStateTransitionData(t *testing.T, nextState bool, primaryPK, second // user authMTProof := primaryEntity.AuthMTPStrign(t) - authNonRevMTProof, nodeAuxNonRev := primaryEntity.ClaimRevMTP(t, primaryEntity.AuthClaim) + authNonRevMTProof, nodeAuxNonRev := primaryEntity.ClaimRevMTPLevels(t, primaryEntity.AuthClaim, utils.IdOwnershipLevels) oldState := primaryEntity.State(t) // old state is genesis oldCltRoot := primaryEntity.Clt.Root().BigInt().String() @@ -180,7 +180,7 @@ func generateStateTransitionData(t *testing.T, nextState bool, primaryPK, second oldRotRoot = primaryEntity.Rot.Root().BigInt().String() authMTProof = primaryEntity.AuthMTPStrign(t) - authNonRevMTProof, nodeAuxNonRev = primaryEntity.ClaimRevMTP(t, primaryEntity.AuthClaim) + authNonRevMTProof, nodeAuxNonRev = primaryEntity.ClaimRevMTPLevels(t, primaryEntity.AuthClaim, utils.IdOwnershipLevels) primaryEntityClaim := utils.DefaultUserClaim(t, primaryEntity.ID, nil) primaryEntity.AddClaim(t, primaryEntityClaim) } @@ -251,7 +251,7 @@ func generateData(t *testing.T, desc string, gistData []*gistData, userFirstStat const isRevoked = false const isSubjectIDProfile = true - valueInput := utils.PrepareStrArray([]string{"20010101"}, 64) + valueInput := utils.PrepareStrArray([]string{"20010101"}, utils.MaxValueArraySize) var user *utils.IdentityTest @@ -310,7 +310,7 @@ func generateData(t *testing.T, desc string, gistData []*gistData, userFirstStat } else { claim = utils.DefaultUserClaim(t, subjectID, nil) - claimPathMtp = utils.PrepareStrArray([]string{}, 32) + claimPathMtp = utils.PrepareStrArray([]string{}, utils.ClaimLevels) claimPathMtpNoAux = "0" claimPathMtpAuxHi = "0" claimPathMtpAuxHv = "0" @@ -353,13 +353,13 @@ func generateData(t *testing.T, desc string, gistData []*gistData, userFirstStat issuerAuthState = issuer.State(t).String() - issuerAuthClaimMtp, _ = issuer.ClaimMTP(t, issuer.AuthClaim) + issuerAuthClaimMtp, _ = issuer.ClaimMTPLevels(t, issuer.AuthClaim, utils.IssuerLevels) if !issuetGenesisState { issuer.AddClaim(t, claim) } - issuerClaimMtp, _ = issuer.ClaimMTP(t, claim) + issuerClaimMtp, _ = issuer.ClaimMTPLevels(t, claim, utils.IssuerLevels) require.NoError(t, err) issuerClaimIdenState = issuer.State(t).String() @@ -374,9 +374,9 @@ func generateData(t *testing.T, desc string, gistData []*gistData, userFirstStat } // prove revocation on latest state of the issuer - issuerClaimNonRevMtp, issuerClaimNonRevAux := issuer.ClaimRevMTP(t, claim) + issuerClaimNonRevMtp, issuerClaimNonRevAux := issuer.ClaimRevMTPLevels(t, claim, utils.IssuerLevels) - issuerAuthClaimNonRevMtp, issuerAuthClaimNodeAux := issuer.ClaimRevMTP(t, issuer.AuthClaim) + issuerAuthClaimNonRevMtp, issuerAuthClaimNodeAux := issuer.ClaimRevMTPLevels(t, issuer.AuthClaim, utils.IssuerLevels) issuerAuthClaimNonRevMtpNoAux = issuerAuthClaimNodeAux.NoAux issuerAuthClaimNonRevMtpAuxHi = issuerAuthClaimNodeAux.Key issuerAuthClaimNonRevMtpAuxHv = issuerAuthClaimNodeAux.Value @@ -402,7 +402,7 @@ func generateData(t *testing.T, desc string, gistData []*gistData, userFirstStat issuerAuthClaimNonRevMtpAuxHv = "0" issuerAuthClaimNonRevMtpNoAux = "0" - issuerAuthClaimMtp = utils.PrepareStrArray([]string{}, 40) + issuerAuthClaimMtp = utils.PrepareStrArray([]string{}, utils.IssuerLevels) issuerAuthClaim = &core.Claim{} @@ -416,7 +416,7 @@ func generateData(t *testing.T, desc string, gistData []*gistData, userFirstStat proofType = "2" } - gisTree, err := merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), 64) + gisTree, err := merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), utils.OnChainLevels) require.Nil(t, err) for _, data := range gistData { @@ -439,19 +439,19 @@ func generateData(t *testing.T, desc string, gistData []*gistData, userFirstStat // user if isBJJAuthEnabled == 1 { - authMTProof = user.AuthMTPStrign(t) - userAuthNonRevMTProof, userNodeAuxNonRev = user.ClaimRevMTP(t, user.AuthClaim) + authMTProof = user.AuthMTPStrignLevels(t, utils.IdOwnershipLevels) + userAuthNonRevMTProof, userNodeAuxNonRev = user.ClaimRevMTPLevels(t, user.AuthClaim, utils.IdOwnershipLevels) sig = user.Sign(challenge) gistProofRaw, _, err := gisTree.GenerateProof(context.Background(), user.IDHash(t), nil) require.NoError(t, err) gistRoot = gisTree.Root() - gistProof, gistNodeAux = utils.PrepareProof(gistProofRaw, utils.GistLevels) + gistProof, gistNodeAux = utils.PrepareProof(gistProofRaw, utils.OnChainLevels) } else { emptyArr := make([]*merkletree.Hash, 0) - authMTProof = utils.PrepareSiblingsStr(emptyArr, utils.IdentityTreeLevels) - userAuthNonRevMTProof = utils.PrepareSiblingsStr(emptyArr, utils.IdentityTreeLevels) + authMTProof = utils.PrepareSiblingsStr(emptyArr, utils.IssuerLevels) + userAuthNonRevMTProof = utils.PrepareSiblingsStr(emptyArr, utils.IssuerLevels) userNodeAuxNonRev = utils.NodeAuxValue{ Key: merkletree.HashZero.String(), Value: merkletree.HashZero.String(), @@ -466,7 +466,7 @@ func generateData(t *testing.T, desc string, gistData []*gistData, userFirstStat } gistRoot = &merkletree.HashZero - gistProof = utils.PrepareSiblingsStr(emptyArr, utils.GistLevels) + gistProof = utils.PrepareSiblingsStr(emptyArr, utils.OnChainLevels) gistNodeAux = utils.NodeAuxValue{ Key: merkletree.HashZero.String(), Value: merkletree.HashZero.String(), diff --git a/testvectorgen/credentials/onchain/v3/v3_test.go b/testvectorgen/credentials/onchain/v3/v3_test.go index cee317b5..ac5681b5 100644 --- a/testvectorgen/credentials/onchain/v3/v3_test.go +++ b/testvectorgen/credentials/onchain/v3/v3_test.go @@ -489,15 +489,15 @@ func generateTestDataWithOperatorAndRevCheck(t *testing.T, desc string, isUserID gistProofRaw, _, err := gisTree.GenerateProof(context.Background(), user.IDHash(t), nil) require.NoError(t, err) gistRoot = gisTree.Root() - gistProof, gistNodeAux = utils.PrepareProof(gistProofRaw, utils.GistLevels) + gistProof, gistNodeAux = utils.PrepareProof(gistProofRaw, utils.OnChainLevels) } else { emptyArr := make([]*merkletree.Hash, 0) addr := common.HexToAddress(ethAddress) challenge = new(big.Int).SetBytes(merkletree.SwapEndianness(addr.Bytes())) - authMTProof = utils.PrepareSiblingsStr(emptyArr, utils.IdentityTreeLevels) - authNonRevMTProof = utils.PrepareSiblingsStr(emptyArr, utils.IdentityTreeLevels) + authMTProof = utils.PrepareSiblingsStr(emptyArr, utils.IssuerLevels) + authNonRevMTProof = utils.PrepareSiblingsStr(emptyArr, utils.IssuerLevels) user.AuthClaim, err = core.NewClaim(core.AuthSchemaHash) require.NoError(t, err) nodeAuxNonRev = utils.NodeAuxValue{ @@ -514,7 +514,7 @@ func generateTestDataWithOperatorAndRevCheck(t *testing.T, desc string, isUserID } gistRoot = &merkletree.HashZero - gistProof = utils.PrepareSiblingsStr(emptyArr, utils.GistLevels) + gistProof = utils.PrepareSiblingsStr(emptyArr, utils.OnChainLevels) gistNodeAux = utils.NodeAuxValue{ Key: merkletree.HashZero.String(), Value: merkletree.HashZero.String(), @@ -752,7 +752,7 @@ func generateJSONLD_NON_INCLUSION_TestData(t *testing.T, isUserIDProfile, isSubj require.NoError(t, err) gistRoot := gisTree.Root() - gistProof, gistNodAux := utils.PrepareProof(gistProofRaw, utils.GistLevels) + gistProof, gistNodAux := utils.PrepareProof(gistProofRaw, utils.OnChainLevels) valueArraySize := utils.GetValueArraySizeForOperator(utils.EXISTS) diff --git a/testvectorgen/utils/constants.go b/testvectorgen/utils/constants.go index baf35dfc..8728ddf5 100644 --- a/testvectorgen/utils/constants.go +++ b/testvectorgen/utils/constants.go @@ -87,7 +87,15 @@ const TestNormalClaimDocument = ` }}` const ( - IdentityTreeLevels = 40 - GistLevels = 64 - ClaimLevels = 32 + IssuerLevels = 40 + ClaimLevels = 32 + MaxValueArraySize = 64 + IdOwnershipLevels = 40 + OnChainLevels = 64 + + IssuerLevels2 = 16 + ClaimLevels2 = 16 + MaxValueArraySize2 = 64 + IdOwnershipLevels2 = 16 + OnChainLevels2 = 32 ) diff --git a/testvectorgen/utils/identity.go b/testvectorgen/utils/identity.go index 6bcf079b..3bb5f595 100644 --- a/testvectorgen/utils/identity.go +++ b/testvectorgen/utils/identity.go @@ -36,7 +36,12 @@ func (it *IdentityTest) State(t testing.TB) *big.Int { func (it *IdentityTest) AuthMTPStrign(t testing.TB) []string { p, _ := it.ClaimMTPRaw(t, it.AuthClaim) - return PrepareSiblingsStr(p.AllSiblings(), IdentityTreeLevels) + return PrepareSiblingsStr(p.AllSiblings(), IssuerLevels) +} + +func (it *IdentityTest) AuthMTPStrignLevels(t testing.TB, levels int) []string { + p, _ := it.ClaimMTPRaw(t, it.AuthClaim) + return PrepareSiblingsStr(p.AllSiblings(), levels) } func (it *IdentityTest) SignClaim(t testing.TB, claim *core.Claim) *babyjub.Signature { @@ -79,7 +84,22 @@ func (it *IdentityTest) ClaimMTP(t testing.TB, claim *core.Claim) (sibling []str t.Fatalf("can't generate proof %v", err) } - return PrepareProof(proof, IdentityTreeLevels) + return PrepareProof(proof, IssuerLevels) +} + +func (it *IdentityTest) ClaimMTPLevels(t testing.TB, claim *core.Claim, levels int) (sibling []string, nodeAux NodeAuxValue) { + // add auth claim to claimsMT + hi, _, err := claim.HiHv() + if err != nil { + t.Fatalf("can't get claim index hash %v", err) + } + + proof, _, err := it.Clt.GenerateProof(context.Background(), hi, nil) + if err != nil { + t.Fatalf("can't generate proof %v", err) + } + + return PrepareProof(proof, levels) } func (it *IdentityTest) ClaimRevMTPRaw(t testing.TB, claim *core.Claim) (*merkletree.Proof, *big.Int) { @@ -102,7 +122,20 @@ func (it *IdentityTest) ClaimRevMTP(t testing.TB, claim *core.Claim) (sibling [] t.Fatalf("can't generate proof %v", err) } - return PrepareProof(proof, IdentityTreeLevels) + return PrepareProof(proof, IssuerLevels) + +} + +func (it *IdentityTest) ClaimRevMTPLevels(t testing.TB, claim *core.Claim, levels int) (sibling []string, nodeAux NodeAuxValue) { + // add auth claim to claimsMT + revNonce := claim.GetRevocationNonce() + + proof, _, err := it.Ret.GenerateProof(context.Background(), new(big.Int).SetUint64(revNonce), nil) + if err != nil { + t.Fatalf("can't generate proof %v", err) + } + + return PrepareProof(proof, levels) } @@ -134,15 +167,15 @@ func NewIdentity(t testing.TB, privKHex string) *IdentityTest { // init claims tree - it.Clt, err = merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), IdentityTreeLevels) + it.Clt, err = merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), IssuerLevels) if err != nil { t.Fatalf("Error creating Claims merkle tree: %v", err) } - it.Ret, err = merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), IdentityTreeLevels) + it.Ret, err = merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), IssuerLevels) if err != nil { t.Fatalf("Error creating Revocation merkle tree: %v", err) } - it.Rot, err = merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), IdentityTreeLevels) + it.Rot, err = merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), IssuerLevels) if err != nil { t.Fatalf("Error creating Roots merkle tree: %v", err) } @@ -179,15 +212,15 @@ func NewEthereumBasedIdentity(t testing.TB, ethAddr string) *IdentityTest { // init claims tree - it.Clt, err = merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), IdentityTreeLevels) + it.Clt, err = merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), IssuerLevels) if err != nil { t.Fatalf("Error creating Claims merkle tree: %v", err) } - it.Ret, err = merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), IdentityTreeLevels) + it.Ret, err = merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), IssuerLevels) if err != nil { t.Fatalf("Error creating Revocation merkle tree: %v", err) } - it.Rot, err = merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), IdentityTreeLevels) + it.Rot, err = merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), IssuerLevels) if err != nil { t.Fatalf("Error creating Roots merkle tree: %v", err) } diff --git a/update-contract-data/update-contract-data-v3-stable-16-16-64-16-32.js b/update-contract-data/update-contract-data-v3-stable-16-16-64-16-32.js new file mode 100644 index 00000000..8aba2197 --- /dev/null +++ b/update-contract-data/update-contract-data-v3-stable-16-16-64-16-32.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const path = require('path'); +const dataFolder = path.join(__dirname, '../testvectorgen/contract_data/v3-16-16-64-16-32/testdata/v3-16-16-64-16-32'); +const contractDataBaseFolder = path.join(__dirname, '../../contracts/test/validators/'); +const buildFolder = path.join(__dirname, '../build/'); +const { execSync } = require('child_process'); + +const files = fs.readdirSync(dataFolder); + +let circuitName = null; +let destinationFolder = null; +for (const file of files) { + + + if (file.includes('state')) { + continue; + //circuitName = 'stateTransition' + //destinationFolder = 'common-data' + } else { + circuitName = 'credentialAtomicQueryV3OnChain-16-16-64-16-32' + destinationFolder = 'v3-stable/data-16-16-64-16-32' + } + const buildPath = `${buildFolder}${circuitName}/${circuitName}_js/`; + ['input.json', 'public.json', 'proof.json'].forEach((f) => { + const p = path.join(`${buildFolder}${circuitName}/${circuitName}_js`, f) + fs.existsSync(p) && + fs.unlinkSync(p); + console.log(`Deleted file: ${p}`); + }); + const { inputs } = require(`${dataFolder}/${file}`); + console.log(`Reading file: ${dataFolder}/${file}`); + + console.log(`Creating file: ${buildPath}/input.json`); + fs.writeFileSync(`${buildPath}/input.json`, JSON.stringify(inputs), 'utf-8'); + const child = execSync(`./generate.sh ${circuitName}`); + console.log(`execution completed`, new TextDecoder().decode(child)); + const pub_signals = JSON.parse(fs.readFileSync(`${buildPath}/public.json`).toString()); + console.log(pub_signals); + const proof = JSON.parse(fs.readFileSync(`${buildPath}/proof.json`).toString()); + console.log('Writing file: ', `${contractDataBaseFolder}/${destinationFolder}/${file}`); + fs.writeFileSync(`${contractDataBaseFolder}/${destinationFolder}/${file}`, JSON.stringify({ + pub_signals, + proof + }), 'utf-8'); + +} + +console.log('Done'); diff --git a/update-contract-data/update-contract-data-v3-stable.js b/update-contract-data/update-contract-data-v3-stable.js new file mode 100644 index 00000000..cccdbc85 --- /dev/null +++ b/update-contract-data/update-contract-data-v3-stable.js @@ -0,0 +1,47 @@ +const fs = require('fs'); +const path = require('path'); +const dataFolder = path.join(__dirname, '../testvectorgen/contract_data/v3/testdata/v3'); +const contractDataBaseFolder = path.join(__dirname, '../../contracts/test/validators/'); +const buildFolder = path.join(__dirname, '../build/'); +const { execSync } = require('child_process'); + +const files = fs.readdirSync(dataFolder); + +let circuitName = null; +let destinationFolder = null; +for (const file of files) { + + + if (file.includes('state')) { + circuitName = 'stateTransition' + destinationFolder = 'common-data' + } else { + circuitName = 'credentialAtomicQueryV3OnChain' + destinationFolder = 'v3-stable/data' + } + const buildPath = `${buildFolder}${circuitName}/${circuitName}_js/`; + ['input.json', 'public.json', 'proof.json'].forEach((f) => { + const p = path.join(`${buildFolder}${circuitName}/${circuitName}_js`, f) + fs.existsSync(p) && + fs.unlinkSync(p); + console.log(`Deleted file: ${p}`); + }); + const { inputs } = require(`${dataFolder}/${file}`); + console.log(`Reading file: ${dataFolder}/${file}`); + + console.log(`Creating file: ${buildPath}/input.json`); + fs.writeFileSync(`${buildPath}/input.json`, JSON.stringify(inputs), 'utf-8'); + const child = execSync(`./generate.sh ${circuitName}`); + console.log(`execution completed`, new TextDecoder().decode(child)); + const pub_signals = JSON.parse(fs.readFileSync(`${buildPath}/public.json`).toString()); + console.log(pub_signals); + const proof = JSON.parse(fs.readFileSync(`${buildPath}/proof.json`).toString()); + console.log('Writing file: ', `${contractDataBaseFolder}/${destinationFolder}/${file}`); + fs.writeFileSync(`${contractDataBaseFolder}/${destinationFolder}/${file}`, JSON.stringify({ + pub_signals, + proof + }), 'utf-8'); + +} + +console.log('Done'); diff --git a/update-contract-data-v3.js b/update-contract-data/update-contract-data-v3.js similarity index 75% rename from update-contract-data-v3.js rename to update-contract-data/update-contract-data-v3.js index ad8dc95b..f53ea0ea 100644 --- a/update-contract-data-v3.js +++ b/update-contract-data/update-contract-data-v3.js @@ -1,9 +1,9 @@ -const dataFolder = './testvectorgen/contract_data/testdata/v3'; -const contractDataBaseFolder = '../contracts/test/validators/'; -const buildFolder = './build/'; +const dataFolder = '../testvectorgen/contract_data/v3/testdata/v3'; +const contractDataBaseFolder = '../../contracts/test/validators/'; +const buildFolder = '../build/'; const fs = require('fs'); const path = require('path'); -const { execSync, execFileSync } = require('child_process'); +const { execSync } = require('child_process'); const files = fs.readdirSync(dataFolder); @@ -19,9 +19,9 @@ for (const file of files) { circuitName = 'credentialAtomicQueryV3OnChain-beta.1' destinationFolder = 'v3/data' } - const buildPath = `./build/${circuitName}/${circuitName}_js/`; + const buildPath = `${buildFolder}${circuitName}/${circuitName}_js/`; ['input.json', 'public.json', 'proof.json'].forEach((f) => { - const p = path.join(`./build/${circuitName}/${circuitName}_js`, f) + const p = path.join(`${buildFolder}${circuitName}/${circuitName}_js`, f) fs.existsSync(p) && fs.unlinkSync(p); console.log(`Deleted file: ${p}`); @@ -31,7 +31,7 @@ for (const file of files) { console.log(`Creating file: ${buildPath}/input.json`); fs.writeFileSync(`${buildPath}/input.json`, JSON.stringify(inputs), 'utf-8'); - const child = execSync(`./generate.sh ${circuitName}`); + const child = execSync(`../generate.sh ${circuitName}`); console.log(`execution completed`, new TextDecoder().decode(child)); const pub_signals = JSON.parse(fs.readFileSync(`${buildPath}/public.json`).toString()); console.log(pub_signals); diff --git a/update-contract-data.js b/update-contract-data/update-contract-data.js similarity index 79% rename from update-contract-data.js rename to update-contract-data/update-contract-data.js index 099a5e55..1824859c 100644 --- a/update-contract-data.js +++ b/update-contract-data/update-contract-data.js @@ -1,9 +1,9 @@ -const dataFolder = './testvectorgen/contract_data/testdata/v3'; -const contractDataBaseFolder = '../contracts/test/validators/v'; -const buildFolder = './build/'; +const dataFolder = '../testvectorgen/contract_data/testdata/v3'; +const contractDataBaseFolder = '../../contracts/test/validators/v'; +const buildFolder = '../build/'; const fs = require('fs'); const path = require('path'); -const { execSync, execFileSync } = require('child_process'); +const { execSync } = require('child_process'); const files = fs.readdirSync(dataFolder); @@ -24,9 +24,9 @@ for (const file of files) { } else { throw new Error('unknown circuit') } - const buildPath = `./build/${circuitName}/${circuitName}_js/`; + const buildPath = `${buildFolder}${circuitName}/${circuitName}_js/`; ['input.json', 'public.json', 'proof.json'].forEach((f) => { - const p = path.join(`./build/${circuitName}/${circuitName}_js`, f) + const p = path.join(`${buildFolder}${circuitName}/${circuitName}_js`, f) fs.existsSync(p) && fs.unlinkSync(p); console.log(`Deleted file: ${p}`); @@ -36,7 +36,7 @@ for (const file of files) { console.log(`Creating file: ${buildPath}/input.json`); fs.writeFileSync(`${buildPath}/input.json`, JSON.stringify(inputs), 'utf-8'); - const child = execSync(`./generate.sh ${circuitName}`); + const child = execSync(`../generate.sh ${circuitName}`); console.log(`execution completed`, new TextDecoder().decode(child)); const pub_signals = JSON.parse(fs.readFileSync(`${buildPath}/public.json`).toString()); console.log(pub_signals); @@ -55,6 +55,6 @@ for (const part of ['MTP', 'Sig']) { const contractName = `${buildFolder}${circuitName}/verifier.sol`; const contractContent = fs.readFileSync(contractName).toString(); const newContractContent = contractContent.replace('pragma solidity ^0.6.11;', 'pragma solidity ^0.8.0;').replace('contract Verifier', 'contract Verifier' + part); - fs.writeFileSync(`../contracts/contracts/lib/verifier${part}.sol`, newContractContent, 'utf-8'); + fs.writeFileSync(`../../contracts/contracts/lib/verifier${part}.sol`, newContractContent, 'utf-8'); } console.log('Done'); From 93fc35c3222f5f9b6aef9d487c5bdb39854d0e09 Mon Sep 17 00:00:00 2001 From: daveroga Date: Fri, 6 Feb 2026 16:38:24 +0100 Subject: [PATCH 2/2] fixes --- README.md | 6 +++--- testvectorgen/auth/authV3_test.go | 1 - .../update-contract-data-v3-stable-16-16-64-16-32.js | 8 +++----- .../update-contract-data-v3-stable.js | 12 +++++------- update-contract-data/update-contract-data-v3.js | 12 +++++------- 5 files changed, 16 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 335fdd4f..5aefdd5c 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ wget https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_18.ptau Examples: ```bash -./compile-circuit.sh circuits/auth.circom build/powersOfTau28_hez_final_18.ptau -./compile-circuit.sh circuits/stateTransition.circom build/powersOfTau28_hez_final_18.ptau +./compile-circuit.sh circuits/auth.circom powersOfTau28_hez_final_18.ptau +./compile-circuit.sh circuits/stateTransition.circom powersOfTau28_hez_final_18.ptau ``` ## Work with `s3_util.js` script @@ -104,7 +104,7 @@ Example: Generate data for v3 tests in contracts repo (you should have the repo 4. You will see a folder `testdata` generated in the same folder with files with inputs for generating the different proofs. 5. In root folder of the repo you can execute the Node script to generate the JSON files with proofs that will be copied to contracts repo ```bash - node update-contract-data/update-contract-data-v3-stable.js + node update-contract-data/update-contract-data-v3.js ``` 6. You will see in your `../contracts/test/validators/v3/data` and `../contracts/test/validators/common-data` the JSON files generated with the proofs needed for the validators tests in contracts. diff --git a/testvectorgen/auth/authV3_test.go b/testvectorgen/auth/authV3_test.go index bd7b1920..246c22d5 100644 --- a/testvectorgen/auth/authV3_test.go +++ b/testvectorgen/auth/authV3_test.go @@ -117,7 +117,6 @@ func generateAuthTestData(t *testing.T, profile, genesis, isSecondAuthClaim bool gisTree, err := merkletree.NewMerkleTree(context.Background(), memory.NewMemoryStorage(), 40) require.Nil(t, err) - //gisTree.Add(context.Background(), big.NewInt(1), big.NewInt(1)) if genesis == false { // extract pubKey diff --git a/update-contract-data/update-contract-data-v3-stable-16-16-64-16-32.js b/update-contract-data/update-contract-data-v3-stable-16-16-64-16-32.js index 8aba2197..ae6c85c9 100644 --- a/update-contract-data/update-contract-data-v3-stable-16-16-64-16-32.js +++ b/update-contract-data/update-contract-data-v3-stable-16-16-64-16-32.js @@ -14,15 +14,13 @@ for (const file of files) { if (file.includes('state')) { continue; - //circuitName = 'stateTransition' - //destinationFolder = 'common-data' } else { - circuitName = 'credentialAtomicQueryV3OnChain-16-16-64-16-32' - destinationFolder = 'v3-stable/data-16-16-64-16-32' + circuitName = 'credentialAtomicQueryV3OnChain-16-16-64-16-32'; + destinationFolder = 'v3-stable/data-16-16-64-16-32'; } const buildPath = `${buildFolder}${circuitName}/${circuitName}_js/`; ['input.json', 'public.json', 'proof.json'].forEach((f) => { - const p = path.join(`${buildFolder}${circuitName}/${circuitName}_js`, f) + const p = path.join(`${buildFolder}${circuitName}/${circuitName}_js`, f); fs.existsSync(p) && fs.unlinkSync(p); console.log(`Deleted file: ${p}`); diff --git a/update-contract-data/update-contract-data-v3-stable.js b/update-contract-data/update-contract-data-v3-stable.js index cccdbc85..a7208c61 100644 --- a/update-contract-data/update-contract-data-v3-stable.js +++ b/update-contract-data/update-contract-data-v3-stable.js @@ -10,18 +10,16 @@ const files = fs.readdirSync(dataFolder); let circuitName = null; let destinationFolder = null; for (const file of files) { - - if (file.includes('state')) { - circuitName = 'stateTransition' - destinationFolder = 'common-data' + circuitName = 'stateTransition'; + destinationFolder = 'common-data'; } else { - circuitName = 'credentialAtomicQueryV3OnChain' - destinationFolder = 'v3-stable/data' + circuitName = 'credentialAtomicQueryV3OnChain'; + destinationFolder = 'v3-stable/data'; } const buildPath = `${buildFolder}${circuitName}/${circuitName}_js/`; ['input.json', 'public.json', 'proof.json'].forEach((f) => { - const p = path.join(`${buildFolder}${circuitName}/${circuitName}_js`, f) + const p = path.join(`${buildFolder}${circuitName}/${circuitName}_js`, f); fs.existsSync(p) && fs.unlinkSync(p); console.log(`Deleted file: ${p}`); diff --git a/update-contract-data/update-contract-data-v3.js b/update-contract-data/update-contract-data-v3.js index f53ea0ea..10927f5a 100644 --- a/update-contract-data/update-contract-data-v3.js +++ b/update-contract-data/update-contract-data-v3.js @@ -10,18 +10,16 @@ const files = fs.readdirSync(dataFolder); let circuitName = null; let destinationFolder = null; for (const file of files) { - - if (file.includes('state')) { - circuitName = 'stateTransition' - destinationFolder = 'common-data' + circuitName = 'stateTransition'; + destinationFolder = 'common-data'; } else { - circuitName = 'credentialAtomicQueryV3OnChain-beta.1' - destinationFolder = 'v3/data' + circuitName = 'credentialAtomicQueryV3OnChain-beta.1'; + destinationFolder = 'v3/data'; } const buildPath = `${buildFolder}${circuitName}/${circuitName}_js/`; ['input.json', 'public.json', 'proof.json'].forEach((f) => { - const p = path.join(`${buildFolder}${circuitName}/${circuitName}_js`, f) + const p = path.join(`${buildFolder}${circuitName}/${circuitName}_js`, f); fs.existsSync(p) && fs.unlinkSync(p); console.log(`Deleted file: ${p}`);