├── .github └── workflows │ ├── lint.yaml │ └── test.yaml ├── .gitignore ├── LICENSE-APACHE ├── LICENSE-MIT ├── Makefile ├── README.md ├── auth.go ├── authV2.go ├── authV2_json.go ├── authV2_test.go ├── auth_test.go ├── circuits.go ├── circuits_test.go ├── cmd └── orderSignals │ ├── README.md │ └── orderSignals.go ├── credentialAtomicQueryMTP.go ├── credentialAtomicQueryMTPV2.go ├── credentialAtomicQueryMTPV2OnChain.go ├── credentialAtomicQueryMTPV2OnChain_test.go ├── credentialAtomicQueryMTPV2_test.go ├── credentialAtomicQueryMTP_test.go ├── credentialAtomicQuerySig.go ├── credentialAtomicQuerySigV2.go ├── credentialAtomicQuerySigV2OnChain.go ├── credentialAtomicQuerySigV2OnChain_test.go ├── credentialAtomicQuerySigV2_test.go ├── credentialAtomicQuerySig_test.go ├── credentialAtomicQueryV3.go ├── credentialAtomicQueryV3OnChain.go ├── credentialAtomicQueryV3OnChain_test.go ├── credentialAtomicQueryV3_test.go ├── errors.go ├── go.mod ├── go.sum ├── linkedMultiQuery.go ├── linkedMultiQuery_test.go ├── query.go ├── query_test.go ├── stateTransition.go ├── stateTransition_test.go ├── sybilCredentialAtomicMTP.go ├── sybilCredentialAtomicMTP_test.go ├── sybilCredentialAtomicSig.go ├── sybilCredentialAtomicSig_test.go ├── testdata ├── V3_mtp_inputs.json ├── V3_mtp_noop_inputs.json ├── V3_sig_inputs.json ├── authV2_inputs.json ├── linkedMultiQuery_inputs.json ├── mtpV2OnChain_inputs.json ├── mtpV2_inputs.json ├── onchain_V3_mtp_inputs.json ├── onchain_V3_sig_inputs.json ├── onchain_V3_sig_noop_inputs.json ├── sigV2OnChain_inputs.json ├── sigV2_inputs.json ├── sybilMTP_inputs.json └── sybilSig_inputs.json ├── testing ├── claim.go ├── identity.go └── utils.go ├── types.go ├── utils.go └── utils_test.go /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | lint: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: actions/setup-go@v3 15 | with: 16 | go-version: 1.19.2 17 | - uses: golangci/golangci-lint-action@v3 18 | with: 19 | version: v1.50.1 20 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | test: 11 | strategy: 12 | matrix: 13 | containers: 14 | - 1.18.0-bullseye 15 | - 1.19.2-bullseye 16 | runs-on: ubuntu-latest 17 | container: golang:${{ matrix.containers }} 18 | steps: 19 | - uses: actions/checkout@v3 20 | - uses: actions/cache@v3 21 | with: 22 | path: | 23 | ~/.cache/go-build 24 | /go/pkg/mod 25 | key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} 26 | restore-keys: | 27 | ${{ runner.os }}-go- 28 | - run: go test -v -race -timeout=60s ./... 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode 3 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2023 0kims Association. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | test: 2 | go test -count=1 ./... 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-circuits 2 | 3 | [![Go Reference](https://pkg.go.dev/badge/github.com/iden3/go-circuits.svg)](https://pkg.go.dev/github.com/iden3/go-circuits) 4 | [![Go Report Card](https://goreportcard.com/badge/github.com/iden3/go-circuits)](https://goreportcard.com/report/github.com/iden3/go-circuits) 5 | 6 | ### General description: 7 | 8 | The library goal is to create a wrapper for private and public inputs for identity circuits 9 | 10 | Repository of circuits implementation: https://github.com/iden3/circuits 11 | 12 | > Set of functionality for circuits inputs preparation, and public signals schema retrieving 13 | > 14 | 15 | ### How to use : 16 | 17 | - All circuits implement *InputsMarshaller* and *PubSignalsUnmarshal* Interfaces 18 | 19 | ```go 20 | type InputsMarshaller interface { 21 | InputsMarshal() ([]byte, error) 22 | } 23 | 24 | 25 | type PubSignalsUnmarshaller interface { 26 | PubSignalsUnmarshal(data []byte) error 27 | } 28 | ``` 29 | 30 | - Example of usage: 31 | 32 | At the moment you have to fill all needed attributes for a specific Inputs, take a look in test for each specific Input 33 | 34 | ```go 35 | inputs := AuthInputs{ 36 | ID: identifier, 37 | AuthClaim: Claim{ 38 | Claim: claim, 39 | Proof: claimEntryMTP, 40 | TreeState: treeState, 41 | NonRevProof: &ClaimNonRevStatus{treeState, claimNonRevMTP}, 42 | }, 43 | Signature: signature, 44 | Challenge: challenge, 45 | } 46 | 47 | circuitInputJSON, err := inputs.InputsMarshal() // marshal JSON inputs for specific circuit in proper format 48 | ``` 49 | 50 | - It’s easy to extend Circuits mapping through registering custom Circuit Wrapper implementation 51 | 52 | ```go 53 | RegisterCircuit(CustomCircuitID, Data{ 54 | Input: CustomInputs{}, 55 | Output: &CustomPubSignals{}, 56 | }) 57 | ``` 58 | 59 | ### Querying : 60 | 61 | The library defines the Query structure for atomic circuits and contains the mapping between query operation and its number. This library is not responsible for resolving SlotIndex for the claim field. 62 | 63 | ```go 64 | // Query represents basic request to claim slot verification 65 | type Query struct { 66 | SlotIndex int 67 | Value *big.Int 68 | Operator int 69 | } 70 | 71 | 72 | // QueryOperators represents operators for atomic circuits 73 | var QueryOperators = map[string]int{ 74 | "$noop": NOOP, 75 | "$eq": EQ, 76 | "$lt": LT, 77 | "$gt": GT, 78 | "$in": IN, 79 | "$nin": NIN, 80 | "$ne": NE, 81 | } 82 | ``` 83 | 84 | ## Contributing 85 | 86 | Unless you explicitly state otherwise, any contribution intentionally submitted 87 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 88 | dual licensed as below, without any additional terms or conditions. 89 | 90 | ## License 91 | 92 | © 2023 0kims Association 93 | 94 | This project is licensed under either of 95 | 96 | - [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) ([`LICENSE-APACHE`](LICENSE-APACHE)) 97 | - [MIT license](https://opensource.org/licenses/MIT) ([`LICENSE-MIT`](LICENSE-MIT)) 98 | 99 | at your option. 100 | -------------------------------------------------------------------------------- /auth.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "math/big" 7 | 8 | core "github.com/iden3/go-iden3-core/v2" 9 | "github.com/iden3/go-iden3-crypto/babyjub" 10 | "github.com/iden3/go-merkletree-sql/v2" 11 | "github.com/pkg/errors" 12 | ) 13 | 14 | // AuthInputs type represent auth.circom private inputs 15 | // Deprecated: use AuthV2Inputs instead 16 | type AuthInputs struct { 17 | BaseConfig 18 | 19 | ID *core.ID 20 | 21 | AuthClaim ClaimWithMTPProof 22 | 23 | Signature *babyjub.Signature 24 | Challenge *big.Int 25 | } 26 | 27 | // authCircuitInputs type reflect auth.circom private inputs required by prover 28 | type authCircuitInputs struct { 29 | UserAuthClaim *core.Claim `json:"userAuthClaim"` 30 | UserAuthClaimMtp []string `json:"userAuthClaimMtp"` 31 | UserAuthClaimNonRevMtp []string `json:"userAuthClaimNonRevMtp"` 32 | UserAuthClaimNonRevMtpAuxHi *merkletree.Hash `json:"userAuthClaimNonRevMtpAuxHi"` 33 | UserAuthClaimNonRevMtpAuxHv *merkletree.Hash `json:"userAuthClaimNonRevMtpAuxHv"` 34 | UserAuthClaimNonRevMtpNoAux string `json:"userAuthClaimNonRevMtpNoAux"` 35 | Challenge string `json:"challenge"` 36 | ChallengeSignatureR8X string `json:"challengeSignatureR8x"` 37 | ChallengeSignatureR8Y string `json:"challengeSignatureR8y"` 38 | ChallengeSignatureS string `json:"challengeSignatureS"` 39 | UserClaimsTreeRoot *merkletree.Hash `json:"userClaimsTreeRoot"` 40 | UserID string `json:"userID"` 41 | UserRevTreeRoot *merkletree.Hash `json:"userRevTreeRoot"` 42 | UserRootsTreeRoot *merkletree.Hash `json:"userRootsTreeRoot"` 43 | UserState *merkletree.Hash `json:"userState"` 44 | } 45 | 46 | // InputsMarshal returns Circom private inputs for auth.circom 47 | func (a AuthInputs) InputsMarshal() ([]byte, error) { 48 | 49 | if a.AuthClaim.IncProof.Proof == nil { 50 | return nil, errors.New(ErrorEmptyAuthClaimProof) 51 | } 52 | 53 | if a.AuthClaim.NonRevProof.Proof == nil { 54 | return nil, errors.New(ErrorEmptyAuthClaimNonRevProof) 55 | } 56 | 57 | if a.Signature == nil { 58 | return nil, errors.New(ErrorEmptyChallengeSignature) 59 | } 60 | 61 | s := authCircuitInputs{ 62 | UserAuthClaim: a.AuthClaim.Claim, 63 | UserAuthClaimMtp: PrepareSiblingsStr(a.AuthClaim.IncProof.Proof.AllSiblings(), 64 | a.GetMTLevel()), 65 | UserAuthClaimNonRevMtp: PrepareSiblingsStr(a.AuthClaim.NonRevProof.Proof.AllSiblings(), 66 | a.GetMTLevel()), 67 | Challenge: a.Challenge.String(), 68 | ChallengeSignatureR8X: a.Signature.R8.X.String(), 69 | ChallengeSignatureR8Y: a.Signature.R8.Y.String(), 70 | ChallengeSignatureS: a.Signature.S.String(), 71 | UserClaimsTreeRoot: a.AuthClaim.IncProof.TreeState.ClaimsRoot, 72 | UserID: a.ID.BigInt().String(), 73 | UserRevTreeRoot: a.AuthClaim.IncProof.TreeState.RevocationRoot, 74 | UserRootsTreeRoot: a.AuthClaim.IncProof.TreeState.RootOfRoots, 75 | UserState: a.AuthClaim.IncProof.TreeState.State, 76 | } 77 | 78 | nodeAuxAuth := GetNodeAuxValue(a.AuthClaim.NonRevProof.Proof) 79 | s.UserAuthClaimNonRevMtpAuxHi = nodeAuxAuth.key 80 | s.UserAuthClaimNonRevMtpAuxHv = nodeAuxAuth.value 81 | s.UserAuthClaimNonRevMtpNoAux = nodeAuxAuth.noAux 82 | 83 | return json.Marshal(s) 84 | } 85 | 86 | // AuthPubSignals auth.circom public signals 87 | // Deprecated: use AuthV2PubSignals instead 88 | type AuthPubSignals struct { 89 | Challenge *big.Int `json:"challenge"` 90 | UserState *merkletree.Hash `json:"userState"` 91 | UserID *core.ID `json:"userID"` 92 | } 93 | 94 | // PubSignalsUnmarshal unmarshal auth.circom public inputs to AuthPubSignals 95 | func (a *AuthPubSignals) PubSignalsUnmarshal(data []byte) error { 96 | var sVals []string 97 | err := json.Unmarshal(data, &sVals) 98 | if err != nil { 99 | return err 100 | } 101 | 102 | if len(sVals) != 3 { 103 | return fmt.Errorf("invalid number of Output values expected {%d} got {%d} ", 3, len(sVals)) 104 | } 105 | 106 | var ok bool 107 | if a.Challenge, ok = big.NewInt(0).SetString(sVals[0], 10); !ok { 108 | return fmt.Errorf("invalid challenge value: '%s'", sVals[0]) 109 | } 110 | 111 | if a.UserState, err = merkletree.NewHashFromString(sVals[1]); err != nil { 112 | return err 113 | } 114 | 115 | if a.UserID, err = idFromIntStr(sVals[2]); err != nil { 116 | return err 117 | } 118 | 119 | return nil 120 | } 121 | 122 | // GetObjMap returns AuthPubSignals as a map 123 | func (a AuthPubSignals) GetObjMap() map[string]interface{} { 124 | return toMap(a) 125 | } 126 | -------------------------------------------------------------------------------- /authV2.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "math/big" 7 | 8 | core "github.com/iden3/go-iden3-core/v2" 9 | "github.com/iden3/go-iden3-crypto/babyjub" 10 | "github.com/iden3/go-merkletree-sql/v2" 11 | "github.com/pkg/errors" 12 | ) 13 | 14 | // AuthV2Inputs type represent authV2.circom inputs 15 | type AuthV2Inputs struct { 16 | BaseConfig 17 | 18 | GenesisID *core.ID `json:"genesisID"` 19 | ProfileNonce *big.Int `json:"profileNonce"` 20 | 21 | AuthClaim *core.Claim `json:"authClaim"` 22 | 23 | AuthClaimIncMtp *merkletree.Proof `json:"authClaimIncMtp"` 24 | AuthClaimNonRevMtp *merkletree.Proof `json:"authClaimNonRevMtp"` 25 | TreeState TreeState `json:"treeState"` 26 | 27 | GISTProof GISTProof `json:"gistProof"` 28 | 29 | Signature *babyjub.Signature `json:"signature"` 30 | Challenge *big.Int `json:"challenge"` 31 | } 32 | 33 | // authCircuitInputs type reflect auth.circom private inputs required by prover 34 | type authV2CircuitInputs struct { 35 | // ID 36 | GenesisID string `json:"genesisID"` 37 | ProfileNonce string `json:"profileNonce"` 38 | 39 | // AuthClaim proof of inclusion 40 | AuthClaim *core.Claim `json:"authClaim"` 41 | AuthClaimMtp []*merkletree.Hash `json:"authClaimIncMtp"` 42 | 43 | // AuthClaim non revocation proof 44 | AuthClaimNonRevMtp []*merkletree.Hash `json:"authClaimNonRevMtp"` 45 | AuthClaimNonRevMtpAuxHi *merkletree.Hash `json:"authClaimNonRevMtpAuxHi"` 46 | AuthClaimNonRevMtpAuxHv *merkletree.Hash `json:"authClaimNonRevMtpAuxHv"` 47 | AuthClaimNonRevMtpNoAux string `json:"authClaimNonRevMtpNoAux"` 48 | 49 | Challenge string `json:"challenge"` 50 | ChallengeSignatureR8X string `json:"challengeSignatureR8x"` 51 | ChallengeSignatureR8Y string `json:"challengeSignatureR8y"` 52 | ChallengeSignatureS string `json:"challengeSignatureS"` 53 | 54 | // User State 55 | ClaimsTreeRoot *merkletree.Hash `json:"claimsTreeRoot"` 56 | RevTreeRoot *merkletree.Hash `json:"revTreeRoot"` 57 | RootsTreeRoot *merkletree.Hash `json:"rootsTreeRoot"` 58 | State *merkletree.Hash `json:"state"` 59 | 60 | // Global on-cain state 61 | GISTRoot *merkletree.Hash `json:"gistRoot"` 62 | GISTMtp []*merkletree.Hash `json:"gistMtp"` 63 | GISTMtpAuxHi *merkletree.Hash `json:"gistMtpAuxHi"` 64 | GISTMtpAuxHv *merkletree.Hash `json:"gistMtpAuxHv"` 65 | GISTMtpNoAux string `json:"gistMtpNoAux"` 66 | } 67 | 68 | func (a AuthV2Inputs) Validate() error { 69 | 70 | if a.GenesisID == nil { 71 | return errors.New(ErrorEmptyID) 72 | } 73 | 74 | if a.AuthClaimIncMtp == nil { 75 | return errors.New(ErrorEmptyAuthClaimProof) 76 | } 77 | 78 | if a.AuthClaimNonRevMtp == nil { 79 | return errors.New(ErrorEmptyAuthClaimNonRevProof) 80 | } 81 | 82 | if a.GISTProof.Proof == nil { 83 | return errors.New(ErrorEmptyGISTProof) 84 | } 85 | 86 | if a.Signature == nil { 87 | return errors.New(ErrorEmptyChallengeSignature) 88 | } 89 | 90 | if a.Challenge == nil { 91 | return errors.New(ErrorEmptyChallenge) 92 | } 93 | 94 | return nil 95 | } 96 | 97 | // InputsMarshal returns Circom private inputs for auth.circom 98 | func (a AuthV2Inputs) InputsMarshal() ([]byte, error) { 99 | 100 | if err := a.Validate(); err != nil { 101 | return nil, err 102 | } 103 | 104 | s := authV2CircuitInputs{ 105 | GenesisID: a.GenesisID.BigInt().String(), 106 | ProfileNonce: a.ProfileNonce.String(), 107 | AuthClaim: a.AuthClaim, 108 | AuthClaimMtp: merkletree.CircomSiblingsFromSiblings(a.AuthClaimIncMtp.AllSiblings(), 109 | a.GetMTLevel()-1), 110 | AuthClaimNonRevMtp: merkletree.CircomSiblingsFromSiblings(a.AuthClaimNonRevMtp.AllSiblings(), 111 | a.GetMTLevel()-1), 112 | Challenge: a.Challenge.String(), 113 | ChallengeSignatureR8X: a.Signature.R8.X.String(), 114 | ChallengeSignatureR8Y: a.Signature.R8.Y.String(), 115 | ChallengeSignatureS: a.Signature.S.String(), 116 | ClaimsTreeRoot: a.TreeState.ClaimsRoot, 117 | RevTreeRoot: a.TreeState.RevocationRoot, 118 | RootsTreeRoot: a.TreeState.RootOfRoots, 119 | State: a.TreeState.State, 120 | GISTRoot: a.GISTProof.Root, 121 | GISTMtp: merkletree.CircomSiblingsFromSiblings(a.GISTProof.Proof.AllSiblings(), 122 | a.GetMTLevelOnChain()-1), 123 | } 124 | 125 | nodeAuxAuth := GetNodeAuxValue(a.AuthClaimNonRevMtp) 126 | s.AuthClaimNonRevMtpAuxHi = nodeAuxAuth.key 127 | s.AuthClaimNonRevMtpAuxHv = nodeAuxAuth.value 128 | s.AuthClaimNonRevMtpNoAux = nodeAuxAuth.noAux 129 | 130 | gistNodeAux := GetNodeAuxValue(a.GISTProof.Proof) 131 | s.GISTMtpAuxHi = gistNodeAux.key 132 | s.GISTMtpAuxHv = gistNodeAux.value 133 | s.GISTMtpNoAux = gistNodeAux.noAux 134 | 135 | return json.Marshal(s) 136 | } 137 | 138 | // GetPublicStatesInfo returns states and gists information, 139 | // implements PublicStatesInfoProvider interface 140 | func (a AuthV2Inputs) GetPublicStatesInfo() (StatesInfo, error) { 141 | 142 | if err := a.Validate(); err != nil { 143 | return StatesInfo{}, err 144 | } 145 | 146 | userID, err := core.ProfileID(*a.GenesisID, a.ProfileNonce) 147 | if err != nil { 148 | return StatesInfo{}, err 149 | } 150 | return StatesInfo{ 151 | States: []State{}, 152 | Gists: []Gist{ 153 | { 154 | ID: userID, 155 | Root: *a.GISTProof.Root, 156 | }, 157 | }, 158 | }, nil 159 | } 160 | 161 | 162 | // AuthV2PubSignals auth.circom public signals 163 | type AuthV2PubSignals struct { 164 | UserID *core.ID `json:"userID"` 165 | Challenge *big.Int `json:"challenge"` 166 | GISTRoot *merkletree.Hash `json:"GISTRoot"` 167 | } 168 | 169 | // PubSignalsUnmarshal unmarshal auth.circom public inputs to AuthPubSignals 170 | func (a *AuthV2PubSignals) PubSignalsUnmarshal(data []byte) error { 171 | var sVals []string 172 | err := json.Unmarshal(data, &sVals) 173 | if err != nil { 174 | return err 175 | } 176 | 177 | if len(sVals) != 3 { 178 | return fmt.Errorf("invalid number of Output values expected {%d} got {%d} ", 3, len(sVals)) 179 | } 180 | 181 | if a.UserID, err = idFromIntStr(sVals[0]); err != nil { 182 | return err 183 | } 184 | 185 | var ok bool 186 | if a.Challenge, ok = big.NewInt(0).SetString(sVals[1], 10); !ok { 187 | return fmt.Errorf("invalid challenge value: '%s'", sVals[0]) 188 | } 189 | 190 | if a.GISTRoot, err = merkletree.NewHashFromString(sVals[2]); err != nil { 191 | return err 192 | } 193 | 194 | return nil 195 | } 196 | 197 | // GetObjMap returns AuthPubSignals as a map 198 | func (a AuthV2PubSignals) GetObjMap() map[string]interface{} { 199 | return toMap(a) 200 | } 201 | 202 | func (a AuthV2PubSignals) GetStatesInfo() (StatesInfo, error) { 203 | if a.UserID == nil { 204 | return StatesInfo{}, errors.New(ErrorEmptyID) 205 | } 206 | if a.GISTRoot == nil { 207 | return StatesInfo{}, errors.New(ErrorEmptyStateHash) 208 | } 209 | return StatesInfo{ 210 | States: []State{}, 211 | Gists: []Gist{{ID: *a.UserID, Root: *a.GISTRoot}}, 212 | }, nil 213 | } 214 | -------------------------------------------------------------------------------- /authV2_json.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "encoding/hex" 5 | "encoding/json" 6 | "errors" 7 | "math/big" 8 | 9 | core "github.com/iden3/go-iden3-core/v2" 10 | "github.com/iden3/go-iden3-crypto/babyjub" 11 | "github.com/iden3/go-merkletree-sql/v2" 12 | ) 13 | 14 | type jsonInt big.Int 15 | 16 | func (j *jsonInt) UnmarshalJSON(bytes []byte) error { 17 | var s string 18 | if err := json.Unmarshal(bytes, &s); err != nil { 19 | return err 20 | } 21 | var i = (*big.Int)(j) 22 | _, ok := i.SetString(s, 10) 23 | if !ok { 24 | return errors.New("error parsing big.Int") 25 | } 26 | return nil 27 | } 28 | 29 | func (j *jsonInt) MarshalJSON() ([]byte, error) { 30 | if j == nil { 31 | return []byte("null"), nil 32 | } 33 | 34 | return json.Marshal((*big.Int)(j).String()) 35 | } 36 | 37 | func (j *jsonInt) BigInt() *big.Int { 38 | if j == nil { 39 | return nil 40 | } 41 | return (*big.Int)(j) 42 | } 43 | 44 | type jsonSignature babyjub.Signature 45 | 46 | func (s *jsonSignature) UnmarshalJSON(bytes []byte) error { 47 | var sHex string 48 | if err := json.Unmarshal(bytes, &sHex); err != nil { 49 | return err 50 | } 51 | sigComp, err := hex.DecodeString(sHex) 52 | if err != nil { 53 | return err 54 | } 55 | var sigComp2 babyjub.SignatureComp 56 | if len(sigComp2) != len(sigComp) { 57 | return errors.New("incorrect signature length") 58 | } 59 | copy(sigComp2[:], sigComp) 60 | sig, err := sigComp2.Decompress() 61 | if err != nil { 62 | return err 63 | } 64 | *((*babyjub.Signature)(s)) = *sig 65 | return nil 66 | } 67 | 68 | func (s *jsonSignature) MarshalJSON() ([]byte, error) { 69 | if s == nil { 70 | return []byte("null"), nil 71 | } 72 | 73 | bs := babyjub.Signature(*s) 74 | sigComp := bs.Compress() 75 | return json.Marshal(hex.EncodeToString(sigComp[:])) 76 | } 77 | 78 | type jsonInputs struct { 79 | GenesisID *core.ID `json:"genesisID"` 80 | ProfileNonce *jsonInt `json:"profileNonce"` 81 | AuthClaim *core.Claim `json:"authClaim"` 82 | AuthClaimIncMtp *merkletree.Proof `json:"authClaimIncMtp"` 83 | AuthClaimNonRevMtp *merkletree.Proof `json:"authClaimNonRevMtp"` 84 | TreeState TreeState `json:"treeState"` // Identity state 85 | GISTProof GISTProof `json:"gistProof"` 86 | Signature *jsonSignature `json:"signature"` 87 | Challenge *jsonInt `json:"challenge"` 88 | } 89 | 90 | func newJsonInputs(a AuthV2Inputs) jsonInputs { 91 | var inputs jsonInputs 92 | inputs.GenesisID = a.GenesisID 93 | inputs.ProfileNonce = (*jsonInt)(a.ProfileNonce) 94 | inputs.AuthClaim = a.AuthClaim 95 | inputs.AuthClaimIncMtp = a.AuthClaimIncMtp 96 | inputs.AuthClaimNonRevMtp = a.AuthClaimNonRevMtp 97 | inputs.TreeState = a.TreeState 98 | inputs.GISTProof = a.GISTProof 99 | inputs.Signature = (*jsonSignature)(a.Signature) 100 | inputs.Challenge = (*jsonInt)(a.Challenge) 101 | return inputs 102 | } 103 | 104 | func (inputs jsonInputs) Unwrap() AuthV2Inputs { 105 | var a AuthV2Inputs 106 | a.GenesisID = inputs.GenesisID 107 | a.ProfileNonce = (*big.Int)(inputs.ProfileNonce) 108 | a.AuthClaim = inputs.AuthClaim 109 | a.AuthClaimIncMtp = inputs.AuthClaimIncMtp 110 | a.AuthClaimNonRevMtp = inputs.AuthClaimNonRevMtp 111 | a.TreeState = inputs.TreeState 112 | a.GISTProof = inputs.GISTProof 113 | a.Signature = (*babyjub.Signature)(inputs.Signature) 114 | a.Challenge = (*big.Int)(inputs.Challenge) 115 | return a 116 | } 117 | 118 | func (a AuthV2Inputs) MarshalJSON() ([]byte, error) { 119 | return json.Marshal(newJsonInputs(a)) 120 | } 121 | 122 | func (a *AuthV2Inputs) UnmarshalJSON(in []byte) error { 123 | var inputs jsonInputs 124 | err := json.Unmarshal(in, &inputs) 125 | if err != nil { 126 | return err 127 | } 128 | *a = inputs.Unwrap() 129 | return nil 130 | } 131 | -------------------------------------------------------------------------------- /authV2_test.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "math/big" 7 | "testing" 8 | 9 | it "github.com/iden3/go-circuits/v2/testing" 10 | core "github.com/iden3/go-iden3-core/v2" 11 | "github.com/iden3/go-merkletree-sql/v2" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func authV2Inputs(t testing.TB) AuthV2Inputs { 16 | ctx := context.Background() 17 | challenge := big.NewInt(10) 18 | 19 | // generate identity 20 | user := it.NewIdentity(t, userPK) 21 | nonce := big.NewInt(0) 22 | 23 | user2 := it.NewIdentity(t, issuerPK) 24 | 25 | // generate gist tree 26 | gTree := it.GISTTree(ctx) 27 | 28 | err := gTree.Add(ctx, user2.ID.BigInt(), user2.State(t).BigInt()) 29 | require.NoError(t, err) 30 | 31 | // prepare inputs 32 | gistProof, _, err := gTree.GenerateProof(ctx, user.ID.BigInt(), nil) 33 | require.NoError(t, err) 34 | 35 | authClaimIncMTP, _ := user.ClaimMTPRaw(t, user.AuthClaim) 36 | 37 | authClaimNonRevMTP, _ := user.ClaimRevMTPRaw(t, user.AuthClaim) 38 | require.NoError(t, err) 39 | 40 | signature, err := user.SignBBJJ(challenge.Bytes()) 41 | require.NoError(t, err) 42 | 43 | return AuthV2Inputs{ 44 | GenesisID: &user.ID, 45 | ProfileNonce: nonce, 46 | AuthClaim: user.AuthClaim, 47 | AuthClaimIncMtp: authClaimIncMTP, 48 | AuthClaimNonRevMtp: authClaimNonRevMTP, 49 | TreeState: GetTreeState(t, user), 50 | GISTProof: GISTProof{ 51 | Root: gTree.Root(), 52 | Proof: gistProof, 53 | }, 54 | Signature: signature, 55 | Challenge: challenge, 56 | } 57 | } 58 | 59 | func TestAuthV2Inputs_InputsMarshal(t *testing.T) { 60 | inputs := authV2Inputs(t) 61 | circuitInputJSON, err := inputs.InputsMarshal() 62 | require.NoError(t, err) 63 | 64 | //t.Log(string(circuitInputJSON)) 65 | exp := it.TestData(t, "authV2_inputs", string(circuitInputJSON), *generate) 66 | require.JSONEq(t, exp, string(circuitInputJSON)) 67 | } 68 | 69 | func TestAuthV2Inputs_GetPublicStatesInfo(t *testing.T) { 70 | inputs := authV2Inputs(t) 71 | statesInfo, err := inputs.GetPublicStatesInfo() 72 | require.NoError(t, err) 73 | 74 | statesInfoJsonBytes, err := json.Marshal(statesInfo) 75 | require.NoError(t, err) 76 | 77 | want := `{ 78 | "states":[], 79 | "gists":[ 80 | { 81 | "id":"26109404700696283154998654512117952420503675471097392618762221546565140481", 82 | "root":"11098939821764568131087645431296528907277253709936443029379587475821759259406" 83 | } 84 | ] 85 | }` 86 | 87 | require.JSONEq(t, want, string(statesInfoJsonBytes)) 88 | } 89 | 90 | func TestAuthV2Inputs_InputsMarshal_fromJson(t *testing.T) { 91 | t.Skip("skipping TODO: finish test") 92 | auth2_json := `{ 93 | "id": "119tqceWdRd2F6WnAyVuFQRFjK3WUXq2LorSPyGQoC", 94 | "nonce": "10", 95 | "authClaim": { 96 | "IssuerID": null, 97 | "Claim": [ 98 | "304427537360709784173770334266246861770", 99 | "0", 100 | "17640206035128972995519606214765283372613874593503528180869261482403155458945", 101 | "20634138280259599560273310290025659992320584624461316485434108770067472477956", 102 | "15930428023331155902", 103 | "0", 104 | "0", 105 | "0" 106 | ], 107 | "IncProof": { 108 | "proof": { 109 | "existence": true, 110 | "siblings": [] 111 | }, 112 | "treeState": { 113 | "state": "18656147546666944484453899241916469544090258810192803949522794490493271005313", 114 | "claimsRoot": "9763429684850732628215303952870004997159843236039795272605841029866455670219", 115 | "revocationRoot": "0", 116 | "rootOfRoots": "0" 117 | } 118 | }, 119 | "NonRevProof": { 120 | "proof": { 121 | "existence": false, 122 | "siblings": [] 123 | }, 124 | "treeState": { 125 | "state": "18656147546666944484453899241916469544090258810192803949522794490493271005313", 126 | "claimsRoot": "9763429684850732628215303952870004997159843236039795272605841029866455670219", 127 | "revocationRoot": "0", 128 | "rootOfRoots": "0" 129 | } 130 | } 131 | }, 132 | "globalTree": { 133 | "root": "8654801164827267300505642792609108116741757079309873831472910903288030796079", 134 | "proof": { 135 | "existence": false, 136 | "siblings": [], 137 | "node_aux": { 138 | "key": "24225204644786657620626565452898941426026601178354142146799363069935288320", 139 | "value": "1257746809182882563786560928809910818663538703587513060503018952434273712929" 140 | } 141 | } 142 | }, 143 | "signature": "13274071857accaec43e289504c539812c7b258bb23ce58a4598ad59daf3402eabdf39d356d0d3d2eaac1c983af1f046aa734cfb1d907f7149db32f1e616d502", 144 | "challenge": "6110517768249559238193477435454792024732173865488900270849624328650765691494" 145 | }` 146 | 147 | var inputs AuthV2Inputs 148 | err := json.Unmarshal([]byte(auth2_json), &inputs) 149 | require.NoError(t, err) 150 | 151 | circuitInputJSON, err := inputs.InputsMarshal() 152 | require.NoError(t, err) 153 | //t.Log(string(circuitInputJSON)) 154 | expectedJSONInputs := `{"userGenesisID":"20920305170169595198233610955511031459141100274346276665183631177096036352","nonce":"10","userAuthClaim":["304427537360709784173770334266246861770","0","17640206035128972995519606214765283372613874593503528180869261482403155458945","20634138280259599560273310290025659992320584624461316485434108770067472477956","15930428023331155902","0","0","0"],"userAuthClaimMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"userAuthClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"userAuthClaimNonRevMtpAuxHi":"0","userAuthClaimNonRevMtpAuxHv":"0","userAuthClaimNonRevMtpNoAux":"1","challenge":"6110517768249559238193477435454792024732173865488900270849624328650765691494","challengeSignatureR8x":"2273647433349372574162365571517182161856978101733725351784171216877260126349","challengeSignatureR8y":"20921152258050920729820249883788091534543872328111915977763626674391221282579","challengeSignatureS":"1281122186572874955530253539759994983000852038854525332258204958436946993067","userClaimsTreeRoot":"9763429684850732628215303952870004997159843236039795272605841029866455670219","userRevTreeRoot":"0","userRootsTreeRoot":"0","userState":"18656147546666944484453899241916469544090258810192803949522794490493271005313","globalSmtRoot":"8654801164827267300505642792609108116741757079309873831472910903288030796079","globalSmtMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"globalSmtMtpAuxHi":"24225204644786657620626565452898941426026601178354142146799363069935288320","globalSmtMtpAuxHv":"1257746809182882563786560928809910818663538703587513060503018952434273712929","globalSmtMtpNoAux":"0"} 155 | ` 156 | require.JSONEq(t, expectedJSONInputs, string(circuitInputJSON)) 157 | } 158 | 159 | func TestAuthV2Circuit_CircuitUnmarshal(t *testing.T) { 160 | // generate mock Data. 161 | intID, b := new(big.Int).SetString("19224224881555258540966250468059781351205177043309252290095510834143232000", 162 | 10) 163 | require.True(t, b) 164 | identifier, err := core.IDFromInt(intID) 165 | require.NoError(t, err) 166 | 167 | challenge := big.NewInt(1) 168 | 169 | stateInt, b := new(big.Int).SetString( 170 | "18656147546666944484453899241916469544090258810192803949522794490493271005313", 171 | 10) 172 | require.True(t, b) 173 | state, err := merkletree.NewHashFromBigInt(stateInt) 174 | require.NoError(t, err) 175 | 176 | out := []string{identifier.BigInt().String(), challenge.String(), state.BigInt().String()} 177 | bytesOut, err := json.Marshal(out) 178 | require.NoError(t, err) 179 | 180 | ao := AuthV2PubSignals{} 181 | err = ao.PubSignalsUnmarshal(bytesOut) 182 | require.NoError(t, err) 183 | require.Equal(t, challenge, ao.Challenge) 184 | require.Equal(t, state, ao.GISTRoot) 185 | require.Equal(t, &identifier, ao.UserID) 186 | 187 | statesInfo, err := ao.GetStatesInfo() 188 | require.NoError(t, err) 189 | wantStatesInfo := StatesInfo{ 190 | States: []State{}, 191 | Gists: []Gist{ 192 | { 193 | ID: idFromInt("19224224881555258540966250468059781351205177043309252290095510834143232000"), 194 | Root: hashFromInt("18656147546666944484453899241916469544090258810192803949522794490493271005313"), 195 | }, 196 | }, 197 | } 198 | j, err := json.Marshal(statesInfo) 199 | require.NoError(t, err) 200 | require.Equal(t, wantStatesInfo, statesInfo, string(j)) 201 | } 202 | 203 | func GetTreeState(t testing.TB, it *it.IdentityTest) TreeState { 204 | return TreeState{ 205 | State: it.State(t), 206 | ClaimsRoot: it.Clt.Root(), 207 | RevocationRoot: it.Ret.Root(), 208 | RootOfRoots: it.Rot.Root(), 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /auth_test.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "math/big" 7 | "testing" 8 | 9 | it "github.com/iden3/go-circuits/v2/testing" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestCircuitMarshal(t *testing.T) { 14 | 15 | ctx := context.Background() 16 | privKeyHex := "28156abe7fe2fd433dc9df969286b96666489bac508612d0e16593e944c4f69f" 17 | challenge := big.NewInt(1) 18 | identifier, claim, state, claimsTree, revTree, rootsTree, claimEntryMTP, claimNonRevMTP, signature, err := it.AuthClaimFullInfo(ctx, privKeyHex, challenge) 19 | assert.Nil(t, err) 20 | 21 | treeState := TreeState{ 22 | State: state, 23 | ClaimsRoot: claimsTree.Root(), 24 | RevocationRoot: revTree.Root(), 25 | RootOfRoots: rootsTree.Root(), 26 | } 27 | 28 | inputs := AuthInputs{ 29 | ID: identifier, 30 | AuthClaim: ClaimWithMTPProof{ 31 | Claim: claim, 32 | IncProof: MTProof{ 33 | Proof: claimEntryMTP, 34 | TreeState: treeState, 35 | }, 36 | NonRevProof: MTProof{ 37 | claimNonRevMTP, 38 | treeState}, 39 | }, 40 | Signature: signature, 41 | Challenge: challenge, 42 | BaseConfig: BaseConfig{MTLevel: 32}, 43 | } 44 | 45 | circuitInputJSON, err := inputs.InputsMarshal() 46 | assert.Nil(t, err) 47 | t.Log(string(circuitInputJSON)) 48 | expectedJSONInputs := `{"userAuthClaim":["304427537360709784173770334266246861770","0","17640206035128972995519606214765283372613874593503528180869261482403155458945","20634138280259599560273310290025659992320584624461316485434108770067472477956","15930428023331155902","0","0","0"],"userAuthClaimMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"userAuthClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"userAuthClaimNonRevMtpAuxHi":"0","userAuthClaimNonRevMtpAuxHv":"0","userAuthClaimNonRevMtpNoAux":"1","challenge":"1","challengeSignatureR8x":"8553678144208642175027223770335048072652078621216414881653012537434846327449","challengeSignatureR8y":"5507837342589329113352496188906367161790372084365285966741761856353367255709","challengeSignatureS":"2093461910575977345603199789919760192811763972089699387324401771367839603655","userClaimsTreeRoot":"9763429684850732628215303952870004997159843236039795272605841029866455670219","userID":"20920305170169595198233610955511031459141100274346276665183631177096036352","userRevTreeRoot":"0","userRootsTreeRoot":"0","userState":"18656147546666944484453899241916469544090258810192803949522794490493271005313"} 49 | ` 50 | 51 | var actualInputs map[string]interface{} 52 | err = json.Unmarshal(circuitInputJSON, &actualInputs) 53 | assert.Nil(t, err) 54 | 55 | var expectedInputs map[string]interface{} 56 | err = json.Unmarshal([]byte(expectedJSONInputs), &expectedInputs) 57 | assert.Nil(t, err) 58 | 59 | assert.Equal(t, actualInputs, expectedInputs) 60 | } 61 | 62 | func TestAuthCircuit_CircuitUnmarshal(t *testing.T) { 63 | // generate mock Data. 64 | ctx := context.Background() 65 | privKeyHex := "28156abe7fe2fd433dc9df969286b96666489bac508612d0e16593e944c4f69f" 66 | challenge := big.NewInt(1) 67 | identifier, _, state, _, _, _, _, _, _, err := it.AuthClaimFullInfo(ctx, privKeyHex, challenge) 68 | assert.NoError(t, err) 69 | 70 | out := []string{challenge.String(), state.BigInt().String(), identifier.BigInt().String()} 71 | bytesOut, err := json.Marshal(out) 72 | assert.NoError(t, err) 73 | 74 | ao := AuthPubSignals{} 75 | err = ao.PubSignalsUnmarshal(bytesOut) 76 | assert.NoError(t, err) 77 | assert.Equal(t, challenge, ao.Challenge) 78 | assert.Equal(t, state, ao.UserState) 79 | assert.Equal(t, identifier, ao.UserID) 80 | } 81 | 82 | func TestAuthCircuit_DefaultValues(t *testing.T) { 83 | in := AuthInputs{} 84 | in.MTLevel = 4 85 | in.ValueArraySize = 2 86 | 87 | assert.Equal(t, 4, in.GetMTLevel()) 88 | assert.Equal(t, 2, in.GetValueArrSize()) 89 | } 90 | -------------------------------------------------------------------------------- /circuits_test.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "encoding/json" 5 | "math/big" 6 | "testing" 7 | 8 | core "github.com/iden3/go-iden3-core/v2" 9 | "github.com/iden3/go-merkletree-sql/v2" 10 | "github.com/stretchr/testify/assert" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func TestUnmarshalCircuitOutput(t *testing.T) { 15 | 16 | id, err := core.IDFromString("1124NoAu14diR5EM1kgUha2uHFkvUrPrTXMtf4tncZ") 17 | assert.Nil(t, err) 18 | 19 | challenge := big.NewInt(11) 20 | userState, err := merkletree.NewHashFromBigInt(big.NewInt(12)) 21 | assert.NoError(t, err) 22 | 23 | out := []string{challenge.String(), userState.BigInt().String(), 24 | id.BigInt().String()} 25 | 26 | json, err := json.Marshal(out) 27 | assert.Nil(t, err) 28 | 29 | got, err := UnmarshalCircuitOutput(AuthCircuitID, json) 30 | assert.Nil(t, err) 31 | 32 | assert.Equal(t, got["userID"], &id) 33 | assert.Equal(t, got["challenge"], challenge) 34 | assert.Equal(t, got["userState"], userState) 35 | } 36 | 37 | func TestUnmarshalCircuitOutput_Err(t *testing.T) { 38 | 39 | _, err := UnmarshalCircuitOutput("Err", []byte("{}")) 40 | 41 | assert.Equal(t, err, ErrorCircuitIDNotFound) 42 | } 43 | 44 | func TestGistJsonMarshallers(t *testing.T) { 45 | var in Gist 46 | var err error 47 | in.ID, err = core.IDFromString("tQomzpDTB6x4EJUaiwk153FVi96jeNfP9WjKp9xys") 48 | require.NoError(t, err) 49 | 50 | h, err := merkletree.NewHashFromString("11098939821764568131087645431296528907277253709936443029379587475821759259406") 51 | require.NoError(t, err) 52 | in.Root = *h 53 | 54 | wantJson := `{ 55 | "id": "26109404700696283154998654512117952420503675471097392618762221546565140481", 56 | "root": "11098939821764568131087645431296528907277253709936443029379587475821759259406" 57 | }` 58 | 59 | inJsonBytes, err := json.Marshal(in) 60 | require.NoError(t, err) 61 | 62 | require.JSONEq(t, wantJson, string(inJsonBytes)) 63 | 64 | var out Gist 65 | err = json.Unmarshal(inJsonBytes, &out) 66 | require.NoError(t, err) 67 | require.Equal(t, in, out) 68 | } 69 | 70 | func TestStateJsonMarshallers(t *testing.T) { 71 | var in State 72 | var err error 73 | in.ID, err = core.IDFromString("tQomzpDTB6x4EJUaiwk153FVi96jeNfP9WjKp9xys") 74 | require.NoError(t, err) 75 | 76 | h, err := merkletree.NewHashFromString("11098939821764568131087645431296528907277253709936443029379587475821759259406") 77 | require.NoError(t, err) 78 | in.State = *h 79 | 80 | wantJson := `{ 81 | "id": "26109404700696283154998654512117952420503675471097392618762221546565140481", 82 | "state": "11098939821764568131087645431296528907277253709936443029379587475821759259406" 83 | }` 84 | 85 | inJsonBytes, err := json.Marshal(in) 86 | require.NoError(t, err) 87 | 88 | require.JSONEq(t, wantJson, string(inJsonBytes)) 89 | 90 | var out State 91 | err = json.Unmarshal(inJsonBytes, &out) 92 | require.NoError(t, err) 93 | require.Equal(t, in, out) 94 | } 95 | -------------------------------------------------------------------------------- /cmd/orderSignals/README.md: -------------------------------------------------------------------------------- 1 | # Order public signals 2 | 3 | Read sym file of circuit and output public signals in appropriate order. 4 | 5 | Example: 6 | ```shell 7 | go build && ./orderSignals -sym ~/src/circuits/build/credentialJsonLDAtomicQueryMTP/circuit.sym -signals challenge,userID,userState,claimSchema,issuerID,claimPathKey,operator,value,timestamp 8 | ``` 9 | -------------------------------------------------------------------------------- /cmd/orderSignals/orderSignals.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "log" 8 | "os" 9 | "regexp" 10 | "sort" 11 | "strconv" 12 | "strings" 13 | ) 14 | 15 | var sym = flag.String("sym", "", "path to sym file") 16 | var signals = flag.String("signals", "", "coma delimited list of signals") 17 | 18 | type listItem struct { 19 | value string 20 | order int64 21 | } 22 | 23 | func main() { 24 | flag.Parse() 25 | if *sym == "" { 26 | log.Fatal("sym file path is empty") 27 | } 28 | 29 | if *signals == "" { 30 | log.Fatal("signals is empty") 31 | } 32 | 33 | signalsN := strings.Split(*signals, ",") 34 | _ = signalsN 35 | 36 | var signalsRE []string 37 | for _, s := range signalsN { 38 | signalsRE = append(signalsRE, regexp.QuoteMeta(s)) 39 | } 40 | 41 | re, err := regexp.Compile( 42 | fmt.Sprintf(`^(\d+),\d+,\d+,main.(%v)(\[\d+])?$`, 43 | strings.Join(signalsRE, "|"))) 44 | if err != nil { 45 | panic(err) 46 | } 47 | 48 | f, err := os.Open(*sym) 49 | if err != nil { 50 | panic(err) 51 | } 52 | defer f.Close() 53 | 54 | seenSignals := make(map[string]struct{}) 55 | var items []listItem 56 | 57 | br := bufio.NewScanner(f) 58 | for br.Scan() { 59 | ln := br.Text() 60 | ss := re.FindStringSubmatch(ln) 61 | if ss == nil { 62 | continue 63 | } 64 | 65 | _, seen := seenSignals[ss[2]] 66 | if seen { 67 | continue 68 | } 69 | seenSignals[ss[2]] = struct{}{} 70 | 71 | item := listItem{value: ss[2]} 72 | item.order, err = strconv.ParseInt(ss[1], 10, 32) 73 | if err != nil { 74 | panic(err) 75 | } 76 | items = append(items, item) 77 | } 78 | 79 | if err := br.Err(); err != nil { 80 | panic(err) 81 | } 82 | 83 | sort.Slice(items, func(i, j int) bool { 84 | return items[i].order < items[j].order 85 | }) 86 | 87 | for _, i := range items { 88 | fmt.Println(i.value) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /credentialAtomicQueryMTPV2OnChain_test.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "math/big" 7 | "testing" 8 | 9 | it "github.com/iden3/go-circuits/v2/testing" 10 | "github.com/iden3/go-iden3-crypto/poseidon" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func queryMTPV2OnChainInputs(t testing.TB) AtomicQueryMTPV2OnChainInputs { 15 | challenge := big.NewInt(10) 16 | 17 | // generate identity 18 | user := it.NewIdentity(t, userPK) 19 | nonce := big.NewInt(0) 20 | 21 | user2 := it.NewIdentity(t, issuerPK) 22 | 23 | // generate global tree 24 | gTree := it.GISTTree(context.Background()) 25 | 26 | err := gTree.Add(context.Background(), user2.ID.BigInt(), user2.State(t).BigInt()) 27 | require.NoError(t, err) 28 | 29 | // prepare inputs 30 | globalProof, _, err := gTree.GenerateProof(context.Background(), user.ID.BigInt(), nil) 31 | require.NoError(t, err) 32 | 33 | authClaimIncMTP, _ := user.ClaimMTPRaw(t, user.AuthClaim) 34 | 35 | authClaimNonRevMTP, _ := user.ClaimRevMTPRaw(t, user.AuthClaim) 36 | require.NoError(t, err) 37 | 38 | signature, err := user.SignBBJJ(challenge.Bytes()) 39 | require.NoError(t, err) 40 | issuer := it.NewIdentity(t, issuerPK) 41 | 42 | subjectID := user.ID 43 | nonceSubject := big.NewInt(0) 44 | 45 | claim := it.DefaultUserClaim(t, subjectID) 46 | 47 | issuer.AddClaim(t, claim) 48 | 49 | issuerClaimMtp, _ := issuer.ClaimMTPRaw(t, claim) 50 | 51 | issuerClaimNonRevMtp, _ := issuer.ClaimRevMTPRaw(t, claim) 52 | 53 | return AtomicQueryMTPV2OnChainInputs{ 54 | RequestID: big.NewInt(23), 55 | ID: &user.ID, 56 | ProfileNonce: nonce, 57 | ClaimSubjectProfileNonce: nonceSubject, 58 | Claim: ClaimWithMTPProof{ 59 | IssuerID: &issuer.ID, 60 | Claim: claim, 61 | IncProof: MTProof{ 62 | Proof: issuerClaimMtp, 63 | TreeState: TreeState{ 64 | State: issuer.State(t), 65 | ClaimsRoot: issuer.Clt.Root(), 66 | RevocationRoot: issuer.Ret.Root(), 67 | RootOfRoots: issuer.Rot.Root(), 68 | }, 69 | }, 70 | NonRevProof: MTProof{ 71 | TreeState: TreeState{ 72 | State: issuer.State(t), 73 | ClaimsRoot: issuer.Clt.Root(), 74 | RevocationRoot: issuer.Ret.Root(), 75 | RootOfRoots: issuer.Rot.Root(), 76 | }, 77 | Proof: issuerClaimNonRevMtp, 78 | }, 79 | }, 80 | Query: Query{ 81 | ValueProof: nil, 82 | Operator: EQ, 83 | Values: it.PrepareIntArray([]*big.Int{big.NewInt(10)}, 64), 84 | SlotIndex: 2, 85 | }, 86 | CurrentTimeStamp: timestamp, 87 | AuthClaim: user.AuthClaim, 88 | AuthClaimIncMtp: authClaimIncMTP, 89 | AuthClaimNonRevMtp: authClaimNonRevMTP, 90 | TreeState: GetTreeState(t, user), 91 | GISTProof: GISTProof{ 92 | Root: gTree.Root(), 93 | Proof: globalProof, 94 | }, 95 | Signature: signature, 96 | Challenge: challenge, 97 | } 98 | } 99 | 100 | func TestAttrQueryMTPV2OnChain_PrepareInputs(t *testing.T) { 101 | in := queryMTPV2OnChainInputs(t) 102 | bytesInputs, err := in.InputsMarshal() 103 | require.Nil(t, err) 104 | exp := it.TestData(t, "mtpV2OnChain_inputs", string(bytesInputs), *generate) 105 | t.Log(string(bytesInputs)) 106 | require.JSONEq(t, exp, string(bytesInputs)) 107 | 108 | } 109 | 110 | func TestAttrQueryMTPV2OnChain_GetPublicStatesInfo(t *testing.T) { 111 | in := queryMTPV2OnChainInputs(t) 112 | statesInfo, err := in.GetPublicStatesInfo() 113 | require.NoError(t, err) 114 | 115 | bs, err := json.Marshal(statesInfo) 116 | require.NoError(t, err) 117 | 118 | wantStatesInfo := `{ 119 | "states": [ 120 | { 121 | "id": "27918766665310231445021466320959318414450284884582375163563581940319453185", 122 | "state": "19157496396839393206871475267813888069926627705277243727237933406423274512449" 123 | } 124 | ], 125 | "gists": [ 126 | { 127 | "id": "26109404700696283154998654512117952420503675471097392618762221546565140481", 128 | "root": "11098939821764568131087645431296528907277253709936443029379587475821759259406" 129 | } 130 | ] 131 | }` 132 | require.JSONEq(t, wantStatesInfo, string(bs)) 133 | } 134 | 135 | func TestAtomicQueryMTPVOnChain2Outputs_CircuitUnmarshal(t *testing.T) { 136 | out := new(AtomicQueryMTPV2OnChainPubSignals) 137 | err := out.PubSignalsUnmarshal([]byte(`[ 138 | "0", 139 | "26109404700696283154998654512117952420503675471097392618762221546565140481", 140 | "7002038488948284767652984010448061038733120594540539539730565455904340350321", 141 | "23", 142 | "10", 143 | "11098939821764568131087645431296528907277253709936443029379587475821759259406", 144 | "27918766665310231445021466320959318414450284884582375163563581940319453185", 145 | "19157496396839393206871475267813888069926627705277243727237933406423274512449", 146 | "1", 147 | "19157496396839393206871475267813888069926627705277243727237933406423274512449", 148 | "1642074362" 149 | ]`)) 150 | require.NoError(t, err) 151 | challenge := big.NewInt(10) 152 | 153 | value, err := PrepareCircuitArrayValues([]*big.Int{big.NewInt(10)}, 64) 154 | require.NoError(t, err) 155 | valueHash, err := PoseidonHashValue(value) 156 | require.NoError(t, err) 157 | schema := it.CoreSchemaFromStr(t, "180410020913331409885634153623124536270") 158 | slotIndex := 2 159 | operator := 1 160 | queryHash, err := poseidon.Hash([]*big.Int{ 161 | schema.BigInt(), 162 | big.NewInt(int64(slotIndex)), 163 | big.NewInt(int64(operator)), 164 | big.NewInt(0), 165 | big.NewInt(1), 166 | valueHash, 167 | }) 168 | require.NoError(t, err) 169 | 170 | exp := AtomicQueryMTPV2OnChainPubSignals{ 171 | RequestID: big.NewInt(23), 172 | UserID: it.IDFromStr( 173 | t, "26109404700696283154998654512117952420503675471097392618762221546565140481"), 174 | IssuerID: it.IDFromStr(t, 175 | "27918766665310231445021466320959318414450284884582375163563581940319453185"), 176 | IssuerClaimIdenState: it.MTHashFromStr(t, 177 | "19157496396839393206871475267813888069926627705277243727237933406423274512449"), 178 | IssuerClaimNonRevState: it.MTHashFromStr(t, "19157496396839393206871475267813888069926627705277243727237933406423274512449"), 179 | QueryHash: queryHash, 180 | Timestamp: int64(1642074362), 181 | Merklized: 0, 182 | IsRevocationChecked: 1, 183 | Challenge: challenge, 184 | GlobalRoot: it.MTHashFromStr(t, "11098939821764568131087645431296528907277253709936443029379587475821759259406"), 185 | } 186 | 187 | jsonOut, err := json.Marshal(out) 188 | require.NoError(t, err) 189 | jsonExp, err := json.Marshal(exp) 190 | require.NoError(t, err) 191 | 192 | require.JSONEq(t, string(jsonExp), string(jsonOut)) 193 | 194 | statesInfo, err := exp.GetStatesInfo() 195 | require.NoError(t, err) 196 | wantStatesInfo := StatesInfo{ 197 | States: []State{ 198 | { 199 | ID: idFromInt("27918766665310231445021466320959318414450284884582375163563581940319453185"), 200 | State: hashFromInt("19157496396839393206871475267813888069926627705277243727237933406423274512449"), 201 | }, 202 | }, 203 | Gists: []Gist{ 204 | { 205 | ID: idFromInt("26109404700696283154998654512117952420503675471097392618762221546565140481"), 206 | Root: hashFromInt("11098939821764568131087645431296528907277253709936443029379587475821759259406"), 207 | }, 208 | }, 209 | } 210 | j, err := json.Marshal(statesInfo) 211 | require.NoError(t, err) 212 | require.Equal(t, wantStatesInfo, statesInfo, string(j)) 213 | } 214 | -------------------------------------------------------------------------------- /credentialAtomicQueryMTPV2_test.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "encoding/json" 5 | "math/big" 6 | "testing" 7 | 8 | it "github.com/iden3/go-circuits/v2/testing" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func queryMTPV2Inputs(t testing.TB) AtomicQueryMTPV2Inputs { 13 | user := it.NewIdentity(t, userPK) 14 | issuer := it.NewIdentity(t, issuerPK) 15 | 16 | nonce := big.NewInt(0) 17 | 18 | subjectID := user.ID 19 | nonceSubject := big.NewInt(0) 20 | 21 | claim := it.DefaultUserClaim(t, subjectID) 22 | 23 | issuer.AddClaim(t, claim) 24 | 25 | issuerClaimMtp, _ := issuer.ClaimMTPRaw(t, claim) 26 | 27 | issuerClaimNonRevMtp, _ := issuer.ClaimRevMTPRaw(t, claim) 28 | 29 | return AtomicQueryMTPV2Inputs{ 30 | RequestID: big.NewInt(23), 31 | ID: &user.ID, 32 | ProfileNonce: nonce, 33 | ClaimSubjectProfileNonce: nonceSubject, 34 | Claim: ClaimWithMTPProof{ 35 | IssuerID: &issuer.ID, 36 | Claim: claim, 37 | IncProof: MTProof{ 38 | Proof: issuerClaimMtp, 39 | TreeState: TreeState{ 40 | State: issuer.State(t), 41 | ClaimsRoot: issuer.Clt.Root(), 42 | RevocationRoot: issuer.Ret.Root(), 43 | RootOfRoots: issuer.Rot.Root(), 44 | }, 45 | }, 46 | NonRevProof: MTProof{ 47 | TreeState: TreeState{ 48 | State: issuer.State(t), 49 | ClaimsRoot: issuer.Clt.Root(), 50 | RevocationRoot: issuer.Ret.Root(), 51 | RootOfRoots: issuer.Rot.Root(), 52 | }, 53 | Proof: issuerClaimNonRevMtp, 54 | }, 55 | }, 56 | Query: Query{ 57 | ValueProof: nil, 58 | Operator: EQ, 59 | Values: it.PrepareIntArray([]*big.Int{big.NewInt(10)}, 64), 60 | SlotIndex: 2, 61 | }, 62 | CurrentTimeStamp: timestamp, 63 | } 64 | } 65 | 66 | func TestAttrQueryMTPV2_PrepareInputs(t *testing.T) { 67 | in := queryMTPV2Inputs(t) 68 | bytesInputs, err := in.InputsMarshal() 69 | require.Nil(t, err) 70 | 71 | exp := it.TestData(t, "mtpV2_inputs", string(bytesInputs), *generate) 72 | t.Log(string(bytesInputs)) 73 | require.JSONEq(t, exp, string(bytesInputs)) 74 | } 75 | 76 | func TestAttrQueryMTPV2_GetPublicStatesInfo(t *testing.T) { 77 | in := queryMTPV2Inputs(t) 78 | statesInfo, err := in.GetPublicStatesInfo() 79 | require.NoError(t, err) 80 | 81 | bs, err := json.Marshal(statesInfo) 82 | require.NoError(t, err) 83 | 84 | wantStatesInfo := `{ 85 | "states": [ 86 | { 87 | "id": "27918766665310231445021466320959318414450284884582375163563581940319453185", 88 | "state": "19157496396839393206871475267813888069926627705277243727237933406423274512449" 89 | } 90 | ], 91 | "gists": [] 92 | }` 93 | require.JSONEq(t, wantStatesInfo, string(bs)) 94 | } 95 | 96 | func TestAtomicQueryMTPV2Outputs_CircuitUnmarshal(t *testing.T) { 97 | out := new(AtomicQueryMTPV2PubSignals) 98 | err := out.PubSignalsUnmarshal([]byte(`[ 99 | "0", 100 | "19104853439462320209059061537253618984153217267677512271018416655565783041", 101 | "23", 102 | "23528770672049181535970744460798517976688641688582489375761566420828291073", 103 | "5687720250943511874245715094520098014548846873346473635855112185560372332782", 104 | "1", 105 | "5687720250943511874245715094520098014548846873346473635855112185560372332782", 106 | "1642074362", 107 | "180410020913331409885634153623124536270", 108 | "0", 109 | "0", 110 | "2", 111 | "1", 112 | "10", 113 | "0", 114 | "0", 115 | "0", 116 | "0", 117 | "0", 118 | "0", 119 | "0", 120 | "0", 121 | "0", 122 | "0", 123 | "0", 124 | "0", 125 | "0", 126 | "0", 127 | "0", 128 | "0", 129 | "0", 130 | "0", 131 | "0", 132 | "0", 133 | "0", 134 | "0", 135 | "0", 136 | "0", 137 | "0", 138 | "0", 139 | "0", 140 | "0", 141 | "0", 142 | "0", 143 | "0", 144 | "0", 145 | "0", 146 | "0", 147 | "0", 148 | "0", 149 | "0", 150 | "0", 151 | "0", 152 | "0", 153 | "0", 154 | "0", 155 | "0", 156 | "0", 157 | "0", 158 | "0", 159 | "0", 160 | "0", 161 | "0", 162 | "0", 163 | "0", 164 | "0", 165 | "0", 166 | "0", 167 | "0", 168 | "0", 169 | "0", 170 | "0", 171 | "0", 172 | "0", 173 | "0", 174 | "0", 175 | "0" 176 | ]`)) 177 | require.NoError(t, err) 178 | 179 | expValue, err := PrepareCircuitArrayValues([]*big.Int{big.NewInt(10)}, 64) 180 | require.NoError(t, err) 181 | 182 | exp := AtomicQueryMTPV2PubSignals{ 183 | RequestID: big.NewInt(23), 184 | UserID: it.IDFromStr( 185 | t, "19104853439462320209059061537253618984153217267677512271018416655565783041"), 186 | IssuerID: it.IDFromStr(t, 187 | "23528770672049181535970744460798517976688641688582489375761566420828291073"), 188 | IssuerClaimIdenState: it.MTHashFromStr(t, 189 | "5687720250943511874245715094520098014548846873346473635855112185560372332782"), 190 | IssuerClaimNonRevState: it.MTHashFromStr(t, "5687720250943511874245715094520098014548846873346473635855112185560372332782"), 191 | ClaimSchema: it.CoreSchemaFromStr(t, "180410020913331409885634153623124536270"), 192 | SlotIndex: 2, 193 | Operator: 1, 194 | Value: expValue, 195 | Timestamp: int64(1642074362), 196 | Merklized: 0, 197 | ClaimPathKey: big.NewInt(0), 198 | ClaimPathNotExists: 0, 199 | IsRevocationChecked: 1, 200 | } 201 | 202 | jsonOut, err := json.Marshal(out) 203 | require.NoError(t, err) 204 | jsonExp, err := json.Marshal(exp) 205 | require.NoError(t, err) 206 | 207 | require.JSONEq(t, string(jsonExp), string(jsonOut)) 208 | 209 | statesInfo, err := exp.GetStatesInfo() 210 | require.NoError(t, err) 211 | wantStatesInfo := StatesInfo{ 212 | States: []State{ 213 | { 214 | ID: idFromInt("23528770672049181535970744460798517976688641688582489375761566420828291073"), 215 | State: hashFromInt("5687720250943511874245715094520098014548846873346473635855112185560372332782"), 216 | }, 217 | }, 218 | Gists: []Gist{}, 219 | } 220 | j, err := json.Marshal(statesInfo) 221 | require.NoError(t, err) 222 | require.Equal(t, wantStatesInfo, statesInfo, string(j)) 223 | } 224 | -------------------------------------------------------------------------------- /credentialAtomicQuerySigV2OnChain_test.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "math/big" 7 | "testing" 8 | 9 | it "github.com/iden3/go-circuits/v2/testing" 10 | "github.com/iden3/go-iden3-crypto/poseidon" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func querySigV2OnChainInputs(t testing.TB) AtomicQuerySigV2OnChainInputs { 15 | user := it.NewIdentity(t, userPK) 16 | 17 | issuer := it.NewIdentity(t, issuerPK) 18 | 19 | subjectID := user.ID 20 | profileNonce := big.NewInt(0) 21 | 22 | nonceSubject := big.NewInt(0) 23 | 24 | claim := it.DefaultUserClaim(t, subjectID) 25 | 26 | // Sig claim 27 | claimSig := issuer.SignClaim(t, claim) 28 | 29 | issuerClaimNonRevMtp, _ := issuer.ClaimRevMTPRaw(t, claim) 30 | 31 | issuerAuthClaimNonRevMtp, _ := issuer.ClaimRevMTPRaw(t, issuer.AuthClaim) 32 | issuerAuthClaimMtp, _ := issuer.ClaimMTPRaw(t, issuer.AuthClaim) 33 | 34 | // generate global tree 35 | gTree := it.GISTTree(context.Background()) 36 | 37 | err := gTree.Add(context.Background(), issuer.ID.BigInt(), issuer.State(t).BigInt()) 38 | require.NoError(t, err) 39 | 40 | // prepare inputs 41 | globalProof, _, err := gTree.GenerateProof(context.Background(), user.ID.BigInt(), nil) 42 | require.NoError(t, err) 43 | authClaimIncMTP, _ := user.ClaimMTPRaw(t, user.AuthClaim) 44 | 45 | authClaimNonRevMTP, _ := user.ClaimRevMTPRaw(t, user.AuthClaim) 46 | require.NoError(t, err) 47 | challenge := big.NewInt(10) 48 | signature, err := user.SignBBJJ(challenge.Bytes()) 49 | require.NoError(t, err) 50 | 51 | return AtomicQuerySigV2OnChainInputs{ 52 | RequestID: big.NewInt(23), 53 | ID: &user.ID, 54 | ProfileNonce: profileNonce, 55 | ClaimSubjectProfileNonce: nonceSubject, 56 | Claim: ClaimWithSigProof{ 57 | IssuerID: &issuer.ID, 58 | Claim: claim, 59 | NonRevProof: MTProof{ 60 | TreeState: TreeState{ 61 | State: issuer.State(t), 62 | ClaimsRoot: issuer.Clt.Root(), 63 | RevocationRoot: issuer.Ret.Root(), 64 | RootOfRoots: issuer.Rot.Root(), 65 | }, 66 | Proof: issuerClaimNonRevMtp, 67 | }, 68 | SignatureProof: BJJSignatureProof{ 69 | Signature: claimSig, 70 | IssuerAuthClaim: issuer.AuthClaim, 71 | IssuerAuthIncProof: MTProof{ 72 | TreeState: TreeState{ 73 | State: issuer.State(t), 74 | ClaimsRoot: issuer.Clt.Root(), 75 | RevocationRoot: issuer.Ret.Root(), 76 | RootOfRoots: issuer.Rot.Root(), 77 | }, 78 | Proof: issuerAuthClaimMtp, 79 | }, 80 | IssuerAuthNonRevProof: MTProof{ 81 | TreeState: TreeState{ 82 | State: issuer.State(t), 83 | ClaimsRoot: issuer.Clt.Root(), 84 | RevocationRoot: issuer.Ret.Root(), 85 | RootOfRoots: issuer.Rot.Root(), 86 | }, 87 | Proof: issuerAuthClaimNonRevMtp, 88 | }, 89 | }, 90 | }, 91 | Query: Query{ 92 | ValueProof: nil, 93 | Operator: EQ, 94 | Values: it.PrepareIntArray([]*big.Int{big.NewInt(10)}, 64), 95 | SlotIndex: 2, 96 | }, 97 | CurrentTimeStamp: timestamp, 98 | AuthClaim: user.AuthClaim, 99 | AuthClaimIncMtp: authClaimIncMTP, 100 | AuthClaimNonRevMtp: authClaimNonRevMTP, 101 | TreeState: GetTreeState(t, user), 102 | GISTProof: GISTProof{ 103 | Root: gTree.Root(), 104 | Proof: globalProof, 105 | }, 106 | Signature: signature, 107 | Challenge: challenge, 108 | } 109 | } 110 | 111 | func TestAttrQuerySigV2OnChain_PrepareInputs(t *testing.T) { 112 | in := querySigV2OnChainInputs(t) 113 | bytesInputs, err := in.InputsMarshal() 114 | require.Nil(t, err) 115 | 116 | exp := it.TestData(t, "sigV2OnChain_inputs", string(bytesInputs), *generate) 117 | require.JSONEq(t, exp, string(bytesInputs)) 118 | } 119 | 120 | func TestAttrQuerySigV2OnChain_GetPublicStatesInfo(t *testing.T) { 121 | in := querySigV2OnChainInputs(t) 122 | statesInfo, err := in.GetPublicStatesInfo() 123 | require.NoError(t, err) 124 | 125 | bs, err := json.Marshal(statesInfo) 126 | require.NoError(t, err) 127 | 128 | wantStatesInfo := `{ 129 | "states": [ 130 | { 131 | "id": "27918766665310231445021466320959318414450284884582375163563581940319453185", 132 | "state": "20177832565449474772630743317224985532862797657496372535616634430055981993180" 133 | } 134 | ], 135 | "gists": [ 136 | { 137 | "id": "26109404700696283154998654512117952420503675471097392618762221546565140481", 138 | "root": "11098939821764568131087645431296528907277253709936443029379587475821759259406" 139 | } 140 | ] 141 | }` 142 | require.JSONEq(t, wantStatesInfo, string(bs)) 143 | } 144 | 145 | func TestAtomicQuerySigV2OnChainOutputs_CircuitUnmarshal(t *testing.T) { 146 | out := new(AtomicQuerySigV2OnChainPubSignals) 147 | err := out.PubSignalsUnmarshal([]byte( 148 | `[ 149 | "0", 150 | "26109404700696283154998654512117952420503675471097392618762221546565140481", 151 | "7002038488948284767652984010448061038733120594540539539730565455904340350321", 152 | "20177832565449474772630743317224985532862797657496372535616634430055981993180", 153 | "23", 154 | "10", 155 | "11098939821764568131087645431296528907277253709936443029379587475821759259406", 156 | "27918766665310231445021466320959318414450284884582375163563581940319453185", 157 | "1", 158 | "20177832565449474772630743317224985532862797657496372535616634430055981993180", 159 | "1642074362" 160 | ]`)) 161 | require.NoError(t, err) 162 | 163 | expValue, err := PrepareCircuitArrayValues([]*big.Int{big.NewInt(10)}, 64) 164 | require.NoError(t, err) 165 | valueHash, err := PoseidonHashValue(expValue) 166 | require.NoError(t, err) 167 | schema := it.CoreSchemaFromStr(t, "180410020913331409885634153623124536270") 168 | slotIndex := 2 169 | operator := 1 170 | queryHash, err := poseidon.Hash([]*big.Int{ 171 | schema.BigInt(), 172 | big.NewInt(int64(slotIndex)), 173 | big.NewInt(int64(operator)), 174 | big.NewInt(0), 175 | big.NewInt(1), 176 | valueHash, 177 | }) 178 | require.NoError(t, err) 179 | 180 | exp := AtomicQuerySigV2OnChainPubSignals{ 181 | RequestID: big.NewInt(23), 182 | UserID: it.IDFromStr( 183 | t, "26109404700696283154998654512117952420503675471097392618762221546565140481"), 184 | IssuerID: it.IDFromStr(t, "27918766665310231445021466320959318414450284884582375163563581940319453185"), 185 | IssuerAuthState: it.MTHashFromStr(t, "20177832565449474772630743317224985532862797657496372535616634430055981993180"), 186 | IssuerClaimNonRevState: it.MTHashFromStr(t, "20177832565449474772630743317224985532862797657496372535616634430055981993180"), 187 | QueryHash: queryHash, 188 | Timestamp: int64(1642074362), 189 | Merklized: 0, 190 | IsRevocationChecked: 1, 191 | Challenge: big.NewInt(10), 192 | GlobalRoot: it.MTHashFromStr(t, "11098939821764568131087645431296528907277253709936443029379587475821759259406"), 193 | } 194 | 195 | jsonOut, err := json.Marshal(out) 196 | require.NoError(t, err) 197 | jsonExp, err := json.Marshal(exp) 198 | require.NoError(t, err) 199 | 200 | require.JSONEq(t, string(jsonExp), string(jsonOut)) 201 | 202 | statesInfo, err := exp.GetStatesInfo() 203 | require.NoError(t, err) 204 | wantStatesInfo := StatesInfo{ 205 | States: []State{ 206 | { 207 | ID: idFromInt("27918766665310231445021466320959318414450284884582375163563581940319453185"), 208 | State: hashFromInt("20177832565449474772630743317224985532862797657496372535616634430055981993180"), 209 | }, 210 | }, 211 | Gists: []Gist{ 212 | { 213 | ID: idFromInt("26109404700696283154998654512117952420503675471097392618762221546565140481"), 214 | Root: hashFromInt("11098939821764568131087645431296528907277253709936443029379587475821759259406"), 215 | }, 216 | }, 217 | } 218 | j, err := json.Marshal(statesInfo) 219 | require.NoError(t, err) 220 | require.Equal(t, wantStatesInfo, statesInfo, string(j)) 221 | } 222 | -------------------------------------------------------------------------------- /credentialAtomicQuerySigV2_test.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "encoding/json" 5 | "flag" 6 | "math/big" 7 | "os" 8 | "testing" 9 | 10 | it "github.com/iden3/go-circuits/v2/testing" 11 | core "github.com/iden3/go-iden3-core/v2" 12 | "github.com/iden3/go-merkletree-sql/v2" 13 | "github.com/stretchr/testify/require" 14 | ) 15 | 16 | var ( 17 | generate = flag.Bool("generate", false, "generate the test files") 18 | ) 19 | 20 | func TestMain(m *testing.M) { 21 | flag.Parse() 22 | os.Exit(m.Run()) 23 | } 24 | 25 | const ( 26 | userPK = "28156abe7fe2fd433dc9df969286b96666489bac508612d0e16593e944c4f69f" 27 | issuerPK = "21a5e7321d0e2f3ca1cc6504396e6594a2211544b08c206847cdee96f832421a" 28 | timestamp = 1642074362 29 | ) 30 | 31 | func querySigV2Inputs(t testing.TB) AtomicQuerySigV2Inputs { 32 | user := it.NewIdentity(t, userPK) 33 | issuer := it.NewIdentity(t, issuerPK) 34 | 35 | subjectID := user.ID 36 | profileNonce := big.NewInt(0) 37 | 38 | nonceSubject := big.NewInt(0) 39 | 40 | claim := it.DefaultUserClaim(t, subjectID) 41 | 42 | // Sig claim 43 | claimSig := issuer.SignClaim(t, claim) 44 | 45 | issuerClaimNonRevMtp, _ := issuer.ClaimRevMTPRaw(t, claim) 46 | 47 | issuerAuthClaimNonRevMtp, _ := issuer.ClaimRevMTPRaw(t, issuer.AuthClaim) 48 | issuerAuthClaimMtp, _ := issuer.ClaimMTPRaw(t, issuer.AuthClaim) 49 | 50 | return AtomicQuerySigV2Inputs{ 51 | RequestID: big.NewInt(23), 52 | ID: &user.ID, 53 | ProfileNonce: profileNonce, 54 | ClaimSubjectProfileNonce: nonceSubject, 55 | Claim: ClaimWithSigProof{ 56 | IssuerID: &issuer.ID, 57 | Claim: claim, 58 | NonRevProof: MTProof{ 59 | TreeState: TreeState{ 60 | State: issuer.State(t), 61 | ClaimsRoot: issuer.Clt.Root(), 62 | RevocationRoot: issuer.Ret.Root(), 63 | RootOfRoots: issuer.Rot.Root(), 64 | }, 65 | Proof: issuerClaimNonRevMtp, 66 | }, 67 | SignatureProof: BJJSignatureProof{ 68 | Signature: claimSig, 69 | IssuerAuthClaim: issuer.AuthClaim, 70 | IssuerAuthIncProof: MTProof{ 71 | TreeState: TreeState{ 72 | State: issuer.State(t), 73 | ClaimsRoot: issuer.Clt.Root(), 74 | RevocationRoot: issuer.Ret.Root(), 75 | RootOfRoots: issuer.Rot.Root(), 76 | }, 77 | Proof: issuerAuthClaimMtp, 78 | }, 79 | IssuerAuthNonRevProof: MTProof{ 80 | TreeState: TreeState{ 81 | State: issuer.State(t), 82 | ClaimsRoot: issuer.Clt.Root(), 83 | RevocationRoot: issuer.Ret.Root(), 84 | RootOfRoots: issuer.Rot.Root(), 85 | }, 86 | Proof: issuerAuthClaimNonRevMtp, 87 | }, 88 | }, 89 | }, 90 | Query: Query{ 91 | ValueProof: nil, 92 | Operator: EQ, 93 | Values: it.PrepareIntArray([]*big.Int{big.NewInt(10)}, 64), 94 | SlotIndex: 2, 95 | }, 96 | CurrentTimeStamp: timestamp, 97 | } 98 | } 99 | 100 | func TestAttrQuerySigV2_PrepareInputs(t *testing.T) { 101 | in := querySigV2Inputs(t) 102 | bytesInputs, err := in.InputsMarshal() 103 | require.Nil(t, err) 104 | 105 | exp := it.TestData(t, "sigV2_inputs", string(bytesInputs), *generate) 106 | require.JSONEq(t, exp, string(bytesInputs)) 107 | 108 | } 109 | 110 | func TestAttrQuerySigV2_GetPublicStatesInfo(t *testing.T) { 111 | in := querySigV2Inputs(t) 112 | statesInfo, err := in.GetPublicStatesInfo() 113 | require.NoError(t, err) 114 | 115 | bs, err := json.Marshal(statesInfo) 116 | require.NoError(t, err) 117 | 118 | wantStatesInfo := `{ 119 | "states": [ 120 | { 121 | "id": "27918766665310231445021466320959318414450284884582375163563581940319453185", 122 | "state": "20177832565449474772630743317224985532862797657496372535616634430055981993180" 123 | } 124 | ], 125 | "gists": [] 126 | }` 127 | require.JSONEq(t, wantStatesInfo, string(bs)) 128 | } 129 | 130 | func TestAtomicQuerySigOutputs_CircuitUnmarshal(t *testing.T) { 131 | out := new(AtomicQuerySigV2PubSignals) 132 | err := out.PubSignalsUnmarshal([]byte( 133 | `[ 134 | "0", 135 | "23148936466334350744548790012294489365207440754509988986684797708370051073", 136 | "2943483356559152311923412925436024635269538717812859789851139200242297094", 137 | "23", 138 | "21933750065545691586450392143787330185992517860945727248803138245838110721", 139 | "1", 140 | "2943483356559152311923412925436024635269538717812859789851139200242297094", 141 | "1642074362", 142 | "180410020913331409885634153623124536270", 143 | "0", 144 | "0", 145 | "2", 146 | "1", 147 | "10", 148 | "0", 149 | "0", 150 | "0", 151 | "0", 152 | "0", 153 | "0", 154 | "0", 155 | "0", 156 | "0", 157 | "0", 158 | "0", 159 | "0", 160 | "0", 161 | "0", 162 | "0", 163 | "0", 164 | "0", 165 | "0", 166 | "0", 167 | "0", 168 | "0", 169 | "0", 170 | "0", 171 | "0", 172 | "0", 173 | "0", 174 | "0", 175 | "0", 176 | "0", 177 | "0", 178 | "0", 179 | "0", 180 | "0", 181 | "0", 182 | "0", 183 | "0", 184 | "0", 185 | "0", 186 | "0", 187 | "0", 188 | "0", 189 | "0", 190 | "0", 191 | "0", 192 | "0", 193 | "0", 194 | "0", 195 | "0", 196 | "0", 197 | "0", 198 | "0", 199 | "0", 200 | "0", 201 | "0", 202 | "0", 203 | "0", 204 | "0", 205 | "0", 206 | "0", 207 | "0", 208 | "0", 209 | "0", 210 | "0" 211 | ]`)) 212 | require.NoError(t, err) 213 | 214 | expValue, err := PrepareCircuitArrayValues([]*big.Int{big.NewInt(10)}, 64) 215 | require.NoError(t, err) 216 | 217 | exp := AtomicQuerySigV2PubSignals{ 218 | RequestID: big.NewInt(23), 219 | UserID: it.IDFromStr( 220 | t, "23148936466334350744548790012294489365207440754509988986684797708370051073"), 221 | IssuerID: it.IDFromStr(t, "21933750065545691586450392143787330185992517860945727248803138245838110721"), 222 | IssuerAuthState: it.MTHashFromStr(t, "2943483356559152311923412925436024635269538717812859789851139200242297094"), 223 | IssuerClaimNonRevState: it.MTHashFromStr(t, "2943483356559152311923412925436024635269538717812859789851139200242297094"), 224 | ClaimSchema: it.CoreSchemaFromStr(t, "180410020913331409885634153623124536270"), 225 | SlotIndex: 2, 226 | Operator: 1, 227 | Value: expValue, 228 | Timestamp: int64(1642074362), 229 | Merklized: 0, 230 | ClaimPathKey: big.NewInt(0), 231 | ClaimPathNotExists: 0, 232 | IsRevocationChecked: 1, 233 | } 234 | 235 | jsonOut, err := json.Marshal(out) 236 | require.NoError(t, err) 237 | jsonExp, err := json.Marshal(exp) 238 | require.NoError(t, err) 239 | 240 | require.JSONEq(t, string(jsonExp), string(jsonOut)) 241 | 242 | statesInfo, err := exp.GetStatesInfo() 243 | require.NoError(t, err) 244 | wantStatesInfo := StatesInfo{ 245 | States: []State{ 246 | { 247 | ID: idFromInt("21933750065545691586450392143787330185992517860945727248803138245838110721"), 248 | State: hashFromInt("2943483356559152311923412925436024635269538717812859789851139200242297094"), 249 | }, 250 | }, 251 | Gists: []Gist{}, 252 | } 253 | j, err := json.Marshal(statesInfo) 254 | require.NoError(t, err) 255 | require.Equal(t, wantStatesInfo, statesInfo, string(j)) 256 | } 257 | 258 | func idFromInt(i string) core.ID { 259 | bi, ok := new(big.Int).SetString(i, 10) 260 | if !ok { 261 | panic("can't parse int") 262 | } 263 | id, err := core.IDFromInt(bi) 264 | if err != nil { 265 | panic(err) 266 | } 267 | return id 268 | } 269 | 270 | func hashFromInt(i string) merkletree.Hash { 271 | h, err := merkletree.NewHashFromString(i) 272 | if err != nil { 273 | panic(err) 274 | } 275 | return *h 276 | } 277 | 278 | func hashPtrFromInt(i *big.Int) *merkletree.Hash { 279 | h, err := merkletree.NewHashFromBigInt(i) 280 | if err != nil { 281 | panic(err) 282 | } 283 | return h 284 | } 285 | -------------------------------------------------------------------------------- /errors.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | const ( 4 | ErrorEmptyAuthClaimProof = "empty auth claim mtp proof" 5 | ErrorEmptyAuthClaimInNewStateProof = "empty auth claim in new state mtp proof" 6 | ErrorEmptyAuthClaimNonRevProof = "empty auth claim non-revocation mtp proof" 7 | ErrorEmptyChallengeSignature = "empty challenge signature" 8 | ErrorEmptyClaimSignature = "empty claim signature" 9 | ErrorEmptyClaimProof = "empty claim mtp proof" 10 | ErrorEmptyClaimNonRevProof = "empty claim non-revocation mtp proof" 11 | ErrorEmptyIssuerAuthClaimProof = "empty issuer auth claim mtp proof" 12 | ErrorEmptyIssuerClaim = "empty issuer claim" 13 | ErrorEmptyStateCommitmentClaim = "empty state commitment claim" 14 | ErrorEmptyIssuerAuthClaimNonRevProof = "empty issuer auth claim non-revocation mtp proof" 15 | ErrorEmptyJsonLDQueryProof = "empty JSON-LD query mtp proof" 16 | ErrorEmptyJsonLDQueryValue = "empty JSON-LD query value" 17 | ErrorEmptyJsonLDQueryPath = "empty JSON-LD query path" 18 | ErrorEmptyQueryValue = "empty query value" 19 | ErrorEmptyJsonLDQueryValues = "empty JSON-LD query values" 20 | ErrorEmptyID = "empty ID" 21 | ErrorEmptyChallenge = "empty challenge" 22 | ErrorEmptyGISTProof = "empty GIST identity mtp proof" 23 | ErrorEmptyRequestID = "empty request ID" 24 | ErrorEmptyLinkNonce = "empty link nonce" 25 | ErrorEmptyClaim = "empty claim" 26 | ErrorEmptyQueries = "empty queries" 27 | ErrorTooManyQueries = "too many queries" 28 | ErrorInvalidProofType = "invalid proof type" 29 | ErrorEmptySignatureProof = "empty signature proof" 30 | ErrorEmptyMTPProof = "empty MTP proof" 31 | ErrorInvalidValuesArrSize = "invalid query Values array size" 32 | ErrorEmptyStateHash = "empty state hash" 33 | ) 34 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/iden3/go-circuits/v2 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/iden3/go-iden3-core/v2 v2.3.2 7 | github.com/iden3/go-iden3-crypto v0.0.17 8 | github.com/iden3/go-merkletree-sql/v2 v2.0.6 9 | github.com/pkg/errors v0.9.1 10 | github.com/stretchr/testify v1.9.0 11 | ) 12 | 13 | require ( 14 | github.com/davecgh/go-spew v1.1.1 // indirect 15 | github.com/dchest/blake512 v1.0.0 // indirect 16 | github.com/mr-tron/base58 v1.2.0 // indirect 17 | github.com/pmezard/go-difflib v1.0.0 // indirect 18 | golang.org/x/crypto v0.7.0 // indirect 19 | golang.org/x/sys v0.6.0 // indirect 20 | gopkg.in/yaml.v3 v3.0.1 // indirect 21 | ) 22 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/dchest/blake512 v1.0.0 h1:oDFEQFIqFSeuA34xLtXZ/rWxCXdSjirjzPhey5EUvmA= 4 | github.com/dchest/blake512 v1.0.0/go.mod h1:FV1x7xPPLWukZlpDpWQ88rF/SFwZ5qbskrzhLMB92JI= 5 | github.com/iden3/go-iden3-core/v2 v2.3.2 h1:kZq/TiSUmBKO/mvPUucfFE45ugTW+hXXlGT+Jf6CQTg= 6 | github.com/iden3/go-iden3-core/v2 v2.3.2/go.mod h1:8vmG6y8k9VS7iNoxuiKukKbRQFsMyabCc+i8er07zOs= 7 | github.com/iden3/go-iden3-crypto v0.0.17 h1:NdkceRLJo/pI4UpcjVah4lN/a3yzxRUGXqxbWcYh9mY= 8 | github.com/iden3/go-iden3-crypto v0.0.17/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= 9 | github.com/iden3/go-merkletree-sql/v2 v2.0.6 h1:vsVDImnvnHf7Ggr45ptFOXJyWNA/8IwVQO1jzRLUlY8= 10 | github.com/iden3/go-merkletree-sql/v2 v2.0.6/go.mod h1:kRhHKYpui5DUsry5RpveP6IC4XMe6iApdV9VChRYuEk= 11 | github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= 12 | github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= 13 | github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= 14 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 15 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 16 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 17 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 18 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 19 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 20 | golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= 21 | golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= 22 | golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= 23 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 24 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 25 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 26 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 27 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 28 | -------------------------------------------------------------------------------- /linkedMultiQuery.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "math/big" 7 | "strconv" 8 | 9 | core "github.com/iden3/go-iden3-core/v2" 10 | "github.com/iden3/go-merkletree-sql/v2" 11 | "github.com/pkg/errors" 12 | ) 13 | 14 | const LinkedMultiQueryLength = 10 15 | 16 | // LinkedMultiQueryInputs type represent linkedMultiQuery10.circom inputs 17 | type LinkedMultiQueryInputs struct { 18 | BaseConfig 19 | LinkNonce *big.Int 20 | Claim *core.Claim 21 | Query []*Query 22 | } 23 | 24 | // linkedMultiQueryCircuitInputs type reflect linkedMultiQuery10.circom private inputs required by prover 25 | type linkedMultiQueryCircuitInputs struct { 26 | LinkNonce string `json:"linkNonce"` 27 | IssuerClaim *core.Claim `json:"issuerClaim"` 28 | ClaimSchema string `json:"claimSchema"` 29 | ClaimPathMtp [][]string `json:"claimPathMtp"` 30 | ClaimPathMtpNoAux []string `json:"claimPathMtpNoAux"` // 1 if aux node is empty, 0 if non-empty or for inclusion proofs 31 | ClaimPathMtpAuxHi []*merkletree.Hash `json:"claimPathMtpAuxHi"` // 0 for inclusion proof 32 | ClaimPathMtpAuxHv []*merkletree.Hash `json:"claimPathMtpAuxHv"` // 0 for inclusion proof 33 | ClaimPathKey []string `json:"claimPathKey"` // hash of path in merklized json-ld document 34 | ClaimPathValue []string `json:"claimPathValue"` // value in this path in merklized json-ld document 35 | SlotIndex []int `json:"slotIndex"` 36 | Operator []int `json:"operator"` 37 | Value [][]string `json:"value"` 38 | ActualValueArraySize []int `json:"valueArraySize"` 39 | } 40 | 41 | func (l LinkedMultiQueryInputs) Validate() error { 42 | if l.LinkNonce == nil { 43 | return errors.New(ErrorEmptyLinkNonce) 44 | } 45 | 46 | if l.Claim == nil { 47 | return errors.New(ErrorEmptyClaim) 48 | } 49 | 50 | if len(l.Query) == 0 { 51 | return errors.New(ErrorEmptyQueries) 52 | } 53 | 54 | if len(l.Query) > LinkedMultiQueryLength { 55 | return errors.New(ErrorTooManyQueries) 56 | } 57 | 58 | for _, q := range l.Query { 59 | if q == nil { 60 | continue 61 | } 62 | if err := q.ValidateValueArraySize(l.GetValueArrSize()); err != nil { 63 | return err 64 | } 65 | } 66 | 67 | return nil 68 | } 69 | 70 | // InputsMarshal returns Circom private inputs for linkedMultiQuery10.circom 71 | func (l LinkedMultiQueryInputs) InputsMarshal() ([]byte, error) { 72 | if err := l.Validate(); err != nil { 73 | return nil, err 74 | } 75 | 76 | s := linkedMultiQueryCircuitInputs{} 77 | s.LinkNonce = l.LinkNonce.String() 78 | s.IssuerClaim = l.Claim 79 | s.ClaimSchema = l.Claim.GetSchemaHash().BigInt().String() 80 | 81 | s.ClaimPathMtp = make([][]string, LinkedMultiQueryLength) 82 | s.ClaimPathMtpNoAux = make([]string, LinkedMultiQueryLength) 83 | s.ClaimPathMtpAuxHi = make([]*merkletree.Hash, LinkedMultiQueryLength) 84 | s.ClaimPathMtpAuxHv = make([]*merkletree.Hash, LinkedMultiQueryLength) 85 | s.ClaimPathKey = make([]string, LinkedMultiQueryLength) 86 | s.ClaimPathValue = make([]string, LinkedMultiQueryLength) 87 | s.SlotIndex = make([]int, LinkedMultiQueryLength) 88 | s.Operator = make([]int, LinkedMultiQueryLength) 89 | s.Value = make([][]string, LinkedMultiQueryLength) 90 | s.ActualValueArraySize = make([]int, LinkedMultiQueryLength) 91 | 92 | for i := 0; i < LinkedMultiQueryLength; i++ { 93 | if i >= len(l.Query) || l.Query[i] == nil { 94 | s.ClaimPathMtp[i] = PrepareSiblingsStr([]*merkletree.Hash{}, l.GetMTLevelsClaim()) 95 | 96 | s.ClaimPathMtpNoAux[i] = "0" 97 | s.ClaimPathMtpAuxHi[i] = &merkletree.HashZero 98 | s.ClaimPathMtpAuxHv[i] = &merkletree.HashZero 99 | 100 | s.ClaimPathKey[i] = "0" 101 | s.ClaimPathValue[i] = "0" 102 | 103 | s.SlotIndex[i] = 0 104 | s.Operator[i] = 0 105 | 106 | values, err := PrepareCircuitArrayValues(make([]*big.Int, 0), l.GetValueArrSize()) 107 | if err != nil { 108 | return nil, err 109 | } 110 | s.Value[i] = bigIntArrayToStringArray(values) 111 | s.ActualValueArraySize[i] = 0 112 | continue 113 | } 114 | 115 | valueProof := l.Query[i].ValueProof 116 | if valueProof == nil { 117 | valueProof = &ValueProof{} 118 | valueProof.Path = big.NewInt(0) 119 | valueProof.Value = big.NewInt(0) 120 | valueProof.MTP = &merkletree.Proof{} 121 | } 122 | 123 | s.ClaimPathMtp[i] = PrepareSiblingsStr(valueProof.MTP.AllSiblings(), 124 | l.GetMTLevelsClaim()) 125 | 126 | nodAuxJSONLD := GetNodeAuxValue(valueProof.MTP) 127 | s.ClaimPathMtpNoAux[i] = nodAuxJSONLD.noAux 128 | s.ClaimPathMtpAuxHi[i] = nodAuxJSONLD.key 129 | s.ClaimPathMtpAuxHv[i] = nodAuxJSONLD.value 130 | 131 | s.ClaimPathKey[i] = valueProof.Path.String() 132 | s.ClaimPathValue[i] = valueProof.Value.String() 133 | 134 | s.SlotIndex[i] = l.Query[i].SlotIndex 135 | s.Operator[i] = l.Query[i].Operator 136 | s.ActualValueArraySize[i] = len(l.Query[i].Values) 137 | values, err := PrepareCircuitArrayValues(l.Query[i].Values, l.GetValueArrSize()) 138 | if err != nil { 139 | return nil, err 140 | } 141 | s.Value[i] = bigIntArrayToStringArray(values) 142 | } 143 | 144 | return json.Marshal(s) 145 | } 146 | 147 | // LinkedMultiQueryPubSignals linkedMultiQuery10.circom public signals 148 | type LinkedMultiQueryPubSignals struct { 149 | LinkID *big.Int `json:"linkID"` 150 | Merklized int `json:"merklized"` 151 | OperatorOutput []*big.Int `json:"operatorOutput"` 152 | CircuitQueryHash []*big.Int `json:"circuitQueryHash"` 153 | } 154 | 155 | // PubSignalsUnmarshal unmarshal linkedMultiQuery10.circom public inputs to LinkedMultiQueryPubSignals 156 | func (lo *LinkedMultiQueryPubSignals) PubSignalsUnmarshal(data []byte) error { 157 | // expected order: 158 | // linkID 159 | // merklized 160 | // operatorOutput 161 | // circuitQueryHash 162 | 163 | outputsLength := LinkedMultiQueryLength*2 + 2 164 | var sVals []string 165 | err := json.Unmarshal(data, &sVals) 166 | if err != nil { 167 | return err 168 | } 169 | 170 | if len(sVals) != outputsLength { 171 | return fmt.Errorf("invalid number of Output values expected {%d} go {%d} ", outputsLength, len(sVals)) 172 | } 173 | 174 | var ok bool 175 | fieldIdx := 0 176 | 177 | // - linkID 178 | if lo.LinkID, ok = big.NewInt(0).SetString(sVals[fieldIdx], 10); !ok { 179 | return fmt.Errorf("invalid link ID value: '%s'", sVals[fieldIdx]) 180 | } 181 | fieldIdx++ 182 | 183 | // -- merklized 184 | if lo.Merklized, err = strconv.Atoi(sVals[fieldIdx]); err != nil { 185 | return err 186 | } 187 | fieldIdx++ 188 | 189 | // -- operatorOutput 190 | lo.OperatorOutput = make([]*big.Int, LinkedMultiQueryLength) 191 | for i := 0; i < LinkedMultiQueryLength; i++ { 192 | if lo.OperatorOutput[i], ok = big.NewInt(0).SetString(sVals[fieldIdx], 10); !ok { 193 | return fmt.Errorf("invalid operator output value: '%s'", sVals[fieldIdx]) 194 | } 195 | fieldIdx++ 196 | } 197 | // -- circuitQueryHash 198 | lo.CircuitQueryHash = make([]*big.Int, LinkedMultiQueryLength) 199 | for i := 0; i < LinkedMultiQueryLength; i++ { 200 | if lo.CircuitQueryHash[i], ok = big.NewInt(0).SetString(sVals[fieldIdx], 10); !ok { 201 | return fmt.Errorf("invalid query hash value: '%s'", sVals[fieldIdx]) 202 | } 203 | fieldIdx++ 204 | } 205 | 206 | return nil 207 | } 208 | 209 | // GetObjMap returns LinkedMultiQueryPubSignals as a map 210 | func (l LinkedMultiQueryPubSignals) GetObjMap() map[string]interface{} { 211 | return toMap(l) 212 | } 213 | -------------------------------------------------------------------------------- /linkedMultiQuery_test.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "math/big" 7 | "testing" 8 | 9 | it "github.com/iden3/go-circuits/v2/testing" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func TestLinkedMultiQueryInputs_PrepareInputs(t *testing.T) { 14 | user := it.NewIdentity(t, userPK) 15 | subjectID := user.ID 16 | claim := it.DefaultUserClaim(t, subjectID) 17 | 18 | queries := make([]*Query, 10) 19 | queries[0] = &Query{ 20 | ValueProof: nil, 21 | Operator: EQ, 22 | Values: []*big.Int{big.NewInt(10)}, 23 | SlotIndex: 2, 24 | } 25 | 26 | queries[1] = &Query{ 27 | ValueProof: nil, 28 | Operator: LT, 29 | Values: []*big.Int{big.NewInt(133)}, 30 | SlotIndex: 2, 31 | } 32 | 33 | queries[2] = &Query{ 34 | ValueProof: nil, 35 | Operator: LTE, 36 | Values: []*big.Int{big.NewInt(555)}, 37 | SlotIndex: 2, 38 | } 39 | 40 | in := LinkedMultiQueryInputs{ 41 | LinkNonce: big.NewInt(35346346369657418), 42 | Claim: claim, 43 | Query: queries, 44 | } 45 | 46 | bytesInputs, err := in.InputsMarshal() 47 | require.Nil(t, err) 48 | 49 | fmt.Println(string(bytesInputs)) 50 | 51 | exp := it.TestData(t, "linkedMultiQuery_inputs", string(bytesInputs), *generate) 52 | require.JSONEq(t, exp, string(bytesInputs)) 53 | } 54 | 55 | // test if query slice length is less than LinkedMultiQueryLength 56 | func TestLinkedMultiQueryInputs_PrepareInputs_Ln(t *testing.T) { 57 | user := it.NewIdentity(t, userPK) 58 | subjectID := user.ID 59 | claim := it.DefaultUserClaim(t, subjectID) 60 | in := LinkedMultiQueryInputs{ 61 | LinkNonce: big.NewInt(35346346369657418), 62 | Claim: claim, 63 | } 64 | in.Query = append(in.Query, 65 | &Query{ 66 | ValueProof: nil, 67 | Operator: EQ, 68 | Values: []*big.Int{big.NewInt(10)}, 69 | SlotIndex: 2, 70 | }, 71 | &Query{ 72 | ValueProof: nil, 73 | Operator: LT, 74 | Values: []*big.Int{big.NewInt(133)}, 75 | SlotIndex: 2, 76 | }, 77 | &Query{ 78 | ValueProof: nil, 79 | Operator: LTE, 80 | Values: []*big.Int{big.NewInt(555)}, 81 | SlotIndex: 2, 82 | }, 83 | ) 84 | 85 | bytesInputs, err := in.InputsMarshal() 86 | require.NoError(t, err) 87 | 88 | exp := it.TestData(t, "linkedMultiQuery_inputs", string(bytesInputs), *generate) 89 | require.JSONEq(t, exp, string(bytesInputs)) 90 | } 91 | 92 | func TestLinkedMultiQueryInputs_PrepareInputs_Error(t *testing.T) { 93 | user := it.NewIdentity(t, userPK) 94 | subjectID := user.ID 95 | claim := it.DefaultUserClaim(t, subjectID) 96 | in := LinkedMultiQueryInputs{ 97 | //LinkNonce: big.NewInt(35346346369657418), 98 | //Claim: claim, 99 | } 100 | _, err := in.InputsMarshal() 101 | require.EqualError(t, err, "empty link nonce") 102 | 103 | in.LinkNonce = big.NewInt(35346346369657418) 104 | _, err = in.InputsMarshal() 105 | require.EqualError(t, err, "empty claim") 106 | 107 | in.Claim = claim 108 | _, err = in.InputsMarshal() 109 | require.EqualError(t, err, "empty queries") 110 | 111 | in.Query = append(in.Query, 112 | &Query{ 113 | ValueProof: nil, 114 | Operator: EQ, 115 | Values: []*big.Int{big.NewInt(10)}, 116 | SlotIndex: 2, 117 | }, 118 | &Query{ 119 | ValueProof: nil, 120 | Operator: LT, 121 | Values: []*big.Int{big.NewInt(133)}, 122 | SlotIndex: 2, 123 | }, 124 | &Query{ 125 | ValueProof: nil, 126 | Operator: LTE, 127 | Values: []*big.Int{big.NewInt(555)}, 128 | SlotIndex: 2, 129 | }, 130 | ) 131 | 132 | bytesInputs, err := in.InputsMarshal() 133 | require.NoError(t, err) 134 | 135 | exp := it.TestData(t, "linkedMultiQuery_inputs", string(bytesInputs), *generate) 136 | require.JSONEq(t, exp, string(bytesInputs)) 137 | } 138 | 139 | func TestLinkedMultiQueryPubSignals_CircuitUnmarshal(t *testing.T) { 140 | out := new(LinkedMultiQueryPubSignals) 141 | err := out.PubSignalsUnmarshal([]byte( 142 | `[ 143 | "443", 144 | "1", 145 | "1", 146 | "2", 147 | "3", 148 | "4", 149 | "5", 150 | "0", 151 | "0", 152 | "0", 153 | "0", 154 | "0", 155 | "100", 156 | "200", 157 | "300", 158 | "400", 159 | "500", 160 | "0", 161 | "0", 162 | "0", 163 | "0", 164 | "0" 165 | ]`)) 166 | require.NoError(t, err) 167 | 168 | operatorOutput := make([]*big.Int, 10) 169 | circuitQueryHash := make([]*big.Int, 10) 170 | valueArrSize := make([]int, 10) 171 | for i := 1; i <= 10; i++ { 172 | indx := i - 1 173 | operatorOutput[indx] = big.NewInt((int64(i))) 174 | circuitQueryHash[indx] = big.NewInt(int64(i * 100)) 175 | valueArrSize[indx] = 1 176 | if i > 5 { 177 | operatorOutput[indx] = big.NewInt(0) 178 | circuitQueryHash[indx] = big.NewInt(0) 179 | valueArrSize[indx] = 0 180 | } 181 | } 182 | 183 | exp := LinkedMultiQueryPubSignals{ 184 | LinkID: big.NewInt(443), 185 | Merklized: 1, 186 | OperatorOutput: operatorOutput, 187 | CircuitQueryHash: circuitQueryHash, 188 | } 189 | 190 | jsonOut, err := json.Marshal(out) 191 | require.NoError(t, err) 192 | jsonExp, err := json.Marshal(exp) 193 | require.NoError(t, err) 194 | 195 | require.JSONEq(t, string(jsonExp), string(jsonOut)) 196 | } 197 | -------------------------------------------------------------------------------- /query.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/iden3/go-merkletree-sql/v2" 7 | "github.com/pkg/errors" 8 | ) 9 | 10 | // List of available operators. 11 | const ( 12 | NOOP int = iota // No operation, skip query verification in circuit 13 | EQ 14 | LT 15 | GT 16 | IN 17 | NIN 18 | NE 19 | LTE 20 | GTE 21 | BETWEEN 22 | NONBETWEEN 23 | EXISTS 24 | SD = 16 25 | NULLIFY = 17 26 | ) 27 | 28 | // QueryOperators represents operators for atomic circuits 29 | var QueryOperators = map[string]int{ 30 | "$noop": NOOP, 31 | "$eq": EQ, 32 | "$lt": LT, 33 | "$gt": GT, 34 | "$in": IN, 35 | "$nin": NIN, 36 | "$ne": NE, 37 | "$lte": LTE, 38 | "$gte": GTE, 39 | "$between": BETWEEN, 40 | "$nonbetween": NONBETWEEN, 41 | "$exists": EXISTS, 42 | "$sd": SD, 43 | "$nullify": NULLIFY, 44 | } 45 | 46 | // Comparer value. 47 | type Comparer interface { 48 | Compare(int) (bool, error) 49 | } 50 | 51 | // Scalar uses for compare two scalar value. 52 | type Scalar struct { 53 | x, y *big.Int 54 | } 55 | 56 | // NewScalar create `Scalar` comparer. 57 | func NewScalar(x, y *big.Int) *Scalar { 58 | return &Scalar{x, y} 59 | } 60 | 61 | // Compare x with y by target QueryOperators. 62 | // Scalar compare support: $eq, $lt, $gt, $ne, $lte, $gte type. 63 | func (s *Scalar) Compare(t int) (bool, error) { 64 | compare := s.x.Cmp(s.y) 65 | switch t { 66 | case EQ: 67 | return compare == 0, nil 68 | case LT: 69 | return compare == -1, nil 70 | case GT: 71 | return compare == 1, nil 72 | case NE: 73 | return compare != 0, nil 74 | case LTE: 75 | return compare < 1, nil 76 | case GTE: 77 | return compare > -1, nil 78 | } 79 | return false, errors.New("unknown compare type for scalar") 80 | } 81 | 82 | // Vector uses for find/not find x scalar type in y vector type. 83 | type Vector struct { 84 | x *big.Int 85 | y []*big.Int 86 | } 87 | 88 | // NewVector create Vector. 89 | func NewVector(x *big.Int, y []*big.Int) *Vector { 90 | return &Vector{x, y} 91 | } 92 | 93 | // Compare find/not find x in y by type. 94 | // Vector compare support: $in, $nin, $between 95 | func (v *Vector) Compare(t int) (bool, error) { 96 | switch t { 97 | case IN: 98 | if len(v.y) == 0 { 99 | return false, nil 100 | } 101 | for _, i := range v.y { 102 | if v.x.Cmp(i) == 0 { 103 | return true, nil 104 | } 105 | } 106 | return false, nil 107 | case NIN: 108 | if len(v.y) == 0 { 109 | return true, nil 110 | } 111 | for _, i := range v.y { 112 | if v.x.Cmp(i) == 0 { 113 | return false, nil 114 | } 115 | } 116 | return true, nil 117 | case BETWEEN: 118 | if len(v.y) < 2 { 119 | return false, nil 120 | } 121 | if v.x.Cmp(v.y[0]) >= 0 && v.x.Cmp(v.y[1]) <= 0 { 122 | return true, nil 123 | } 124 | return false, nil 125 | case NONBETWEEN: 126 | if len(v.y) < 2 { 127 | return false, nil 128 | } 129 | if !(v.x.Cmp(v.y[0]) >= 0 && v.x.Cmp(v.y[1]) <= 0) { 130 | return true, nil 131 | } 132 | return false, nil 133 | } 134 | return false, errors.New("unknown compare type for vector") 135 | } 136 | 137 | // FactoryComparer depends on input data will return right comparer. 138 | func FactoryComparer(x *big.Int, y []*big.Int, t int) (Comparer, error) { 139 | var cmp Comparer 140 | switch t { 141 | case EQ, LT, GT, NE: 142 | if len(y) != 1 { 143 | return nil, errors.New("currently we support only one value for scalar comparison") 144 | } 145 | cmp = NewScalar(x, y[0]) 146 | case IN, NIN: 147 | cmp = NewVector(x, y) 148 | default: 149 | return nil, errors.New("unknown compare type") 150 | } 151 | return cmp, nil 152 | } 153 | 154 | // Query represents basic request to claim field with MTP and without 155 | type Query struct { 156 | Operator int 157 | Values []*big.Int 158 | SlotIndex int 159 | ValueProof *ValueProof 160 | } 161 | 162 | // Validate value size for operator 163 | func (q Query) ValidateValueArraySize(maxArrSize int) error { 164 | oneArrLengthOps := []int{EQ, LT, GT, NE, LTE, GTE, EXISTS} 165 | twoArrLengthOps := []int{BETWEEN, NONBETWEEN} 166 | maxArrLengthOps := []int{IN, NIN} 167 | 168 | arrSize := len(q.Values) 169 | if contains(oneArrLengthOps, q.Operator) { 170 | if arrSize != 1 { 171 | return errors.New(ErrorInvalidValuesArrSize) 172 | } else { 173 | return nil 174 | } 175 | } 176 | if contains(twoArrLengthOps, q.Operator) { 177 | if arrSize != 2 { 178 | return errors.New(ErrorInvalidValuesArrSize) 179 | } else { 180 | return nil 181 | } 182 | } 183 | if contains(maxArrLengthOps, q.Operator) { 184 | if arrSize == 0 || arrSize > maxArrSize { 185 | return errors.New(ErrorInvalidValuesArrSize) 186 | } else { 187 | return nil 188 | } 189 | } 190 | 191 | if arrSize != 0 { 192 | return errors.New(ErrorInvalidValuesArrSize) 193 | } 194 | return nil 195 | } 196 | 197 | func (q Query) validate() error { 198 | for i := range q.Values { 199 | if q.Values[i] == nil { 200 | return errors.New(ErrorEmptyQueryValue) 201 | } 202 | } 203 | return nil 204 | } 205 | 206 | // ValueProof represents a Merkle Proof for a value stored as MT 207 | type ValueProof struct { 208 | Path *big.Int 209 | Value *big.Int 210 | MTP *merkletree.Proof 211 | } 212 | 213 | func (q ValueProof) validate() error { 214 | if q.Path == nil { 215 | return errors.New(ErrorEmptyJsonLDQueryPath) 216 | } 217 | if q.Value == nil { 218 | return errors.New(ErrorEmptyJsonLDQueryValue) 219 | } 220 | if q.MTP == nil { 221 | return errors.New(ErrorEmptyJsonLDQueryProof) 222 | } 223 | return nil 224 | } 225 | -------------------------------------------------------------------------------- /query_test.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "math/big" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestScalarCompare(t *testing.T) { 11 | type test struct { 12 | name string 13 | x *big.Int 14 | y *big.Int 15 | operator int 16 | expected bool 17 | withErr bool 18 | } 19 | 20 | tests := []test{ 21 | { 22 | name: "testing $eq operator where x == y", 23 | x: big.NewInt(0), 24 | y: big.NewInt(0), 25 | operator: EQ, 26 | expected: true, 27 | }, 28 | { 29 | name: "testing $eq operator where x != y", 30 | x: big.NewInt(10), 31 | y: big.NewInt(0), 32 | operator: EQ, 33 | expected: false, 34 | }, 35 | { 36 | name: "testing $lt operator where x < y", 37 | x: big.NewInt(-1), 38 | y: big.NewInt(0), 39 | operator: LT, 40 | expected: true, 41 | }, 42 | { 43 | name: "testing $lt operator where x > y", 44 | x: big.NewInt(1), 45 | y: big.NewInt(0), 46 | operator: LT, 47 | expected: false, 48 | }, 49 | { 50 | name: "testing $gt operator where x > y", 51 | x: big.NewInt(1), 52 | y: big.NewInt(0), 53 | operator: GT, 54 | expected: true, 55 | }, 56 | { 57 | name: "testing $gt operator where x < y", 58 | x: big.NewInt(0), 59 | y: big.NewInt(1), 60 | operator: GT, 61 | expected: false, 62 | }, 63 | { 64 | name: "testing $in should fail", 65 | x: big.NewInt(0), 66 | y: big.NewInt(1), 67 | operator: IN, 68 | expected: false, 69 | withErr: true, 70 | }, 71 | { 72 | name: "testing $nin should faile", 73 | x: big.NewInt(0), 74 | y: big.NewInt(1), 75 | operator: NIN, 76 | expected: false, 77 | withErr: true, 78 | }, 79 | { 80 | name: "testing $ne operator where x == y", 81 | x: big.NewInt(0), 82 | y: big.NewInt(0), 83 | operator: NE, 84 | expected: false, 85 | }, 86 | { 87 | name: "testing $ne operator where x != y", 88 | x: big.NewInt(10), 89 | y: big.NewInt(0), 90 | operator: NE, 91 | expected: true, 92 | }, 93 | { 94 | name: "testing $lte operator where x == y", 95 | x: big.NewInt(0), 96 | y: big.NewInt(0), 97 | operator: LTE, 98 | expected: true, 99 | }, 100 | { 101 | name: "testing $lte operator where x < y", 102 | x: big.NewInt(0), 103 | y: big.NewInt(1), 104 | operator: LTE, 105 | expected: true, 106 | }, 107 | { 108 | name: "testing $lte operator where x > y", 109 | x: big.NewInt(2), 110 | y: big.NewInt(1), 111 | operator: LTE, 112 | expected: false, 113 | }, 114 | { 115 | name: "testing $gte operator where x == y", 116 | x: big.NewInt(0), 117 | y: big.NewInt(0), 118 | operator: GTE, 119 | expected: true, 120 | }, 121 | { 122 | name: "testing $gte operator where x < y", 123 | x: big.NewInt(0), 124 | y: big.NewInt(1), 125 | operator: GTE, 126 | expected: false, 127 | }, 128 | { 129 | name: "testing $gte operator where x > y", 130 | x: big.NewInt(2), 131 | y: big.NewInt(1), 132 | operator: GTE, 133 | expected: true, 134 | }, 135 | { 136 | name: "testing unknown operator should fail", 137 | x: big.NewInt(0), 138 | y: big.NewInt(1), 139 | operator: 10, // unknown operator. 140 | expected: false, 141 | withErr: true, 142 | }, 143 | } 144 | 145 | for _, tt := range tests { 146 | t.Run(tt.name, func(t *testing.T) { 147 | cmp := NewScalar(tt.x, tt.y) 148 | actual, err := cmp.Compare(tt.operator) 149 | if tt.withErr { 150 | require.NotNil(t, err) 151 | } else if err != nil { 152 | require.NoError(t, err) 153 | } 154 | require.Equal(t, tt.expected, actual) 155 | }) 156 | } 157 | } 158 | 159 | func TestVectorCompare(t *testing.T) { 160 | type test struct { 161 | name string 162 | x *big.Int 163 | y []*big.Int 164 | operator int 165 | expected bool 166 | withErr bool 167 | } 168 | 169 | tests := []test{ 170 | { 171 | name: "testing $in operator where x EXIST in y", 172 | x: big.NewInt(100), 173 | y: []*big.Int{big.NewInt(1), big.NewInt(10), big.NewInt(100)}, 174 | operator: IN, 175 | expected: true, 176 | }, 177 | { 178 | name: "testing $in operator where x NOT EXIST y", 179 | x: big.NewInt(1000), 180 | y: []*big.Int{big.NewInt(1), big.NewInt(10), big.NewInt(100)}, 181 | operator: IN, 182 | expected: false, 183 | }, 184 | { 185 | name: "testing $nin operator where x NOT EXIST in y", 186 | x: big.NewInt(1000), 187 | y: []*big.Int{big.NewInt(1), big.NewInt(10), big.NewInt(100)}, 188 | operator: NIN, 189 | expected: true, 190 | }, 191 | { 192 | name: "testing $nin operator where x EXIST in y", 193 | x: big.NewInt(100), 194 | y: []*big.Int{big.NewInt(1), big.NewInt(10), big.NewInt(100)}, 195 | operator: NIN, 196 | expected: false, 197 | }, 198 | { 199 | name: "testing unknown operator", 200 | x: big.NewInt(0), 201 | y: []*big.Int{big.NewInt(1), big.NewInt(10), big.NewInt(100)}, 202 | operator: 12, // unknown operator. 203 | expected: false, 204 | withErr: true, 205 | }, 206 | { 207 | name: "empty array for $in. return false", 208 | x: big.NewInt(0), 209 | y: []*big.Int{}, 210 | operator: IN, 211 | expected: false, 212 | }, 213 | { 214 | name: "empty array for $nin. return true", 215 | x: big.NewInt(0), 216 | y: []*big.Int{}, 217 | operator: NIN, 218 | expected: true, 219 | }, 220 | { 221 | name: "one value array for $between. return false", 222 | x: big.NewInt(0), 223 | y: []*big.Int{big.NewInt(1)}, 224 | operator: BETWEEN, 225 | expected: false, 226 | }, 227 | { 228 | name: "testing $between operator where x in between range.", 229 | x: big.NewInt(2), 230 | y: []*big.Int{big.NewInt(1), big.NewInt(3)}, 231 | operator: BETWEEN, 232 | expected: true, 233 | }, 234 | { 235 | name: "testing $between operator where x not in between range.", 236 | x: big.NewInt(0), 237 | y: []*big.Int{big.NewInt(1), big.NewInt(3)}, 238 | operator: BETWEEN, 239 | expected: false, 240 | }, 241 | } 242 | 243 | for _, tt := range tests { 244 | t.Run(tt.name, func(t *testing.T) { 245 | cmp := NewVector(tt.x, tt.y) 246 | actual, err := cmp.Compare(tt.operator) 247 | if tt.withErr { 248 | require.NotNil(t, err) 249 | } else if err != nil { 250 | require.NoError(t, err) 251 | } 252 | require.Equal(t, tt.expected, actual) 253 | }) 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /stateTransition.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | 7 | core "github.com/iden3/go-iden3-core/v2" 8 | "github.com/iden3/go-iden3-crypto/babyjub" 9 | "github.com/iden3/go-merkletree-sql/v2" 10 | "github.com/pkg/errors" 11 | ) 12 | 13 | // StateTransitionInputs ZK private inputs for stateTransition.circom 14 | type StateTransitionInputs struct { 15 | BaseConfig 16 | 17 | ID *core.ID 18 | 19 | OldTreeState TreeState 20 | NewTreeState TreeState 21 | IsOldStateGenesis bool 22 | 23 | AuthClaim *core.Claim `json:"claim"` 24 | AuthClaimIncMtp *merkletree.Proof `json:"authClaimIncMtp"` 25 | AuthClaimNonRevMtp *merkletree.Proof `json:"authClaimNonRevMtp"` 26 | AuthClaimNewStateIncMtp *merkletree.Proof `json:"authClaimNewStateIncMtp"` 27 | 28 | Signature *babyjub.Signature 29 | } 30 | 31 | // stateTransitionInputsInternal type represents stateTransition.circom private inputs required by prover 32 | type stateTransitionInputsInternal struct { 33 | AuthClaim core.Claim `json:"authClaim"` 34 | AuthClaimMtp []string `json:"authClaimMtp"` 35 | AuthClaimNonRevMtp []string `json:"authClaimNonRevMtp"` 36 | AuthClaimNonRevMtpAuxHi *merkletree.Hash `json:"authClaimNonRevMtpAuxHi"` 37 | AuthClaimNonRevMtpAuxHv *merkletree.Hash `json:"authClaimNonRevMtpAuxHv"` 38 | AuthClaimNonRevMtpNoAux string `json:"authClaimNonRevMtpNoAux"` 39 | UserID string `json:"userID"` 40 | NewIdState *merkletree.Hash `json:"newUserState"` 41 | OldIdState *merkletree.Hash `json:"oldUserState"` 42 | IsOldStateGenesis string `json:"isOldStateGenesis"` 43 | ClaimsTreeRoot *merkletree.Hash `json:"claimsTreeRoot"` 44 | RevTreeRoot *merkletree.Hash `json:"revTreeRoot"` 45 | RootsTreeRoot *merkletree.Hash `json:"rootsTreeRoot"` 46 | SignatureR8X string `json:"signatureR8x"` 47 | SignatureR8Y string `json:"signatureR8y"` 48 | SignatureS string `json:"signatureS"` 49 | NewAuthClaimMtp []string `json:"newAuthClaimMtp"` 50 | NewClaimsTreeRoot *merkletree.Hash `json:"newClaimsTreeRoot"` 51 | NewRevTreeRoot *merkletree.Hash `json:"newRevTreeRoot"` 52 | NewRootsTreeRoot *merkletree.Hash `json:"newRootsTreeRoot"` 53 | } 54 | 55 | // InputsMarshal returns Circom private inputs for stateTransition.circom 56 | func (c StateTransitionInputs) InputsMarshal() ([]byte, error) { 57 | 58 | if c.AuthClaimIncMtp == nil { 59 | return nil, errors.New(ErrorEmptyAuthClaimProof) 60 | } 61 | 62 | if c.AuthClaimNewStateIncMtp == nil { 63 | return nil, errors.New(ErrorEmptyAuthClaimInNewStateProof) 64 | } 65 | 66 | if c.AuthClaimNonRevMtp == nil { 67 | return nil, errors.New(ErrorEmptyAuthClaimNonRevProof) 68 | } 69 | 70 | s := stateTransitionInputsInternal{ 71 | AuthClaim: *c.AuthClaim, 72 | AuthClaimMtp: PrepareSiblingsStr(c.AuthClaimIncMtp.AllSiblings(), c.GetMTLevel()), 73 | AuthClaimNonRevMtp: PrepareSiblingsStr(c.AuthClaimNonRevMtp.AllSiblings(), c.GetMTLevel()), 74 | UserID: c.ID.BigInt().String(), 75 | NewIdState: c.NewTreeState.State, 76 | ClaimsTreeRoot: c.OldTreeState.ClaimsRoot, 77 | OldIdState: c.OldTreeState.State, 78 | RevTreeRoot: c.OldTreeState.RevocationRoot, 79 | RootsTreeRoot: c.OldTreeState.RootOfRoots, 80 | SignatureR8X: c.Signature.R8.X.String(), 81 | SignatureR8Y: c.Signature.R8.Y.String(), 82 | SignatureS: c.Signature.S.String(), 83 | NewAuthClaimMtp: PrepareSiblingsStr(c.AuthClaimNewStateIncMtp.AllSiblings(), c.GetMTLevel()), 84 | NewClaimsTreeRoot: c.NewTreeState.ClaimsRoot, 85 | NewRevTreeRoot: c.NewTreeState.RevocationRoot, 86 | NewRootsTreeRoot: c.NewTreeState.RootOfRoots, 87 | } 88 | 89 | if c.IsOldStateGenesis { 90 | s.IsOldStateGenesis = "1" 91 | } else { 92 | s.IsOldStateGenesis = "0" 93 | } 94 | 95 | nodeAuxAuth := GetNodeAuxValue(c.AuthClaimNonRevMtp) 96 | s.AuthClaimNonRevMtpAuxHi = nodeAuxAuth.key 97 | s.AuthClaimNonRevMtpAuxHv = nodeAuxAuth.value 98 | s.AuthClaimNonRevMtpNoAux = nodeAuxAuth.noAux 99 | 100 | return json.Marshal(s) 101 | } 102 | 103 | // StateTransitionPubSignals stateTransition.circom public inputs 104 | type StateTransitionPubSignals struct { 105 | UserID *core.ID `json:"userID"` 106 | OldUserState *merkletree.Hash `json:"oldUserState"` 107 | NewUserState *merkletree.Hash `json:"newUserState"` 108 | IsOldStateGenesis bool `json:"isOldStateGenesis"` 109 | } 110 | 111 | // PubSignalsUnmarshal unmarshal stateTransition.circom public signals 112 | func (s *StateTransitionPubSignals) PubSignalsUnmarshal(data []byte) error { 113 | var sVals []string 114 | err := json.Unmarshal(data, &sVals) 115 | if err != nil { 116 | return err 117 | } 118 | 119 | if len(sVals) != 4 { 120 | return fmt.Errorf("invalid number of Output values expected {%d} got {%d} ", 4, len(sVals)) 121 | } 122 | 123 | if s.UserID, err = idFromIntStr(sVals[0]); err != nil { 124 | return err 125 | } 126 | if s.OldUserState, err = merkletree.NewHashFromString(sVals[1]); err != nil { 127 | return err 128 | } 129 | if s.NewUserState, err = merkletree.NewHashFromString(sVals[2]); err != nil { 130 | return err 131 | } 132 | 133 | switch sVals[3] { 134 | case "1": 135 | s.IsOldStateGenesis = true 136 | case "0": 137 | s.IsOldStateGenesis = false 138 | default: 139 | return fmt.Errorf("invalid value for IsOldStateGenesis {%s}", sVals[3]) 140 | } 141 | 142 | return nil 143 | } 144 | 145 | // GetObjMap returns struct field as a map 146 | func (s StateTransitionPubSignals) GetObjMap() map[string]interface{} { 147 | return toMap(s) 148 | } 149 | -------------------------------------------------------------------------------- /stateTransition_test.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "encoding/json" 5 | "math/big" 6 | "testing" 7 | 8 | core "github.com/iden3/go-iden3-core/v2" 9 | "github.com/iden3/go-merkletree-sql/v2" 10 | "github.com/stretchr/testify/assert" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func TestStateTransitionOutput_GetJSONObj(t *testing.T) { 15 | id, err := core.IDFromString("1124NoAu14diR5EM1kgUha2uHFkvUrPrTXMtf4tncZ") 16 | assert.Nil(t, err) 17 | 18 | newState := hashPtrFromInt(big.NewInt(1)) 19 | oldState := hashPtrFromInt(big.NewInt(2)) 20 | 21 | sto := StateTransitionPubSignals{ 22 | UserID: &id, 23 | OldUserState: oldState, 24 | NewUserState: newState, 25 | } 26 | 27 | m := sto.GetObjMap() 28 | assert.Equal(t, &id, m["userID"]) 29 | assert.Equal(t, oldState, m["oldUserState"]) 30 | assert.Equal(t, newState, m["newUserState"]) 31 | 32 | } 33 | 34 | func TestStateTransitionInputs_InputsMarshal(t *testing.T) { 35 | 36 | out := new(StateTransitionPubSignals) 37 | err := out.PubSignalsUnmarshal([]byte(` 38 | [ 39 | "23148936466334350744548790012294489365207440754509988986684797708370051073", 40 | "7115004997868594253010848596868364067574661249707337517331323113105592633327", 41 | "4546963942567895423749885008322935416520496550192665955639269179690288593086", 42 | "0" 43 | ]`)) 44 | require.NoError(t, err) 45 | 46 | userIDStr, b := new(big.Int).SetString( 47 | "23148936466334350744548790012294489365207440754509988986684797708370051073", 10) 48 | assert.True(t, b) 49 | userID, err := core.IDFromInt(userIDStr) 50 | require.NoError(t, err) 51 | 52 | oldUserState, err := merkletree.NewHashFromString( 53 | "7115004997868594253010848596868364067574661249707337517331323113105592633327") 54 | require.NoError(t, err) 55 | 56 | newUserState, err := merkletree.NewHashFromString( 57 | "4546963942567895423749885008322935416520496550192665955639269179690288593086") 58 | require.NoError(t, err) 59 | 60 | exp := StateTransitionPubSignals{ 61 | UserID: &userID, 62 | OldUserState: oldUserState, 63 | NewUserState: newUserState, 64 | IsOldStateGenesis: false, 65 | } 66 | 67 | jsonOut, err := json.Marshal(out) 68 | require.NoError(t, err) 69 | jsonExp, err := json.Marshal(exp) 70 | require.NoError(t, err) 71 | 72 | require.JSONEq(t, string(jsonExp), string(jsonOut)) 73 | } 74 | -------------------------------------------------------------------------------- /sybilCredentialAtomicMTP.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "math/big" 7 | "strconv" 8 | 9 | core "github.com/iden3/go-iden3-core/v2" 10 | "github.com/iden3/go-merkletree-sql/v2" 11 | "github.com/pkg/errors" 12 | ) 13 | 14 | // Deprecated: trusted setup is not done for that circuits. In future releases 15 | // new circuit with sybil support will be added. 16 | type SybilAtomicMTPInputs struct { 17 | BaseConfig 18 | 19 | ID *core.ID 20 | ProfileNonce *big.Int 21 | ClaimSubjectProfileNonce *big.Int 22 | 23 | IssuerClaim ClaimWithMTPProof 24 | StateCommitmentClaim ClaimWithMTPProof 25 | 26 | GISTProof GISTProof 27 | CRS *big.Int 28 | 29 | RequestID *big.Int 30 | Timestamp int64 31 | } 32 | 33 | type sybilAtomicMTPCircuitInputs struct { 34 | IssuerClaim *core.Claim `json:"issuerClaim"` 35 | IssuerClaimMtp []*merkletree.Hash `json:"issuerClaimMtp"` 36 | IssuerClaimClaimsRoot *merkletree.Hash `json:"issuerClaimClaimsRoot"` 37 | IssuerClaimRevRoot *merkletree.Hash `json:"issuerClaimRevRoot"` 38 | IssuerClaimRootsRoot *merkletree.Hash `json:"issuerClaimRootsRoot"` 39 | IssuerClaimIdenState *merkletree.Hash `json:"issuerClaimIdenState"` 40 | 41 | IssuerClaimNonRevMtp []*merkletree.Hash `json:"issuerClaimNonRevMtp"` 42 | IssuerClaimNonRevMtpNoAux string `json:"issuerClaimNonRevMtpNoAux"` 43 | IssuerClaimNonRevMtpAuxHi *merkletree.Hash `json:"issuerClaimNonRevMtpAuxHi"` 44 | IssuerClaimNonRevMtpAuxHv *merkletree.Hash `json:"issuerClaimNonRevMtpAuxHv"` 45 | 46 | IssuerClaimNonRevClaimsRoot *merkletree.Hash `json:"issuerClaimNonRevClaimsRoot"` 47 | IssuerClaimNonRevRevRoot *merkletree.Hash `json:"issuerClaimNonRevRevRoot"` 48 | IssuerClaimNonRevRootsRoot *merkletree.Hash `json:"issuerClaimNonRevRootsRoot"` 49 | IssuerClaimNonRevState *merkletree.Hash `json:"issuerClaimNonRevState"` 50 | 51 | ClaimSchema string `json:"claimSchema"` 52 | 53 | StateCommitmentClaim *core.Claim `json:"stateCommitmentClaim"` 54 | StateCommitmentClaimMtp []*merkletree.Hash `json:"stateCommitmentClaimMtp"` 55 | StateCommitmentClaimClaimsRoot *merkletree.Hash `json:"stateCommitmentClaimClaimsRoot"` 56 | StateCommitmentClaimRevRoot *merkletree.Hash `json:"stateCommitmentClaimRevRoot"` 57 | StateCommitmentClaimRootsRoot *merkletree.Hash `json:"stateCommitmentClaimRootsRoot"` 58 | StateCommitmentClaimIdenState *merkletree.Hash `json:"stateCommitmentClaimIdenState"` 59 | 60 | GistRoot *merkletree.Hash `json:"gistRoot"` 61 | GistMtp []*merkletree.Hash `json:"gistMtp"` 62 | GistMtpAuxHi *merkletree.Hash `json:"gistMtpAuxHi"` 63 | GistMtpAuxHv *merkletree.Hash `json:"gistMtpAuxHv"` 64 | GistMtpNoAux string `json:"gistMtpNoAux"` 65 | 66 | CRS string `json:"crs"` 67 | 68 | UserGenesisID string `json:"userGenesisID"` 69 | ProfileNonce string `json:"profileNonce"` 70 | ClaimSubjectProfileNonce string `json:"claimSubjectProfileNonce"` 71 | 72 | RequestID *big.Int `json:"requestID"` 73 | IssuerID string `json:"issuerID"` 74 | Timestamp int64 `json:"timestamp"` 75 | } 76 | 77 | func (s SybilAtomicMTPInputs) Validate() error { 78 | 79 | if s.ID == nil { 80 | return errors.New(ErrorEmptyID) 81 | } 82 | 83 | if s.GISTProof.Proof == nil { 84 | return errors.New(ErrorEmptyGISTProof) 85 | } 86 | 87 | if s.IssuerClaim.Claim == nil { 88 | return errors.New(ErrorEmptyIssuerClaim) 89 | } 90 | 91 | if s.StateCommitmentClaim.Claim == nil { 92 | return errors.New(ErrorEmptyStateCommitmentClaim) 93 | } 94 | 95 | return nil 96 | } 97 | 98 | func (s SybilAtomicMTPInputs) InputsMarshal() ([]byte, error) { 99 | if err := s.Validate(); err != nil { 100 | return nil, err 101 | } 102 | 103 | mtpInputs := sybilAtomicMTPCircuitInputs{ 104 | IssuerClaim: s.IssuerClaim.Claim, 105 | IssuerClaimMtp: CircomSiblings(s.IssuerClaim.IncProof.Proof, s.GetMTLevel()), 106 | IssuerClaimClaimsRoot: s.IssuerClaim.IncProof.TreeState.ClaimsRoot, 107 | IssuerClaimRevRoot: s.IssuerClaim.IncProof.TreeState.RevocationRoot, 108 | IssuerClaimRootsRoot: s.IssuerClaim.IncProof.TreeState.RootOfRoots, 109 | IssuerClaimIdenState: s.IssuerClaim.IncProof.TreeState.State, 110 | 111 | IssuerClaimNonRevMtp: CircomSiblings(s.IssuerClaim.NonRevProof.Proof, s.GetMTLevel()), 112 | 113 | IssuerClaimNonRevClaimsRoot: s.IssuerClaim.NonRevProof.TreeState.ClaimsRoot, 114 | IssuerClaimNonRevRevRoot: s.IssuerClaim.NonRevProof.TreeState.RevocationRoot, 115 | IssuerClaimNonRevRootsRoot: s.IssuerClaim.NonRevProof.TreeState.RootOfRoots, 116 | IssuerClaimNonRevState: s.IssuerClaim.NonRevProof.TreeState.State, 117 | 118 | ClaimSchema: s.IssuerClaim.Claim.GetSchemaHash().BigInt().String(), 119 | 120 | StateCommitmentClaim: s.StateCommitmentClaim.Claim, 121 | StateCommitmentClaimMtp: CircomSiblings(s.StateCommitmentClaim.IncProof.Proof, s.GetMTLevel()), 122 | StateCommitmentClaimClaimsRoot: s.StateCommitmentClaim.IncProof.TreeState.ClaimsRoot, 123 | StateCommitmentClaimRevRoot: s.StateCommitmentClaim.IncProof.TreeState.RevocationRoot, 124 | StateCommitmentClaimRootsRoot: s.StateCommitmentClaim.IncProof.TreeState.RootOfRoots, 125 | StateCommitmentClaimIdenState: s.StateCommitmentClaim.IncProof.TreeState.State, 126 | 127 | GistRoot: s.GISTProof.Root, 128 | GistMtp: merkletree.CircomSiblingsFromSiblings(s.GISTProof.Proof.AllSiblings(), 129 | s.GetMTLevelOnChain()-1), 130 | 131 | CRS: s.CRS.String(), 132 | 133 | UserGenesisID: s.ID.BigInt().String(), 134 | ProfileNonce: s.ProfileNonce.String(), 135 | ClaimSubjectProfileNonce: s.ClaimSubjectProfileNonce.String(), 136 | } 137 | nodeAuxAuth := GetNodeAuxValue(s.IssuerClaim.NonRevProof.Proof) 138 | mtpInputs.IssuerClaimNonRevMtpNoAux = nodeAuxAuth.noAux 139 | mtpInputs.IssuerClaimNonRevMtpAuxHi = nodeAuxAuth.key 140 | mtpInputs.IssuerClaimNonRevMtpAuxHv = nodeAuxAuth.value 141 | 142 | gistNodeAux := GetNodeAuxValue(s.GISTProof.Proof) 143 | mtpInputs.GistMtpAuxHi = gistNodeAux.key 144 | mtpInputs.GistMtpAuxHv = gistNodeAux.value 145 | mtpInputs.GistMtpNoAux = gistNodeAux.noAux 146 | 147 | mtpInputs.RequestID = s.RequestID 148 | mtpInputs.IssuerID = s.IssuerClaim.IssuerID.BigInt().String() 149 | mtpInputs.Timestamp = s.Timestamp 150 | 151 | return json.Marshal(mtpInputs) 152 | } 153 | 154 | // Deprecated: trusted setup is not done for that circuits. In future releases 155 | // new circuit with sybil support will be added. 156 | type SybilAtomicMTPPubSignals struct { 157 | BaseConfig 158 | 159 | SybilID *big.Int `json:"sybilID"` 160 | UserID *core.ID `json:"userID"` 161 | 162 | RequestID *big.Int `json:"requestID"` 163 | IssuerID *core.ID `json:"issuerID"` 164 | Timestamp int64 `json:"timestamp"` 165 | 166 | IssuerClaimIdenState *merkletree.Hash `json:"issuerClaimIdenState"` 167 | IssuerClaimNonRevState *merkletree.Hash `json:"issuerClaimNonRevState"` 168 | ClaimSchema core.SchemaHash `json:"claimSchema"` 169 | 170 | CRS *big.Int `json:"crs"` 171 | 172 | GISTRoot *merkletree.Hash `json:"gistRoot"` 173 | } 174 | 175 | func (s *SybilAtomicMTPPubSignals) PubSignalsUnmarshal(data []byte) error { 176 | var sVals []string 177 | err := json.Unmarshal(data, &sVals) 178 | if err != nil { 179 | return err 180 | } 181 | 182 | if len(sVals) != 10 { 183 | return fmt.Errorf("invalid number of Output values expected {%d} got {%d} ", 10, len(sVals)) 184 | } 185 | 186 | // expected order: 187 | // 0 - userID 188 | // 1 - sybilID 189 | // 2 - issuerClaimIdenState 190 | // 3 - issuerClaimNonRevState 191 | // 4 - claimSchema 192 | // 5 - gistRoot 193 | // 6 - crs 194 | // 7 - requestID 195 | // 8 - issuerID 196 | // 9 - timestamp 197 | 198 | fieldIdx := 0 199 | 200 | if s.UserID, err = idFromIntStr(sVals[fieldIdx]); err != nil { 201 | return fmt.Errorf("invalid UserID value: '%s'", sVals[fieldIdx]) 202 | } 203 | fieldIdx++ 204 | 205 | var ok bool 206 | if s.SybilID, ok = big.NewInt(0).SetString(sVals[fieldIdx], 10); !ok { 207 | return fmt.Errorf("invalid SybilID value: '%s'", sVals[fieldIdx]) 208 | } 209 | fieldIdx++ 210 | 211 | if s.IssuerClaimIdenState, err = merkletree.NewHashFromString(sVals[fieldIdx]); err != nil { 212 | return fmt.Errorf("invalid IssuerClaimIdenState value: '%s'", sVals[fieldIdx]) 213 | } 214 | fieldIdx++ 215 | 216 | if s.IssuerClaimNonRevState, err = merkletree.NewHashFromString(sVals[fieldIdx]); err != nil { 217 | return fmt.Errorf("invalid IssuerClaimNonRevState value: '%s'", sVals[fieldIdx]) 218 | } 219 | fieldIdx++ 220 | 221 | var schemaInt *big.Int 222 | if schemaInt, ok = big.NewInt(0).SetString(sVals[fieldIdx], 10); !ok { 223 | return fmt.Errorf("invalid schema value: '%s'", sVals[fieldIdx]) 224 | } 225 | s.ClaimSchema = core.NewSchemaHashFromInt(schemaInt) 226 | fieldIdx++ 227 | 228 | if s.GISTRoot, err = merkletree.NewHashFromString(sVals[fieldIdx]); err != nil { 229 | return fmt.Errorf("invalid GISTRoot value: '%s'", sVals[fieldIdx]) 230 | } 231 | fieldIdx++ 232 | 233 | if s.CRS, ok = big.NewInt(0).SetString(sVals[fieldIdx], 10); !ok { 234 | return fmt.Errorf("invalid schema value: '%s'", sVals[fieldIdx]) 235 | } 236 | fieldIdx++ 237 | 238 | if s.RequestID, ok = big.NewInt(0).SetString(sVals[fieldIdx], 10); !ok { 239 | return fmt.Errorf("invalid requestID value: '%s'", sVals[fieldIdx]) 240 | } 241 | fieldIdx++ 242 | 243 | if s.IssuerID, err = idFromIntStr(sVals[fieldIdx]); err != nil { 244 | return fmt.Errorf("invalid IssuerID value: '%s'", sVals[fieldIdx]) 245 | } 246 | fieldIdx++ 247 | 248 | s.Timestamp, err = strconv.ParseInt(sVals[fieldIdx], 10, 64) 249 | if err != nil { 250 | return fmt.Errorf("invalid Timestamp value: '%s'", sVals[fieldIdx]) 251 | } 252 | 253 | return nil 254 | } 255 | 256 | func (s SybilAtomicMTPPubSignals) GetObjMap() map[string]interface{} { 257 | return toMap(s) 258 | } 259 | -------------------------------------------------------------------------------- /sybilCredentialAtomicMTP_test.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "math/big" 7 | "testing" 8 | 9 | it "github.com/iden3/go-circuits/v2/testing" 10 | core "github.com/iden3/go-iden3-core/v2" 11 | "github.com/stretchr/testify/assert" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func TestSybilMTP_PrepareInputs(t *testing.T) { 16 | 17 | user := it.NewIdentity(t, userPK) 18 | 19 | issuer := it.NewIdentity(t, issuerPK) 20 | 21 | subjectID := user.ID 22 | profileNonce := big.NewInt(0) 23 | 24 | nonceSubject := big.NewInt(0) 25 | 26 | requestID := new(big.Int).SetInt64(123) 27 | currentTimestamp := int64(1642074362) 28 | 29 | claim := it.DefaultUserClaim(t, subjectID) 30 | 31 | issuer.AddClaim(t, claim) 32 | 33 | issuerClaimMtp, _ := issuer.ClaimMTPRaw(t, claim) 34 | 35 | issuerClaimNonRevMtp, _ := issuer.ClaimRevMTPRaw(t, claim) 36 | 37 | crs, ok := new(big.Int).SetString("249532670194878832589534456260980839355904887861263878269048090946773573111", 10) 38 | if ok == false { 39 | t.Fatal("failed to set crs") 40 | } 41 | 42 | commClaim := it.UserStateCommitmentClaim(t, new(big.Int).SetInt64(5555)) 43 | user.AddClaim(t, commClaim) 44 | userClaimMtp, _ := user.ClaimMTPRaw(t, commClaim) 45 | 46 | gTree := it.GISTTree(context.Background()) 47 | err := gTree.Add(context.Background(), user.ID.BigInt(), user.State(t).BigInt()) 48 | require.NoError(t, err) 49 | 50 | gistProof, _, err := gTree.GenerateProof(context.Background(), user.ID.BigInt(), nil) 51 | require.NoError(t, err) 52 | 53 | in := SybilAtomicMTPInputs{ 54 | ID: &user.ID, 55 | ProfileNonce: profileNonce, 56 | ClaimSubjectProfileNonce: nonceSubject, 57 | IssuerClaim: ClaimWithMTPProof{ 58 | IssuerID: &issuer.ID, 59 | Claim: claim, 60 | NonRevProof: MTProof{ 61 | TreeState: TreeState{ 62 | State: issuer.State(t), 63 | ClaimsRoot: issuer.Clt.Root(), 64 | RevocationRoot: issuer.Ret.Root(), 65 | RootOfRoots: issuer.Rot.Root(), 66 | }, 67 | Proof: issuerClaimNonRevMtp, 68 | }, 69 | IncProof: MTProof{ 70 | Proof: issuerClaimMtp, 71 | TreeState: TreeState{ 72 | State: issuer.State(t), 73 | ClaimsRoot: issuer.Clt.Root(), 74 | RevocationRoot: issuer.Ret.Root(), 75 | RootOfRoots: issuer.Rot.Root(), 76 | }, 77 | }, 78 | }, 79 | CRS: crs, 80 | StateCommitmentClaim: ClaimWithMTPProof{ 81 | Claim: commClaim, 82 | IncProof: MTProof{ 83 | Proof: userClaimMtp, 84 | TreeState: TreeState{ 85 | State: user.State(t), 86 | ClaimsRoot: user.Clt.Root(), 87 | RevocationRoot: user.Ret.Root(), 88 | RootOfRoots: user.Rot.Root(), 89 | }, 90 | }, 91 | IssuerID: &user.ID, 92 | }, 93 | GISTProof: GISTProof{ 94 | Root: gTree.Root(), 95 | Proof: gistProof, 96 | }, 97 | RequestID: requestID, 98 | Timestamp: currentTimestamp, 99 | } 100 | 101 | circuitInputJSON, err := in.InputsMarshal() 102 | assert.Nil(t, err) 103 | 104 | exp := it.TestData(t, "sybilMTP_inputs", string(circuitInputJSON), *generate) 105 | t.Log(string(circuitInputJSON)) 106 | 107 | require.JSONEq(t, exp, string(circuitInputJSON)) 108 | } 109 | 110 | func TestSybilMTPOutputs_CircuitUnmarshal(t *testing.T) { 111 | out := new(SybilAtomicMTPPubSignals) 112 | 113 | err := out.PubSignalsUnmarshal([]byte(`[ 114 | "26109404700696283154998654512117952420503675471097392618762221546565140481", 115 | "223724973193705074823975451411003107344340988105892551868110723839705504514", 116 | "19157496396839393206871475267813888069926627705277243727237933406423274512449", 117 | "19157496396839393206871475267813888069926627705277243727237933406423274512449", 118 | "180410020913331409885634153623124536270", 119 | "12237249731937050748239754514110031073443409881058925518681107238397055045148", 120 | "249532670194878832589534456260980839355904887861263878269048090946773573111", 121 | "123", 122 | "27918766665310231445021466320959318414450284884582375163563581940319453185", 123 | "1642074362" 124 | ]`)) 125 | require.NoError(t, err) 126 | 127 | user := it.NewIdentity(t, userPK) 128 | 129 | issuer := it.NewIdentity(t, issuerPK) 130 | 131 | issuerClaimSchema, ok := new(big.Int).SetString("180410020913331409885634153623124536270", 10) 132 | if ok == false { 133 | t.Fatalf("new(big.Int).SetString has faild") 134 | } 135 | 136 | sybilID, ok := new(big.Int).SetString("223724973193705074823975451411003107344340988105892551868110723839705504514", 10) 137 | if ok == false { 138 | t.Fatalf("new(big.Int).SetString has faild") 139 | } 140 | 141 | crs, ok := new(big.Int).SetString("249532670194878832589534456260980839355904887861263878269048090946773573111", 10) 142 | if ok == false { 143 | t.Fatal("failed to set crs") 144 | } 145 | 146 | exp := SybilAtomicMTPPubSignals{ 147 | IssuerClaimNonRevState: it.MTHashFromStr(t, "19157496396839393206871475267813888069926627705277243727237933406423274512449"), 148 | CRS: crs, 149 | GISTRoot: it.MTHashFromStr(t, "12237249731937050748239754514110031073443409881058925518681107238397055045148"), 150 | IssuerClaimIdenState: it.MTHashFromStr(t, "19157496396839393206871475267813888069926627705277243727237933406423274512449"), 151 | IssuerID: &issuer.ID, 152 | RequestID: new(big.Int).SetInt64(123), 153 | Timestamp: 1642074362, 154 | UserID: &user.ID, 155 | ClaimSchema: core.NewSchemaHashFromInt(issuerClaimSchema), 156 | SybilID: sybilID, 157 | } 158 | 159 | jsonOut, err := json.Marshal(out) 160 | require.NoError(t, err) 161 | jsonExp, err := json.Marshal(exp) 162 | require.NoError(t, err) 163 | 164 | require.JSONEq(t, string(jsonExp), string(jsonOut)) 165 | } 166 | -------------------------------------------------------------------------------- /sybilCredentialAtomicSig_test.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "math/big" 7 | "testing" 8 | 9 | it "github.com/iden3/go-circuits/v2/testing" 10 | core "github.com/iden3/go-iden3-core/v2" 11 | "github.com/stretchr/testify/assert" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func TestSybilSig_PrepareInputs(t *testing.T) { 16 | 17 | user := it.NewIdentity(t, userPK) 18 | 19 | issuer := it.NewIdentity(t, issuerPK) 20 | 21 | subjectID := user.ID 22 | profileNonce := big.NewInt(0) 23 | 24 | nonceSubject := big.NewInt(0) 25 | 26 | requestID := new(big.Int).SetInt64(123) 27 | currentTimestamp := int64(1642074362) 28 | 29 | claim := it.DefaultUserClaim(t, subjectID) 30 | 31 | claimSig := issuer.SignClaim(t, claim) 32 | 33 | issuerClaimNonRevMtp, _ := issuer.ClaimRevMTPRaw(t, claim) 34 | 35 | issuerAuthClaimNonRevMtp, _ := issuer.ClaimRevMTPRaw(t, issuer.AuthClaim) 36 | issuerAuthClaimMtp, _ := issuer.ClaimMTPRaw(t, issuer.AuthClaim) 37 | 38 | crs, ok := new(big.Int).SetString("249532670194878832589534456260980839355904887861263878269048090946773573111", 10) 39 | if ok == false { 40 | t.Fatal("failed to set crs") 41 | } 42 | 43 | commClaim := it.UserStateCommitmentClaim(t, new(big.Int).SetInt64(5555)) 44 | user.AddClaim(t, commClaim) 45 | userClaimMtp, _ := user.ClaimMTPRaw(t, commClaim) 46 | 47 | gTree := it.GISTTree(context.Background()) 48 | err := gTree.Add(context.Background(), user.ID.BigInt(), user.State(t).BigInt()) 49 | require.NoError(t, err) 50 | 51 | gistProof, _, err := gTree.GenerateProof(context.Background(), user.ID.BigInt(), nil) 52 | require.NoError(t, err) 53 | 54 | in := SybilAtomicSigInputs{ 55 | ID: &user.ID, 56 | ProfileNonce: profileNonce, 57 | ClaimSubjectProfileNonce: nonceSubject, 58 | IssuerClaim: ClaimWithSigProof{ 59 | IssuerID: &issuer.ID, 60 | Claim: claim, 61 | NonRevProof: MTProof{ 62 | TreeState: TreeState{ 63 | State: issuer.State(t), 64 | ClaimsRoot: issuer.Clt.Root(), 65 | RevocationRoot: issuer.Ret.Root(), 66 | RootOfRoots: issuer.Rot.Root(), 67 | }, 68 | Proof: issuerClaimNonRevMtp, 69 | }, 70 | SignatureProof: BJJSignatureProof{ 71 | Signature: claimSig, 72 | IssuerAuthClaim: issuer.AuthClaim, 73 | IssuerAuthIncProof: MTProof{ 74 | TreeState: TreeState{ 75 | State: issuer.State(t), 76 | ClaimsRoot: issuer.Clt.Root(), 77 | RevocationRoot: issuer.Ret.Root(), 78 | RootOfRoots: issuer.Rot.Root(), 79 | }, 80 | Proof: issuerAuthClaimMtp, 81 | }, 82 | IssuerAuthNonRevProof: MTProof{ 83 | TreeState: TreeState{ 84 | State: issuer.State(t), 85 | ClaimsRoot: issuer.Clt.Root(), 86 | RevocationRoot: issuer.Ret.Root(), 87 | RootOfRoots: issuer.Rot.Root(), 88 | }, 89 | Proof: issuerAuthClaimNonRevMtp, 90 | }, 91 | }, 92 | }, 93 | CRS: crs, 94 | StateCommitmentClaim: ClaimWithMTPProof{ 95 | Claim: commClaim, 96 | IncProof: MTProof{ 97 | Proof: userClaimMtp, 98 | TreeState: TreeState{ 99 | State: user.State(t), 100 | ClaimsRoot: user.Clt.Root(), 101 | RevocationRoot: user.Ret.Root(), 102 | RootOfRoots: user.Rot.Root(), 103 | }, 104 | }, 105 | IssuerID: &user.ID, 106 | }, 107 | GISTProof: GISTProof{ 108 | Root: gTree.Root(), 109 | Proof: gistProof, 110 | }, 111 | RequestID: requestID, 112 | Timestamp: currentTimestamp, 113 | BaseConfig: BaseConfig{ 114 | MTLevelOnChain: 40, 115 | }, 116 | } 117 | 118 | circuitInputJSON, err := in.InputsMarshal() 119 | assert.Nil(t, err) 120 | 121 | exp := it.TestData(t, "sybilSig_inputs", string(circuitInputJSON), *generate) 122 | t.Log(string(circuitInputJSON)) 123 | 124 | require.JSONEq(t, exp, string(circuitInputJSON)) 125 | } 126 | 127 | func TestSybilSigOutputs_CircuitUnmarshal(t *testing.T) { 128 | out := new(SybilAtomicSigPubSignals) 129 | 130 | err := out.PubSignalsUnmarshal([]byte(`[ 131 | "223724973193705074823975451411003107344340988105892551868110723839705504514", 132 | "223724973193705074823975451411003107344340988105892551868110723839705504514", 133 | "26109404700696283154998654512117952420503675471097392618762221546565140481", 134 | "20177832565449474772630743317224985532862797657496372535616634430055981993180", 135 | "180410020913331409885634153623124536270", 136 | "12237249731937050748239754514110031073443409881058925518681107238397055045148", 137 | "249532670194878832589534456260980839355904887861263878269048090946773573111", 138 | "123", 139 | "27918766665310231445021466320959318414450284884582375163563581940319453185", 140 | "1642074362" 141 | ]`)) 142 | require.NoError(t, err) 143 | 144 | user := it.NewIdentity(t, userPK) 145 | 146 | issuer := it.NewIdentity(t, issuerPK) 147 | 148 | issuerClaimSchema, ok := new(big.Int).SetString("180410020913331409885634153623124536270", 10) 149 | if ok == false { 150 | t.Fatalf("new(big.Int).SetString has faild") 151 | } 152 | 153 | sybilID, ok := new(big.Int).SetString("223724973193705074823975451411003107344340988105892551868110723839705504514", 10) 154 | if ok == false { 155 | t.Fatalf("new(big.Int).SetString has faild") 156 | } 157 | 158 | crs, ok := new(big.Int).SetString("249532670194878832589534456260980839355904887861263878269048090946773573111", 10) 159 | if ok == false { 160 | t.Fatal("failed to set crs") 161 | } 162 | 163 | exp := SybilAtomicSigPubSignals{ 164 | IssuerClaimNonRevState: it.MTHashFromStr(t, "20177832565449474772630743317224985532862797657496372535616634430055981993180"), 165 | CRS: crs, 166 | GISTRoot: it.MTHashFromStr(t, "12237249731937050748239754514110031073443409881058925518681107238397055045148"), 167 | IssuerID: &issuer.ID, 168 | RequestID: new(big.Int).SetInt64(123), 169 | Timestamp: 1642074362, 170 | UserID: &user.ID, 171 | ClaimSchema: core.NewSchemaHashFromInt(issuerClaimSchema), 172 | SybilID: sybilID, 173 | IssuerAuthState: it.MTHashFromStr(t, "223724973193705074823975451411003107344340988105892551868110723839705504514"), 174 | } 175 | 176 | jsonOut, err := json.Marshal(out) 177 | require.NoError(t, err) 178 | jsonExp, err := json.Marshal(exp) 179 | require.NoError(t, err) 180 | 181 | require.JSONEq(t, string(jsonExp), string(jsonOut)) 182 | } 183 | -------------------------------------------------------------------------------- /testdata/V3_mtp_inputs.json: -------------------------------------------------------------------------------- 1 | { 2 | "requestID": "23", 3 | "userGenesisID": "26109404700696283154998654512117952420503675471097392618762221546565140481", 4 | "profileNonce": "0", 5 | "claimSubjectProfileNonce": "0", 6 | "issuerID": "27918766665310231445021466320959318414450284884582375163563581940319453185", 7 | "issuerClaim": [ 8 | "3583233690122716044519380227940806650830", 9 | "26109404700696283154998654512117952420503675471097392618762221546565140481", 10 | "10", 11 | "0", 12 | "30803922965249841627828060161", 13 | "0", 14 | "0", 15 | "0" 16 | ], 17 | "issuerClaimNonRevClaimsTreeRoot": "21551875744466996287712204148827400686061292275961899951444219768723484280073", 18 | "issuerClaimNonRevRevTreeRoot": "0", 19 | "issuerClaimNonRevRootsTreeRoot": "0", 20 | "issuerClaimNonRevState": "19157496396839393206871475267813888069926627705277243727237933406423274512449", 21 | "issuerClaimNonRevMtp": [ 22 | "0", 23 | "0", 24 | "0", 25 | "0", 26 | "0", 27 | "0", 28 | "0", 29 | "0", 30 | "0", 31 | "0", 32 | "0", 33 | "0", 34 | "0", 35 | "0", 36 | "0", 37 | "0", 38 | "0", 39 | "0", 40 | "0", 41 | "0", 42 | "0", 43 | "0", 44 | "0", 45 | "0", 46 | "0", 47 | "0", 48 | "0", 49 | "0", 50 | "0", 51 | "0", 52 | "0", 53 | "0", 54 | "0", 55 | "0", 56 | "0", 57 | "0", 58 | "0", 59 | "0", 60 | "0", 61 | "0" 62 | ], 63 | "issuerClaimNonRevMtpAuxHi": "0", 64 | "issuerClaimNonRevMtpAuxHv": "0", 65 | "issuerClaimNonRevMtpNoAux": "1", 66 | "claimSchema": "180410020913331409885634153623124536270", 67 | "issuerClaimSignatureR8x": "0", 68 | "issuerClaimSignatureR8y": "0", 69 | "issuerClaimSignatureS": "0", 70 | "issuerAuthClaim": ["0", "0", "0", "0", "0", "0", "0", "0"], 71 | "issuerAuthClaimMtp": [ 72 | "0", 73 | "0", 74 | "0", 75 | "0", 76 | "0", 77 | "0", 78 | "0", 79 | "0", 80 | "0", 81 | "0", 82 | "0", 83 | "0", 84 | "0", 85 | "0", 86 | "0", 87 | "0", 88 | "0", 89 | "0", 90 | "0", 91 | "0", 92 | "0", 93 | "0", 94 | "0", 95 | "0", 96 | "0", 97 | "0", 98 | "0", 99 | "0", 100 | "0", 101 | "0", 102 | "0", 103 | "0", 104 | "0", 105 | "0", 106 | "0", 107 | "0", 108 | "0", 109 | "0", 110 | "0", 111 | "0" 112 | ], 113 | "issuerAuthClaimNonRevMtp": [ 114 | "0", 115 | "0", 116 | "0", 117 | "0", 118 | "0", 119 | "0", 120 | "0", 121 | "0", 122 | "0", 123 | "0", 124 | "0", 125 | "0", 126 | "0", 127 | "0", 128 | "0", 129 | "0", 130 | "0", 131 | "0", 132 | "0", 133 | "0", 134 | "0", 135 | "0", 136 | "0", 137 | "0", 138 | "0", 139 | "0", 140 | "0", 141 | "0", 142 | "0", 143 | "0", 144 | "0", 145 | "0", 146 | "0", 147 | "0", 148 | "0", 149 | "0", 150 | "0", 151 | "0", 152 | "0", 153 | "0" 154 | ], 155 | "issuerAuthClaimNonRevMtpAuxHi": "0", 156 | "issuerAuthClaimNonRevMtpAuxHv": "0", 157 | "issuerAuthClaimNonRevMtpNoAux": "0", 158 | "issuerAuthClaimsTreeRoot": "0", 159 | "issuerAuthRevTreeRoot": "0", 160 | "issuerAuthRootsTreeRoot": "0", 161 | "issuerAuthState": "0", 162 | "isRevocationChecked": 1, 163 | "claimPathMtp": [ 164 | "0", 165 | "0", 166 | "0", 167 | "0", 168 | "0", 169 | "0", 170 | "0", 171 | "0", 172 | "0", 173 | "0", 174 | "0", 175 | "0", 176 | "0", 177 | "0", 178 | "0", 179 | "0", 180 | "0", 181 | "0", 182 | "0", 183 | "0", 184 | "0", 185 | "0", 186 | "0", 187 | "0", 188 | "0", 189 | "0", 190 | "0", 191 | "0", 192 | "0", 193 | "0", 194 | "0", 195 | "0" 196 | ], 197 | "claimPathMtpNoAux": "1", 198 | "claimPathMtpAuxHi": "0", 199 | "claimPathMtpAuxHv": "0", 200 | "claimPathKey": "0", 201 | "claimPathValue": "0", 202 | "operator": 1, 203 | "slotIndex": 2, 204 | "timestamp": 1642074362, 205 | "value": [ 206 | "10", 207 | "0", 208 | "0", 209 | "0", 210 | "0", 211 | "0", 212 | "0", 213 | "0", 214 | "0", 215 | "0", 216 | "0", 217 | "0", 218 | "0", 219 | "0", 220 | "0", 221 | "0", 222 | "0", 223 | "0", 224 | "0", 225 | "0", 226 | "0", 227 | "0", 228 | "0", 229 | "0", 230 | "0", 231 | "0", 232 | "0", 233 | "0", 234 | "0", 235 | "0", 236 | "0", 237 | "0", 238 | "0", 239 | "0", 240 | "0", 241 | "0", 242 | "0", 243 | "0", 244 | "0", 245 | "0", 246 | "0", 247 | "0", 248 | "0", 249 | "0", 250 | "0", 251 | "0", 252 | "0", 253 | "0", 254 | "0", 255 | "0", 256 | "0", 257 | "0", 258 | "0", 259 | "0", 260 | "0", 261 | "0", 262 | "0", 263 | "0", 264 | "0", 265 | "0", 266 | "0", 267 | "0", 268 | "0", 269 | "0" 270 | ], 271 | "valueArraySize": 1, 272 | "issuerClaimMtp": [ 273 | "0", 274 | "10304430946970870697981400054531724100803206948489006715521525892274350097449", 275 | "0", 276 | "0", 277 | "0", 278 | "0", 279 | "0", 280 | "0", 281 | "0", 282 | "0", 283 | "0", 284 | "0", 285 | "0", 286 | "0", 287 | "0", 288 | "0", 289 | "0", 290 | "0", 291 | "0", 292 | "0", 293 | "0", 294 | "0", 295 | "0", 296 | "0", 297 | "0", 298 | "0", 299 | "0", 300 | "0", 301 | "0", 302 | "0", 303 | "0", 304 | "0", 305 | "0", 306 | "0", 307 | "0", 308 | "0", 309 | "0", 310 | "0", 311 | "0", 312 | "0" 313 | ], 314 | "issuerClaimClaimsTreeRoot": "21551875744466996287712204148827400686061292275961899951444219768723484280073", 315 | "issuerClaimRevTreeRoot": "0", 316 | "issuerClaimRootsTreeRoot": "0", 317 | "issuerClaimIdenState": "19157496396839393206871475267813888069926627705277243727237933406423274512449", 318 | "proofType": "2", 319 | "linkNonce": "0", 320 | "verifierID": "21929109382993718606847853573861987353620810345503358891473103689157378049", 321 | "nullifierSessionID": "32" 322 | } 323 | -------------------------------------------------------------------------------- /testdata/V3_mtp_noop_inputs.json: -------------------------------------------------------------------------------- 1 | { 2 | "requestID": "23", 3 | "userGenesisID": "26109404700696283154998654512117952420503675471097392618762221546565140481", 4 | "profileNonce": "0", 5 | "claimSubjectProfileNonce": "0", 6 | "issuerID": "27918766665310231445021466320959318414450284884582375163563581940319453185", 7 | "issuerClaim": [ 8 | "3583233690122716044519380227940806650830", 9 | "26109404700696283154998654512117952420503675471097392618762221546565140481", 10 | "10", 11 | "0", 12 | "30803922965249841627828060161", 13 | "0", 14 | "0", 15 | "0" 16 | ], 17 | "issuerClaimNonRevClaimsTreeRoot": "21551875744466996287712204148827400686061292275961899951444219768723484280073", 18 | "issuerClaimNonRevRevTreeRoot": "0", 19 | "issuerClaimNonRevRootsTreeRoot": "0", 20 | "issuerClaimNonRevState": "19157496396839393206871475267813888069926627705277243727237933406423274512449", 21 | "issuerClaimNonRevMtp": [ 22 | "0", 23 | "0", 24 | "0", 25 | "0", 26 | "0", 27 | "0", 28 | "0", 29 | "0", 30 | "0", 31 | "0", 32 | "0", 33 | "0", 34 | "0", 35 | "0", 36 | "0", 37 | "0", 38 | "0", 39 | "0", 40 | "0", 41 | "0", 42 | "0", 43 | "0", 44 | "0", 45 | "0", 46 | "0", 47 | "0", 48 | "0", 49 | "0", 50 | "0", 51 | "0", 52 | "0", 53 | "0", 54 | "0", 55 | "0", 56 | "0", 57 | "0", 58 | "0", 59 | "0", 60 | "0", 61 | "0" 62 | ], 63 | "issuerClaimNonRevMtpAuxHi": "0", 64 | "issuerClaimNonRevMtpAuxHv": "0", 65 | "issuerClaimNonRevMtpNoAux": "1", 66 | "claimSchema": "180410020913331409885634153623124536270", 67 | "issuerClaimSignatureR8x": "0", 68 | "issuerClaimSignatureR8y": "0", 69 | "issuerClaimSignatureS": "0", 70 | "issuerAuthClaim": ["0", "0", "0", "0", "0", "0", "0", "0"], 71 | "issuerAuthClaimMtp": [ 72 | "0", 73 | "0", 74 | "0", 75 | "0", 76 | "0", 77 | "0", 78 | "0", 79 | "0", 80 | "0", 81 | "0", 82 | "0", 83 | "0", 84 | "0", 85 | "0", 86 | "0", 87 | "0", 88 | "0", 89 | "0", 90 | "0", 91 | "0", 92 | "0", 93 | "0", 94 | "0", 95 | "0", 96 | "0", 97 | "0", 98 | "0", 99 | "0", 100 | "0", 101 | "0", 102 | "0", 103 | "0", 104 | "0", 105 | "0", 106 | "0", 107 | "0", 108 | "0", 109 | "0", 110 | "0", 111 | "0" 112 | ], 113 | "issuerAuthClaimNonRevMtp": [ 114 | "0", 115 | "0", 116 | "0", 117 | "0", 118 | "0", 119 | "0", 120 | "0", 121 | "0", 122 | "0", 123 | "0", 124 | "0", 125 | "0", 126 | "0", 127 | "0", 128 | "0", 129 | "0", 130 | "0", 131 | "0", 132 | "0", 133 | "0", 134 | "0", 135 | "0", 136 | "0", 137 | "0", 138 | "0", 139 | "0", 140 | "0", 141 | "0", 142 | "0", 143 | "0", 144 | "0", 145 | "0", 146 | "0", 147 | "0", 148 | "0", 149 | "0", 150 | "0", 151 | "0", 152 | "0", 153 | "0" 154 | ], 155 | "issuerAuthClaimNonRevMtpAuxHi": "0", 156 | "issuerAuthClaimNonRevMtpAuxHv": "0", 157 | "issuerAuthClaimNonRevMtpNoAux": "0", 158 | "issuerAuthClaimsTreeRoot": "0", 159 | "issuerAuthRevTreeRoot": "0", 160 | "issuerAuthRootsTreeRoot": "0", 161 | "issuerAuthState": "0", 162 | "isRevocationChecked": 1, 163 | "claimPathMtp": [ 164 | "0", 165 | "0", 166 | "0", 167 | "0", 168 | "0", 169 | "0", 170 | "0", 171 | "0", 172 | "0", 173 | "0", 174 | "0", 175 | "0", 176 | "0", 177 | "0", 178 | "0", 179 | "0", 180 | "0", 181 | "0", 182 | "0", 183 | "0", 184 | "0", 185 | "0", 186 | "0", 187 | "0", 188 | "0", 189 | "0", 190 | "0", 191 | "0", 192 | "0", 193 | "0", 194 | "0", 195 | "0" 196 | ], 197 | "claimPathMtpNoAux": "1", 198 | "claimPathMtpAuxHi": "0", 199 | "claimPathMtpAuxHv": "0", 200 | "claimPathKey": "0", 201 | "claimPathValue": "0", 202 | "operator": 0, 203 | "slotIndex": 2, 204 | "timestamp": 1642074362, 205 | "value": [ 206 | "0", 207 | "0", 208 | "0", 209 | "0", 210 | "0", 211 | "0", 212 | "0", 213 | "0", 214 | "0", 215 | "0", 216 | "0", 217 | "0", 218 | "0", 219 | "0", 220 | "0", 221 | "0", 222 | "0", 223 | "0", 224 | "0", 225 | "0", 226 | "0", 227 | "0", 228 | "0", 229 | "0", 230 | "0", 231 | "0", 232 | "0", 233 | "0", 234 | "0", 235 | "0", 236 | "0", 237 | "0", 238 | "0", 239 | "0", 240 | "0", 241 | "0", 242 | "0", 243 | "0", 244 | "0", 245 | "0", 246 | "0", 247 | "0", 248 | "0", 249 | "0", 250 | "0", 251 | "0", 252 | "0", 253 | "0", 254 | "0", 255 | "0", 256 | "0", 257 | "0", 258 | "0", 259 | "0", 260 | "0", 261 | "0", 262 | "0", 263 | "0", 264 | "0", 265 | "0", 266 | "0", 267 | "0", 268 | "0", 269 | "0" 270 | ], 271 | "valueArraySize": 0, 272 | "issuerClaimMtp": [ 273 | "0", 274 | "10304430946970870697981400054531724100803206948489006715521525892274350097449", 275 | "0", 276 | "0", 277 | "0", 278 | "0", 279 | "0", 280 | "0", 281 | "0", 282 | "0", 283 | "0", 284 | "0", 285 | "0", 286 | "0", 287 | "0", 288 | "0", 289 | "0", 290 | "0", 291 | "0", 292 | "0", 293 | "0", 294 | "0", 295 | "0", 296 | "0", 297 | "0", 298 | "0", 299 | "0", 300 | "0", 301 | "0", 302 | "0", 303 | "0", 304 | "0", 305 | "0", 306 | "0", 307 | "0", 308 | "0", 309 | "0", 310 | "0", 311 | "0", 312 | "0" 313 | ], 314 | "issuerClaimClaimsTreeRoot": "21551875744466996287712204148827400686061292275961899951444219768723484280073", 315 | "issuerClaimRevTreeRoot": "0", 316 | "issuerClaimRootsTreeRoot": "0", 317 | "issuerClaimIdenState": "19157496396839393206871475267813888069926627705277243727237933406423274512449", 318 | "proofType": "2", 319 | "linkNonce": "0", 320 | "verifierID": "21929109382993718606847853573861987353620810345503358891473103689157378049", 321 | "nullifierSessionID": "32" 322 | } 323 | -------------------------------------------------------------------------------- /testdata/V3_sig_inputs.json: -------------------------------------------------------------------------------- 1 | { 2 | "requestID": "23", 3 | "userGenesisID": "26109404700696283154998654512117952420503675471097392618762221546565140481", 4 | "profileNonce": "0", 5 | "claimSubjectProfileNonce": "0", 6 | "issuerID": "27918766665310231445021466320959318414450284884582375163563581940319453185", 7 | "issuerClaim": [ 8 | "3583233690122716044519380227940806650830", 9 | "26109404700696283154998654512117952420503675471097392618762221546565140481", 10 | "10", 11 | "0", 12 | "30803922965249841627828060161", 13 | "0", 14 | "0", 15 | "0" 16 | ], 17 | "issuerClaimNonRevClaimsTreeRoot": "10304430946970870697981400054531724100803206948489006715521525892274350097449", 18 | "issuerClaimNonRevRevTreeRoot": "0", 19 | "issuerClaimNonRevRootsTreeRoot": "0", 20 | "issuerClaimNonRevState": "20177832565449474772630743317224985532862797657496372535616634430055981993180", 21 | "issuerClaimNonRevMtp": [ 22 | "0", 23 | "0", 24 | "0", 25 | "0", 26 | "0", 27 | "0", 28 | "0", 29 | "0", 30 | "0", 31 | "0", 32 | "0", 33 | "0", 34 | "0", 35 | "0", 36 | "0", 37 | "0", 38 | "0", 39 | "0", 40 | "0", 41 | "0", 42 | "0", 43 | "0", 44 | "0", 45 | "0", 46 | "0", 47 | "0", 48 | "0", 49 | "0", 50 | "0", 51 | "0", 52 | "0", 53 | "0", 54 | "0", 55 | "0", 56 | "0", 57 | "0", 58 | "0", 59 | "0", 60 | "0", 61 | "0" 62 | ], 63 | "issuerClaimNonRevMtpAuxHi": "0", 64 | "issuerClaimNonRevMtpAuxHv": "0", 65 | "issuerClaimNonRevMtpNoAux": "1", 66 | "claimSchema": "180410020913331409885634153623124536270", 67 | "issuerClaimSignatureR8x": "1651985418874087649697147889073653461168250997226887249132054770010575868904", 68 | "issuerClaimSignatureR8y": "21186185889289266863036576968009990777000485497741800844819909873882380374550", 69 | "issuerClaimSignatureS": "1462737848034339569304412491966425713268123077483712855404323511126257598464", 70 | "issuerAuthClaim": [ 71 | "80551937543569765027552589160822318028", 72 | "0", 73 | "9582165609074695838007712438814613121302719752874385708394134542816240804696", 74 | "18271435592817415588213874506882839610978320325722319742324814767882756910515", 75 | "11203087622270641253", 76 | "0", 77 | "0", 78 | "0" 79 | ], 80 | "issuerAuthClaimMtp": [ 81 | "0", 82 | "0", 83 | "0", 84 | "0", 85 | "0", 86 | "0", 87 | "0", 88 | "0", 89 | "0", 90 | "0", 91 | "0", 92 | "0", 93 | "0", 94 | "0", 95 | "0", 96 | "0", 97 | "0", 98 | "0", 99 | "0", 100 | "0", 101 | "0", 102 | "0", 103 | "0", 104 | "0", 105 | "0", 106 | "0", 107 | "0", 108 | "0", 109 | "0", 110 | "0", 111 | "0", 112 | "0", 113 | "0", 114 | "0", 115 | "0", 116 | "0", 117 | "0", 118 | "0", 119 | "0", 120 | "0" 121 | ], 122 | "issuerAuthClaimNonRevMtp": [ 123 | "0", 124 | "0", 125 | "0", 126 | "0", 127 | "0", 128 | "0", 129 | "0", 130 | "0", 131 | "0", 132 | "0", 133 | "0", 134 | "0", 135 | "0", 136 | "0", 137 | "0", 138 | "0", 139 | "0", 140 | "0", 141 | "0", 142 | "0", 143 | "0", 144 | "0", 145 | "0", 146 | "0", 147 | "0", 148 | "0", 149 | "0", 150 | "0", 151 | "0", 152 | "0", 153 | "0", 154 | "0", 155 | "0", 156 | "0", 157 | "0", 158 | "0", 159 | "0", 160 | "0", 161 | "0", 162 | "0" 163 | ], 164 | "issuerAuthClaimNonRevMtpAuxHi": "0", 165 | "issuerAuthClaimNonRevMtpAuxHv": "0", 166 | "issuerAuthClaimNonRevMtpNoAux": "1", 167 | "issuerAuthClaimsTreeRoot": "10304430946970870697981400054531724100803206948489006715521525892274350097449", 168 | "issuerAuthRevTreeRoot": "0", 169 | "issuerAuthRootsTreeRoot": "0", 170 | "issuerAuthState": "20177832565449474772630743317224985532862797657496372535616634430055981993180", 171 | "isRevocationChecked": 1, 172 | "claimPathMtp": [ 173 | "0", 174 | "0", 175 | "0", 176 | "0", 177 | "0", 178 | "0", 179 | "0", 180 | "0", 181 | "0", 182 | "0", 183 | "0", 184 | "0", 185 | "0", 186 | "0", 187 | "0", 188 | "0", 189 | "0", 190 | "0", 191 | "0", 192 | "0", 193 | "0", 194 | "0", 195 | "0", 196 | "0", 197 | "0", 198 | "0", 199 | "0", 200 | "0", 201 | "0", 202 | "0", 203 | "0", 204 | "0" 205 | ], 206 | "claimPathMtpNoAux": "1", 207 | "claimPathMtpAuxHi": "0", 208 | "claimPathMtpAuxHv": "0", 209 | "claimPathKey": "0", 210 | "claimPathValue": "0", 211 | "operator": 1, 212 | "slotIndex": 2, 213 | "timestamp": 1642074362, 214 | "value": [ 215 | "10", 216 | "0", 217 | "0", 218 | "0", 219 | "0", 220 | "0", 221 | "0", 222 | "0", 223 | "0", 224 | "0", 225 | "0", 226 | "0", 227 | "0", 228 | "0", 229 | "0", 230 | "0", 231 | "0", 232 | "0", 233 | "0", 234 | "0", 235 | "0", 236 | "0", 237 | "0", 238 | "0", 239 | "0", 240 | "0", 241 | "0", 242 | "0", 243 | "0", 244 | "0", 245 | "0", 246 | "0", 247 | "0", 248 | "0", 249 | "0", 250 | "0", 251 | "0", 252 | "0", 253 | "0", 254 | "0", 255 | "0", 256 | "0", 257 | "0", 258 | "0", 259 | "0", 260 | "0", 261 | "0", 262 | "0", 263 | "0", 264 | "0", 265 | "0", 266 | "0", 267 | "0", 268 | "0", 269 | "0", 270 | "0", 271 | "0", 272 | "0", 273 | "0", 274 | "0", 275 | "0", 276 | "0", 277 | "0", 278 | "0" 279 | ], 280 | "issuerClaimMtp": [ 281 | "0", 282 | "0", 283 | "0", 284 | "0", 285 | "0", 286 | "0", 287 | "0", 288 | "0", 289 | "0", 290 | "0", 291 | "0", 292 | "0", 293 | "0", 294 | "0", 295 | "0", 296 | "0", 297 | "0", 298 | "0", 299 | "0", 300 | "0", 301 | "0", 302 | "0", 303 | "0", 304 | "0", 305 | "0", 306 | "0", 307 | "0", 308 | "0", 309 | "0", 310 | "0", 311 | "0", 312 | "0", 313 | "0", 314 | "0", 315 | "0", 316 | "0", 317 | "0", 318 | "0", 319 | "0", 320 | "0" 321 | ], 322 | "valueArraySize": 1, 323 | "issuerClaimClaimsTreeRoot": "0", 324 | "issuerClaimRevTreeRoot": "0", 325 | "issuerClaimRootsTreeRoot": "0", 326 | "issuerClaimIdenState": "0", 327 | "proofType": "1", 328 | "linkNonce": "0", 329 | "verifierID": "21929109382993718606847853573861987353620810345503358891473103689157378049", 330 | "nullifierSessionID": "32" 331 | } 332 | -------------------------------------------------------------------------------- /testdata/authV2_inputs.json: -------------------------------------------------------------------------------- 1 | {"genesisID":"26109404700696283154998654512117952420503675471097392618762221546565140481","profileNonce":"0","authClaim":["80551937543569765027552589160822318028","0","17640206035128972995519606214765283372613874593503528180869261482403155458945","20634138280259599560273310290025659992320584624461316485434108770067472477956","15930428023331155902","0","0","0"],"authClaimIncMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"authClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"authClaimNonRevMtpAuxHi":"0","authClaimNonRevMtpAuxHv":"0","authClaimNonRevMtpNoAux":"1","challenge":"10","challengeSignatureR8x":"2436614617352067078274240654647841101298221663194055411539273018411814965042","challengeSignatureR8y":"18597752099468941062473075570139025288787892531282848931228194191266230422780","challengeSignatureS":"1642466479083925938589665711747519202726798003514101885795868643287098549939","claimsTreeRoot":"9860409408344985873118363460916733946840214387455464863344022463808838582364","revTreeRoot":"0","rootsTreeRoot":"0","state":"1648710229725601204870171311149827592640182384459240511403224642152766848235","gistRoot":"11098939821764568131087645431296528907277253709936443029379587475821759259406","gistMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"gistMtpAuxHi":"27918766665310231445021466320959318414450284884582375163563581940319453185","gistMtpAuxHv":"20177832565449474772630743317224985532862797657496372535616634430055981993180","gistMtpNoAux":"0"} -------------------------------------------------------------------------------- /testdata/mtpV2OnChain_inputs.json: -------------------------------------------------------------------------------- 1 | {"requestID":"23","userGenesisID":"26109404700696283154998654512117952420503675471097392618762221546565140481","profileNonce":"0","claimSubjectProfileNonce":"0","issuerID":"27918766665310231445021466320959318414450284884582375163563581940319453185","issuerClaim":["3583233690122716044519380227940806650830","26109404700696283154998654512117952420503675471097392618762221546565140481","10","0","30803922965249841627828060161","0","0","0"],"issuerClaimMtp":["0","10304430946970870697981400054531724100803206948489006715521525892274350097449","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerClaimClaimsTreeRoot":"21551875744466996287712204148827400686061292275961899951444219768723484280073","issuerClaimRevTreeRoot":"0","issuerClaimRootsTreeRoot":"0","issuerClaimIdenState":"19157496396839393206871475267813888069926627705277243727237933406423274512449","issuerClaimNonRevClaimsTreeRoot":"21551875744466996287712204148827400686061292275961899951444219768723484280073","issuerClaimNonRevRevTreeRoot":"0","issuerClaimNonRevRootsTreeRoot":"0","issuerClaimNonRevState":"19157496396839393206871475267813888069926627705277243727237933406423274512449","issuerClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerClaimNonRevMtpAuxHi":"0","issuerClaimNonRevMtpAuxHv":"0","issuerClaimNonRevMtpNoAux":"1","isRevocationChecked":1,"claimSchema":"180410020913331409885634153623124536270","claimPathNotExists":1,"claimPathMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"claimPathMtpNoAux":"1","claimPathMtpAuxHi":"0","claimPathMtpAuxHv":"0","claimPathKey":"0","claimPathValue":"0","operator":1,"slotIndex":2,"timestamp":1642074362,"value":["10","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"authClaim":["80551937543569765027552589160822318028","0","17640206035128972995519606214765283372613874593503528180869261482403155458945","20634138280259599560273310290025659992320584624461316485434108770067472477956","15930428023331155902","0","0","0"],"authClaimIncMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"authClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"authClaimNonRevMtpAuxHi":"0","authClaimNonRevMtpAuxHv":"0","authClaimNonRevMtpNoAux":"1","challenge":"10","challengeSignatureR8x":"2436614617352067078274240654647841101298221663194055411539273018411814965042","challengeSignatureR8y":"18597752099468941062473075570139025288787892531282848931228194191266230422780","challengeSignatureS":"1642466479083925938589665711747519202726798003514101885795868643287098549939","userClaimsTreeRoot":"9860409408344985873118363460916733946840214387455464863344022463808838582364","userRevTreeRoot":"0","userRootsTreeRoot":"0","userState":"1648710229725601204870171311149827592640182384459240511403224642152766848235","gistRoot":"11098939821764568131087645431296528907277253709936443029379587475821759259406","gistMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"gistMtpAuxHi":"27918766665310231445021466320959318414450284884582375163563581940319453185","gistMtpAuxHv":"20177832565449474772630743317224985532862797657496372535616634430055981993180","gistMtpNoAux":"0"} -------------------------------------------------------------------------------- /testdata/mtpV2_inputs.json: -------------------------------------------------------------------------------- 1 | {"requestID":"23","userGenesisID":"26109404700696283154998654512117952420503675471097392618762221546565140481","profileNonce":"0","claimSubjectProfileNonce":"0","issuerID":"27918766665310231445021466320959318414450284884582375163563581940319453185","issuerClaim":["3583233690122716044519380227940806650830","26109404700696283154998654512117952420503675471097392618762221546565140481","10","0","30803922965249841627828060161","0","0","0"],"issuerClaimMtp":["0","10304430946970870697981400054531724100803206948489006715521525892274350097449","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerClaimClaimsTreeRoot":"21551875744466996287712204148827400686061292275961899951444219768723484280073","issuerClaimRevTreeRoot":"0","issuerClaimRootsTreeRoot":"0","issuerClaimIdenState":"19157496396839393206871475267813888069926627705277243727237933406423274512449","issuerClaimNonRevClaimsTreeRoot":"21551875744466996287712204148827400686061292275961899951444219768723484280073","issuerClaimNonRevRevTreeRoot":"0","issuerClaimNonRevRootsTreeRoot":"0","issuerClaimNonRevState":"19157496396839393206871475267813888069926627705277243727237933406423274512449","issuerClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerClaimNonRevMtpAuxHi":"0","issuerClaimNonRevMtpAuxHv":"0","issuerClaimNonRevMtpNoAux":"1","isRevocationChecked":1,"claimSchema":"180410020913331409885634153623124536270","claimPathNotExists":1,"claimPathMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"claimPathMtpNoAux":"1","claimPathMtpAuxHi":"0","claimPathMtpAuxHv":"0","claimPathKey":"0","claimPathValue":"0","operator":1,"slotIndex":2,"timestamp":1642074362,"value":["10","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"]} -------------------------------------------------------------------------------- /testdata/onchain_V3_mtp_inputs.json: -------------------------------------------------------------------------------- 1 | { 2 | "requestID": "23", 3 | "userGenesisID": "26109404700696283154998654512117952420503675471097392618762221546565140481", 4 | "profileNonce": "0", 5 | "claimSubjectProfileNonce": "0", 6 | "issuerID": "27918766665310231445021466320959318414450284884582375163563581940319453185", 7 | "issuerClaim": [ 8 | "3583233690122716044519380227940806650830", 9 | "26109404700696283154998654512117952420503675471097392618762221546565140481", 10 | "10", 11 | "0", 12 | "30803922965249841627828060161", 13 | "0", 14 | "0", 15 | "0" 16 | ], 17 | "issuerClaimMtp": [ 18 | "0", 19 | "10304430946970870697981400054531724100803206948489006715521525892274350097449", 20 | "0", 21 | "0", 22 | "0", 23 | "0", 24 | "0", 25 | "0", 26 | "0", 27 | "0", 28 | "0", 29 | "0", 30 | "0", 31 | "0", 32 | "0", 33 | "0", 34 | "0", 35 | "0", 36 | "0", 37 | "0", 38 | "0", 39 | "0", 40 | "0", 41 | "0", 42 | "0", 43 | "0", 44 | "0", 45 | "0", 46 | "0", 47 | "0", 48 | "0", 49 | "0", 50 | "0", 51 | "0", 52 | "0", 53 | "0", 54 | "0", 55 | "0", 56 | "0", 57 | "0" 58 | ], 59 | "issuerClaimClaimsTreeRoot": "21551875744466996287712204148827400686061292275961899951444219768723484280073", 60 | "issuerClaimRevTreeRoot": "0", 61 | "issuerClaimRootsTreeRoot": "0", 62 | "issuerClaimIdenState": "19157496396839393206871475267813888069926627705277243727237933406423274512449", 63 | "issuerClaimNonRevClaimsTreeRoot": "21551875744466996287712204148827400686061292275961899951444219768723484280073", 64 | "issuerClaimNonRevRevTreeRoot": "0", 65 | "issuerClaimNonRevRootsTreeRoot": "0", 66 | "issuerClaimNonRevState": "19157496396839393206871475267813888069926627705277243727237933406423274512449", 67 | "issuerClaimNonRevMtp": [ 68 | "0", 69 | "0", 70 | "0", 71 | "0", 72 | "0", 73 | "0", 74 | "0", 75 | "0", 76 | "0", 77 | "0", 78 | "0", 79 | "0", 80 | "0", 81 | "0", 82 | "0", 83 | "0", 84 | "0", 85 | "0", 86 | "0", 87 | "0", 88 | "0", 89 | "0", 90 | "0", 91 | "0", 92 | "0", 93 | "0", 94 | "0", 95 | "0", 96 | "0", 97 | "0", 98 | "0", 99 | "0", 100 | "0", 101 | "0", 102 | "0", 103 | "0", 104 | "0", 105 | "0", 106 | "0", 107 | "0" 108 | ], 109 | "issuerClaimNonRevMtpAuxHi": "0", 110 | "issuerClaimNonRevMtpAuxHv": "0", 111 | "issuerClaimNonRevMtpNoAux": "1", 112 | "isRevocationChecked": 1, 113 | "claimSchema": "180410020913331409885634153623124536270", 114 | "claimPathMtp": [ 115 | "0", 116 | "0", 117 | "0", 118 | "0", 119 | "0", 120 | "0", 121 | "0", 122 | "0", 123 | "0", 124 | "0", 125 | "0", 126 | "0", 127 | "0", 128 | "0", 129 | "0", 130 | "0", 131 | "0", 132 | "0", 133 | "0", 134 | "0", 135 | "0", 136 | "0", 137 | "0", 138 | "0", 139 | "0", 140 | "0", 141 | "0", 142 | "0", 143 | "0", 144 | "0", 145 | "0", 146 | "0" 147 | ], 148 | "claimPathMtpNoAux": "1", 149 | "claimPathMtpAuxHi": "0", 150 | "claimPathMtpAuxHv": "0", 151 | "claimPathKey": "0", 152 | "claimPathValue": "0", 153 | "operator": 1, 154 | "slotIndex": 2, 155 | "timestamp": 1642074362, 156 | "value": [ 157 | "10", 158 | "0", 159 | "0", 160 | "0", 161 | "0", 162 | "0", 163 | "0", 164 | "0", 165 | "0", 166 | "0", 167 | "0", 168 | "0", 169 | "0", 170 | "0", 171 | "0", 172 | "0", 173 | "0", 174 | "0", 175 | "0", 176 | "0", 177 | "0", 178 | "0", 179 | "0", 180 | "0", 181 | "0", 182 | "0", 183 | "0", 184 | "0", 185 | "0", 186 | "0", 187 | "0", 188 | "0", 189 | "0", 190 | "0", 191 | "0", 192 | "0", 193 | "0", 194 | "0", 195 | "0", 196 | "0", 197 | "0", 198 | "0", 199 | "0", 200 | "0", 201 | "0", 202 | "0", 203 | "0", 204 | "0", 205 | "0", 206 | "0", 207 | "0", 208 | "0", 209 | "0", 210 | "0", 211 | "0", 212 | "0", 213 | "0", 214 | "0", 215 | "0", 216 | "0", 217 | "0", 218 | "0", 219 | "0", 220 | "0" 221 | ], 222 | "authClaim": [ 223 | "80551937543569765027552589160822318028", 224 | "0", 225 | "17640206035128972995519606214765283372613874593503528180869261482403155458945", 226 | "20634138280259599560273310290025659992320584624461316485434108770067472477956", 227 | "15930428023331155902", 228 | "0", 229 | "0", 230 | "0" 231 | ], 232 | "authClaimIncMtp": [ 233 | "0", 234 | "0", 235 | "0", 236 | "0", 237 | "0", 238 | "0", 239 | "0", 240 | "0", 241 | "0", 242 | "0", 243 | "0", 244 | "0", 245 | "0", 246 | "0", 247 | "0", 248 | "0", 249 | "0", 250 | "0", 251 | "0", 252 | "0", 253 | "0", 254 | "0", 255 | "0", 256 | "0", 257 | "0", 258 | "0", 259 | "0", 260 | "0", 261 | "0", 262 | "0", 263 | "0", 264 | "0", 265 | "0", 266 | "0", 267 | "0", 268 | "0", 269 | "0", 270 | "0", 271 | "0", 272 | "0" 273 | ], 274 | "authClaimNonRevMtp": [ 275 | "0", 276 | "0", 277 | "0", 278 | "0", 279 | "0", 280 | "0", 281 | "0", 282 | "0", 283 | "0", 284 | "0", 285 | "0", 286 | "0", 287 | "0", 288 | "0", 289 | "0", 290 | "0", 291 | "0", 292 | "0", 293 | "0", 294 | "0", 295 | "0", 296 | "0", 297 | "0", 298 | "0", 299 | "0", 300 | "0", 301 | "0", 302 | "0", 303 | "0", 304 | "0", 305 | "0", 306 | "0", 307 | "0", 308 | "0", 309 | "0", 310 | "0", 311 | "0", 312 | "0", 313 | "0", 314 | "0" 315 | ], 316 | "authClaimNonRevMtpAuxHi": "0", 317 | "authClaimNonRevMtpAuxHv": "0", 318 | "authClaimNonRevMtpNoAux": "1", 319 | "challenge": "10", 320 | "challengeSignatureR8x": "2436614617352067078274240654647841101298221663194055411539273018411814965042", 321 | "challengeSignatureR8y": "18597752099468941062473075570139025288787892531282848931228194191266230422780", 322 | "challengeSignatureS": "1642466479083925938589665711747519202726798003514101885795868643287098549939", 323 | "userClaimsTreeRoot": "9860409408344985873118363460916733946840214387455464863344022463808838582364", 324 | "userRevTreeRoot": "0", 325 | "userRootsTreeRoot": "0", 326 | "userState": "1648710229725601204870171311149827592640182384459240511403224642152766848235", 327 | "gistRoot": "15222217882518596940074630337957696952188390066909734692961129860915499995393", 328 | "gistMtp": [ 329 | "0", 330 | "0", 331 | "0", 332 | "0", 333 | "0", 334 | "0", 335 | "0", 336 | "0", 337 | "0", 338 | "0", 339 | "0", 340 | "0", 341 | "0", 342 | "0", 343 | "0", 344 | "0", 345 | "0", 346 | "0", 347 | "0", 348 | "0", 349 | "0", 350 | "0", 351 | "0", 352 | "0", 353 | "0", 354 | "0", 355 | "0", 356 | "0", 357 | "0", 358 | "0", 359 | "0", 360 | "0", 361 | "0", 362 | "0", 363 | "0", 364 | "0", 365 | "0", 366 | "0", 367 | "0", 368 | "0", 369 | "0", 370 | "0", 371 | "0", 372 | "0", 373 | "0", 374 | "0", 375 | "0", 376 | "0", 377 | "0", 378 | "0", 379 | "0", 380 | "0", 381 | "0", 382 | "0", 383 | "0", 384 | "0", 385 | "0", 386 | "0", 387 | "0", 388 | "0", 389 | "0", 390 | "0", 391 | "0", 392 | "0" 393 | ], 394 | "gistMtpAuxHi": "27918766665310231445021466320959318414450284884582375163563581940319453185", 395 | "gistMtpAuxHv": "19157496396839393206871475267813888069926627705277243727237933406423274512449", 396 | "gistMtpNoAux": "0", 397 | "proofType": "2", 398 | "issuerClaimSignatureR8x": "0", 399 | "issuerClaimSignatureR8y": "0", 400 | "issuerClaimSignatureS": "0", 401 | "issuerAuthClaimNonRevMtpAuxHi": "0", 402 | "issuerAuthClaimNonRevMtpAuxHv": "0", 403 | "issuerAuthClaimNonRevMtpNoAux": "0", 404 | "issuerAuthClaimsTreeRoot": "0", 405 | "issuerAuthRevTreeRoot": "0", 406 | "issuerAuthRootsTreeRoot": "0", 407 | "issuerAuthState": "0", 408 | "issuerAuthClaimNonRevMtp": [ 409 | "0", 410 | "0", 411 | "0", 412 | "0", 413 | "0", 414 | "0", 415 | "0", 416 | "0", 417 | "0", 418 | "0", 419 | "0", 420 | "0", 421 | "0", 422 | "0", 423 | "0", 424 | "0", 425 | "0", 426 | "0", 427 | "0", 428 | "0", 429 | "0", 430 | "0", 431 | "0", 432 | "0", 433 | "0", 434 | "0", 435 | "0", 436 | "0", 437 | "0", 438 | "0", 439 | "0", 440 | "0", 441 | "0", 442 | "0", 443 | "0", 444 | "0", 445 | "0", 446 | "0", 447 | "0", 448 | "0" 449 | ], 450 | "issuerAuthClaim": ["0", "0", "0", "0", "0", "0", "0", "0"], 451 | "issuerAuthClaimMtp": [ 452 | "0", 453 | "0", 454 | "0", 455 | "0", 456 | "0", 457 | "0", 458 | "0", 459 | "0", 460 | "0", 461 | "0", 462 | "0", 463 | "0", 464 | "0", 465 | "0", 466 | "0", 467 | "0", 468 | "0", 469 | "0", 470 | "0", 471 | "0", 472 | "0", 473 | "0", 474 | "0", 475 | "0", 476 | "0", 477 | "0", 478 | "0", 479 | "0", 480 | "0", 481 | "0", 482 | "0", 483 | "0", 484 | "0", 485 | "0", 486 | "0", 487 | "0", 488 | "0", 489 | "0", 490 | "0", 491 | "0" 492 | ], 493 | "valueArraySize": 1, 494 | "linkNonce": "0", 495 | "verifierID": "21929109382993718606847853573861987353620810345503358891473103689157378049", 496 | "nullifierSessionID": "32", 497 | "isBJJAuthEnabled": "1" 498 | } 499 | -------------------------------------------------------------------------------- /testdata/onchain_V3_sig_inputs.json: -------------------------------------------------------------------------------- 1 | { 2 | "requestID": "23", 3 | "userGenesisID": "26109404700696283154998654512117952420503675471097392618762221546565140481", 4 | "profileNonce": "0", 5 | "claimSubjectProfileNonce": "0", 6 | "issuerID": "27918766665310231445021466320959318414450284884582375163563581940319453185", 7 | "issuerClaim": [ 8 | "3583233690122716044519380227940806650830", 9 | "26109404700696283154998654512117952420503675471097392618762221546565140481", 10 | "10", 11 | "0", 12 | "30803922965249841627828060161", 13 | "0", 14 | "0", 15 | "0" 16 | ], 17 | "issuerClaimNonRevClaimsTreeRoot": "10304430946970870697981400054531724100803206948489006715521525892274350097449", 18 | "issuerClaimNonRevRevTreeRoot": "0", 19 | "issuerClaimNonRevRootsTreeRoot": "0", 20 | "issuerClaimNonRevState": "20177832565449474772630743317224985532862797657496372535616634430055981993180", 21 | "issuerClaimNonRevMtp": [ 22 | "0", 23 | "0", 24 | "0", 25 | "0", 26 | "0", 27 | "0", 28 | "0", 29 | "0", 30 | "0", 31 | "0", 32 | "0", 33 | "0", 34 | "0", 35 | "0", 36 | "0", 37 | "0", 38 | "0", 39 | "0", 40 | "0", 41 | "0", 42 | "0", 43 | "0", 44 | "0", 45 | "0", 46 | "0", 47 | "0", 48 | "0", 49 | "0", 50 | "0", 51 | "0", 52 | "0", 53 | "0", 54 | "0", 55 | "0", 56 | "0", 57 | "0", 58 | "0", 59 | "0", 60 | "0", 61 | "0" 62 | ], 63 | "issuerClaimNonRevMtpAuxHi": "0", 64 | "issuerClaimNonRevMtpAuxHv": "0", 65 | "issuerClaimNonRevMtpNoAux": "1", 66 | "claimSchema": "180410020913331409885634153623124536270", 67 | "issuerClaimSignatureR8x": "1651985418874087649697147889073653461168250997226887249132054770010575868904", 68 | "issuerClaimSignatureR8y": "21186185889289266863036576968009990777000485497741800844819909873882380374550", 69 | "issuerClaimSignatureS": "1462737848034339569304412491966425713268123077483712855404323511126257598464", 70 | "issuerAuthClaim": [ 71 | "80551937543569765027552589160822318028", 72 | "0", 73 | "9582165609074695838007712438814613121302719752874385708394134542816240804696", 74 | "18271435592817415588213874506882839610978320325722319742324814767882756910515", 75 | "11203087622270641253", 76 | "0", 77 | "0", 78 | "0" 79 | ], 80 | "issuerAuthClaimMtp": [ 81 | "0", 82 | "0", 83 | "0", 84 | "0", 85 | "0", 86 | "0", 87 | "0", 88 | "0", 89 | "0", 90 | "0", 91 | "0", 92 | "0", 93 | "0", 94 | "0", 95 | "0", 96 | "0", 97 | "0", 98 | "0", 99 | "0", 100 | "0", 101 | "0", 102 | "0", 103 | "0", 104 | "0", 105 | "0", 106 | "0", 107 | "0", 108 | "0", 109 | "0", 110 | "0", 111 | "0", 112 | "0", 113 | "0", 114 | "0", 115 | "0", 116 | "0", 117 | "0", 118 | "0", 119 | "0", 120 | "0" 121 | ], 122 | "issuerAuthClaimNonRevMtp": [ 123 | "0", 124 | "0", 125 | "0", 126 | "0", 127 | "0", 128 | "0", 129 | "0", 130 | "0", 131 | "0", 132 | "0", 133 | "0", 134 | "0", 135 | "0", 136 | "0", 137 | "0", 138 | "0", 139 | "0", 140 | "0", 141 | "0", 142 | "0", 143 | "0", 144 | "0", 145 | "0", 146 | "0", 147 | "0", 148 | "0", 149 | "0", 150 | "0", 151 | "0", 152 | "0", 153 | "0", 154 | "0", 155 | "0", 156 | "0", 157 | "0", 158 | "0", 159 | "0", 160 | "0", 161 | "0", 162 | "0" 163 | ], 164 | "issuerAuthClaimNonRevMtpAuxHi": "0", 165 | "issuerAuthClaimNonRevMtpAuxHv": "0", 166 | "issuerAuthClaimNonRevMtpNoAux": "1", 167 | "issuerAuthClaimsTreeRoot": "10304430946970870697981400054531724100803206948489006715521525892274350097449", 168 | "issuerAuthRevTreeRoot": "0", 169 | "issuerAuthRootsTreeRoot": "0", 170 | "issuerAuthState": "20177832565449474772630743317224985532862797657496372535616634430055981993180", 171 | "isRevocationChecked": 1, 172 | "claimPathMtp": [ 173 | "0", 174 | "0", 175 | "0", 176 | "0", 177 | "0", 178 | "0", 179 | "0", 180 | "0", 181 | "0", 182 | "0", 183 | "0", 184 | "0", 185 | "0", 186 | "0", 187 | "0", 188 | "0", 189 | "0", 190 | "0", 191 | "0", 192 | "0", 193 | "0", 194 | "0", 195 | "0", 196 | "0", 197 | "0", 198 | "0", 199 | "0", 200 | "0", 201 | "0", 202 | "0", 203 | "0", 204 | "0" 205 | ], 206 | "claimPathMtpNoAux": "1", 207 | "claimPathMtpAuxHi": "0", 208 | "claimPathMtpAuxHv": "0", 209 | "claimPathKey": "0", 210 | "claimPathValue": "0", 211 | "operator": 1, 212 | "slotIndex": 2, 213 | "timestamp": 1642074362, 214 | "value": [ 215 | "10", 216 | "0", 217 | "0", 218 | "0", 219 | "0", 220 | "0", 221 | "0", 222 | "0", 223 | "0", 224 | "0", 225 | "0", 226 | "0", 227 | "0", 228 | "0", 229 | "0", 230 | "0", 231 | "0", 232 | "0", 233 | "0", 234 | "0", 235 | "0", 236 | "0", 237 | "0", 238 | "0", 239 | "0", 240 | "0", 241 | "0", 242 | "0", 243 | "0", 244 | "0", 245 | "0", 246 | "0", 247 | "0", 248 | "0", 249 | "0", 250 | "0", 251 | "0", 252 | "0", 253 | "0", 254 | "0", 255 | "0", 256 | "0", 257 | "0", 258 | "0", 259 | "0", 260 | "0", 261 | "0", 262 | "0", 263 | "0", 264 | "0", 265 | "0", 266 | "0", 267 | "0", 268 | "0", 269 | "0", 270 | "0", 271 | "0", 272 | "0", 273 | "0", 274 | "0", 275 | "0", 276 | "0", 277 | "0", 278 | "0" 279 | ], 280 | "authClaim": [ 281 | "80551937543569765027552589160822318028", 282 | "0", 283 | "17640206035128972995519606214765283372613874593503528180869261482403155458945", 284 | "20634138280259599560273310290025659992320584624461316485434108770067472477956", 285 | "15930428023331155902", 286 | "0", 287 | "0", 288 | "0" 289 | ], 290 | "authClaimIncMtp": [ 291 | "0", 292 | "0", 293 | "0", 294 | "0", 295 | "0", 296 | "0", 297 | "0", 298 | "0", 299 | "0", 300 | "0", 301 | "0", 302 | "0", 303 | "0", 304 | "0", 305 | "0", 306 | "0", 307 | "0", 308 | "0", 309 | "0", 310 | "0", 311 | "0", 312 | "0", 313 | "0", 314 | "0", 315 | "0", 316 | "0", 317 | "0", 318 | "0", 319 | "0", 320 | "0", 321 | "0", 322 | "0", 323 | "0", 324 | "0", 325 | "0", 326 | "0", 327 | "0", 328 | "0", 329 | "0", 330 | "0" 331 | ], 332 | "authClaimNonRevMtp": [ 333 | "0", 334 | "0", 335 | "0", 336 | "0", 337 | "0", 338 | "0", 339 | "0", 340 | "0", 341 | "0", 342 | "0", 343 | "0", 344 | "0", 345 | "0", 346 | "0", 347 | "0", 348 | "0", 349 | "0", 350 | "0", 351 | "0", 352 | "0", 353 | "0", 354 | "0", 355 | "0", 356 | "0", 357 | "0", 358 | "0", 359 | "0", 360 | "0", 361 | "0", 362 | "0", 363 | "0", 364 | "0", 365 | "0", 366 | "0", 367 | "0", 368 | "0", 369 | "0", 370 | "0", 371 | "0", 372 | "0" 373 | ], 374 | "authClaimNonRevMtpAuxHi": "0", 375 | "authClaimNonRevMtpAuxHv": "0", 376 | "authClaimNonRevMtpNoAux": "1", 377 | "challenge": "10", 378 | "challengeSignatureR8x": "2436614617352067078274240654647841101298221663194055411539273018411814965042", 379 | "challengeSignatureR8y": "18597752099468941062473075570139025288787892531282848931228194191266230422780", 380 | "challengeSignatureS": "1642466479083925938589665711747519202726798003514101885795868643287098549939", 381 | "userClaimsTreeRoot": "9860409408344985873118363460916733946840214387455464863344022463808838582364", 382 | "userRevTreeRoot": "0", 383 | "userRootsTreeRoot": "0", 384 | "userState": "1648710229725601204870171311149827592640182384459240511403224642152766848235", 385 | "gistRoot": "11098939821764568131087645431296528907277253709936443029379587475821759259406", 386 | "gistMtp": [ 387 | "0", 388 | "0", 389 | "0", 390 | "0", 391 | "0", 392 | "0", 393 | "0", 394 | "0", 395 | "0", 396 | "0", 397 | "0", 398 | "0", 399 | "0", 400 | "0", 401 | "0", 402 | "0", 403 | "0", 404 | "0", 405 | "0", 406 | "0", 407 | "0", 408 | "0", 409 | "0", 410 | "0", 411 | "0", 412 | "0", 413 | "0", 414 | "0", 415 | "0", 416 | "0", 417 | "0", 418 | "0", 419 | "0", 420 | "0", 421 | "0", 422 | "0", 423 | "0", 424 | "0", 425 | "0", 426 | "0", 427 | "0", 428 | "0", 429 | "0", 430 | "0", 431 | "0", 432 | "0", 433 | "0", 434 | "0", 435 | "0", 436 | "0", 437 | "0", 438 | "0", 439 | "0", 440 | "0", 441 | "0", 442 | "0", 443 | "0", 444 | "0", 445 | "0", 446 | "0", 447 | "0", 448 | "0", 449 | "0", 450 | "0" 451 | ], 452 | "gistMtpAuxHi": "27918766665310231445021466320959318414450284884582375163563581940319453185", 453 | "gistMtpAuxHv": "20177832565449474772630743317224985532862797657496372535616634430055981993180", 454 | "gistMtpNoAux": "0", 455 | "proofType": "1", 456 | "issuerClaimMtp": [ 457 | "0", 458 | "0", 459 | "0", 460 | "0", 461 | "0", 462 | "0", 463 | "0", 464 | "0", 465 | "0", 466 | "0", 467 | "0", 468 | "0", 469 | "0", 470 | "0", 471 | "0", 472 | "0", 473 | "0", 474 | "0", 475 | "0", 476 | "0", 477 | "0", 478 | "0", 479 | "0", 480 | "0", 481 | "0", 482 | "0", 483 | "0", 484 | "0", 485 | "0", 486 | "0", 487 | "0", 488 | "0", 489 | "0", 490 | "0", 491 | "0", 492 | "0", 493 | "0", 494 | "0", 495 | "0", 496 | "0" 497 | ], 498 | "valueArraySize": 1, 499 | "issuerClaimClaimsTreeRoot": "0", 500 | "issuerClaimRevTreeRoot": "0", 501 | "issuerClaimRootsTreeRoot": "0", 502 | "issuerClaimIdenState": "0", 503 | "linkNonce": "0", 504 | "verifierID": "21929109382993718606847853573861987353620810345503358891473103689157378049", 505 | "nullifierSessionID": "32", 506 | "isBJJAuthEnabled": "1" 507 | } 508 | -------------------------------------------------------------------------------- /testdata/onchain_V3_sig_noop_inputs.json: -------------------------------------------------------------------------------- 1 | { 2 | "requestID": "23", 3 | "userGenesisID": "26109404700696283154998654512117952420503675471097392618762221546565140481", 4 | "profileNonce": "0", 5 | "claimSubjectProfileNonce": "0", 6 | "issuerID": "27918766665310231445021466320959318414450284884582375163563581940319453185", 7 | "issuerClaim": [ 8 | "3583233690122716044519380227940806650830", 9 | "26109404700696283154998654512117952420503675471097392618762221546565140481", 10 | "10", 11 | "0", 12 | "30803922965249841627828060161", 13 | "0", 14 | "0", 15 | "0" 16 | ], 17 | "issuerClaimNonRevClaimsTreeRoot": "10304430946970870697981400054531724100803206948489006715521525892274350097449", 18 | "issuerClaimNonRevRevTreeRoot": "0", 19 | "issuerClaimNonRevRootsTreeRoot": "0", 20 | "issuerClaimNonRevState": "20177832565449474772630743317224985532862797657496372535616634430055981993180", 21 | "issuerClaimNonRevMtp": [ 22 | "0", 23 | "0", 24 | "0", 25 | "0", 26 | "0", 27 | "0", 28 | "0", 29 | "0", 30 | "0", 31 | "0", 32 | "0", 33 | "0", 34 | "0", 35 | "0", 36 | "0", 37 | "0", 38 | "0", 39 | "0", 40 | "0", 41 | "0", 42 | "0", 43 | "0", 44 | "0", 45 | "0", 46 | "0", 47 | "0", 48 | "0", 49 | "0", 50 | "0", 51 | "0", 52 | "0", 53 | "0", 54 | "0", 55 | "0", 56 | "0", 57 | "0", 58 | "0", 59 | "0", 60 | "0", 61 | "0" 62 | ], 63 | "issuerClaimNonRevMtpAuxHi": "0", 64 | "issuerClaimNonRevMtpAuxHv": "0", 65 | "issuerClaimNonRevMtpNoAux": "1", 66 | "claimSchema": "180410020913331409885634153623124536270", 67 | "issuerClaimSignatureR8x": "1651985418874087649697147889073653461168250997226887249132054770010575868904", 68 | "issuerClaimSignatureR8y": "21186185889289266863036576968009990777000485497741800844819909873882380374550", 69 | "issuerClaimSignatureS": "1462737848034339569304412491966425713268123077483712855404323511126257598464", 70 | "issuerAuthClaim": [ 71 | "80551937543569765027552589160822318028", 72 | "0", 73 | "9582165609074695838007712438814613121302719752874385708394134542816240804696", 74 | "18271435592817415588213874506882839610978320325722319742324814767882756910515", 75 | "11203087622270641253", 76 | "0", 77 | "0", 78 | "0" 79 | ], 80 | "issuerAuthClaimMtp": [ 81 | "0", 82 | "0", 83 | "0", 84 | "0", 85 | "0", 86 | "0", 87 | "0", 88 | "0", 89 | "0", 90 | "0", 91 | "0", 92 | "0", 93 | "0", 94 | "0", 95 | "0", 96 | "0", 97 | "0", 98 | "0", 99 | "0", 100 | "0", 101 | "0", 102 | "0", 103 | "0", 104 | "0", 105 | "0", 106 | "0", 107 | "0", 108 | "0", 109 | "0", 110 | "0", 111 | "0", 112 | "0", 113 | "0", 114 | "0", 115 | "0", 116 | "0", 117 | "0", 118 | "0", 119 | "0", 120 | "0" 121 | ], 122 | "issuerAuthClaimNonRevMtp": [ 123 | "0", 124 | "0", 125 | "0", 126 | "0", 127 | "0", 128 | "0", 129 | "0", 130 | "0", 131 | "0", 132 | "0", 133 | "0", 134 | "0", 135 | "0", 136 | "0", 137 | "0", 138 | "0", 139 | "0", 140 | "0", 141 | "0", 142 | "0", 143 | "0", 144 | "0", 145 | "0", 146 | "0", 147 | "0", 148 | "0", 149 | "0", 150 | "0", 151 | "0", 152 | "0", 153 | "0", 154 | "0", 155 | "0", 156 | "0", 157 | "0", 158 | "0", 159 | "0", 160 | "0", 161 | "0", 162 | "0" 163 | ], 164 | "issuerAuthClaimNonRevMtpAuxHi": "0", 165 | "issuerAuthClaimNonRevMtpAuxHv": "0", 166 | "issuerAuthClaimNonRevMtpNoAux": "1", 167 | "issuerAuthClaimsTreeRoot": "10304430946970870697981400054531724100803206948489006715521525892274350097449", 168 | "issuerAuthRevTreeRoot": "0", 169 | "issuerAuthRootsTreeRoot": "0", 170 | "issuerAuthState": "20177832565449474772630743317224985532862797657496372535616634430055981993180", 171 | "isRevocationChecked": 1, 172 | "claimPathMtp": [ 173 | "0", 174 | "0", 175 | "0", 176 | "0", 177 | "0", 178 | "0", 179 | "0", 180 | "0", 181 | "0", 182 | "0", 183 | "0", 184 | "0", 185 | "0", 186 | "0", 187 | "0", 188 | "0", 189 | "0", 190 | "0", 191 | "0", 192 | "0", 193 | "0", 194 | "0", 195 | "0", 196 | "0", 197 | "0", 198 | "0", 199 | "0", 200 | "0", 201 | "0", 202 | "0", 203 | "0", 204 | "0" 205 | ], 206 | "claimPathMtpNoAux": "1", 207 | "claimPathMtpAuxHi": "0", 208 | "claimPathMtpAuxHv": "0", 209 | "claimPathKey": "0", 210 | "claimPathValue": "0", 211 | "operator": 0, 212 | "slotIndex": 2, 213 | "timestamp": 1642074362, 214 | "value": [ 215 | "0", 216 | "0", 217 | "0", 218 | "0", 219 | "0", 220 | "0", 221 | "0", 222 | "0", 223 | "0", 224 | "0", 225 | "0", 226 | "0", 227 | "0", 228 | "0", 229 | "0", 230 | "0", 231 | "0", 232 | "0", 233 | "0", 234 | "0", 235 | "0", 236 | "0", 237 | "0", 238 | "0", 239 | "0", 240 | "0", 241 | "0", 242 | "0", 243 | "0", 244 | "0", 245 | "0", 246 | "0", 247 | "0", 248 | "0", 249 | "0", 250 | "0", 251 | "0", 252 | "0", 253 | "0", 254 | "0", 255 | "0", 256 | "0", 257 | "0", 258 | "0", 259 | "0", 260 | "0", 261 | "0", 262 | "0", 263 | "0", 264 | "0", 265 | "0", 266 | "0", 267 | "0", 268 | "0", 269 | "0", 270 | "0", 271 | "0", 272 | "0", 273 | "0", 274 | "0", 275 | "0", 276 | "0", 277 | "0", 278 | "0" 279 | ], 280 | "authClaim": [ 281 | "80551937543569765027552589160822318028", 282 | "0", 283 | "17640206035128972995519606214765283372613874593503528180869261482403155458945", 284 | "20634138280259599560273310290025659992320584624461316485434108770067472477956", 285 | "15930428023331155902", 286 | "0", 287 | "0", 288 | "0" 289 | ], 290 | "authClaimIncMtp": [ 291 | "0", 292 | "0", 293 | "0", 294 | "0", 295 | "0", 296 | "0", 297 | "0", 298 | "0", 299 | "0", 300 | "0", 301 | "0", 302 | "0", 303 | "0", 304 | "0", 305 | "0", 306 | "0", 307 | "0", 308 | "0", 309 | "0", 310 | "0", 311 | "0", 312 | "0", 313 | "0", 314 | "0", 315 | "0", 316 | "0", 317 | "0", 318 | "0", 319 | "0", 320 | "0", 321 | "0", 322 | "0", 323 | "0", 324 | "0", 325 | "0", 326 | "0", 327 | "0", 328 | "0", 329 | "0", 330 | "0" 331 | ], 332 | "authClaimNonRevMtp": [ 333 | "0", 334 | "0", 335 | "0", 336 | "0", 337 | "0", 338 | "0", 339 | "0", 340 | "0", 341 | "0", 342 | "0", 343 | "0", 344 | "0", 345 | "0", 346 | "0", 347 | "0", 348 | "0", 349 | "0", 350 | "0", 351 | "0", 352 | "0", 353 | "0", 354 | "0", 355 | "0", 356 | "0", 357 | "0", 358 | "0", 359 | "0", 360 | "0", 361 | "0", 362 | "0", 363 | "0", 364 | "0", 365 | "0", 366 | "0", 367 | "0", 368 | "0", 369 | "0", 370 | "0", 371 | "0", 372 | "0" 373 | ], 374 | "authClaimNonRevMtpAuxHi": "0", 375 | "authClaimNonRevMtpAuxHv": "0", 376 | "authClaimNonRevMtpNoAux": "1", 377 | "challenge": "10", 378 | "challengeSignatureR8x": "2436614617352067078274240654647841101298221663194055411539273018411814965042", 379 | "challengeSignatureR8y": "18597752099468941062473075570139025288787892531282848931228194191266230422780", 380 | "challengeSignatureS": "1642466479083925938589665711747519202726798003514101885795868643287098549939", 381 | "userClaimsTreeRoot": "9860409408344985873118363460916733946840214387455464863344022463808838582364", 382 | "userRevTreeRoot": "0", 383 | "userRootsTreeRoot": "0", 384 | "userState": "1648710229725601204870171311149827592640182384459240511403224642152766848235", 385 | "gistRoot": "11098939821764568131087645431296528907277253709936443029379587475821759259406", 386 | "gistMtp": [ 387 | "0", 388 | "0", 389 | "0", 390 | "0", 391 | "0", 392 | "0", 393 | "0", 394 | "0", 395 | "0", 396 | "0", 397 | "0", 398 | "0", 399 | "0", 400 | "0", 401 | "0", 402 | "0", 403 | "0", 404 | "0", 405 | "0", 406 | "0", 407 | "0", 408 | "0", 409 | "0", 410 | "0", 411 | "0", 412 | "0", 413 | "0", 414 | "0", 415 | "0", 416 | "0", 417 | "0", 418 | "0", 419 | "0", 420 | "0", 421 | "0", 422 | "0", 423 | "0", 424 | "0", 425 | "0", 426 | "0", 427 | "0", 428 | "0", 429 | "0", 430 | "0", 431 | "0", 432 | "0", 433 | "0", 434 | "0", 435 | "0", 436 | "0", 437 | "0", 438 | "0", 439 | "0", 440 | "0", 441 | "0", 442 | "0", 443 | "0", 444 | "0", 445 | "0", 446 | "0", 447 | "0", 448 | "0", 449 | "0", 450 | "0" 451 | ], 452 | "gistMtpAuxHi": "27918766665310231445021466320959318414450284884582375163563581940319453185", 453 | "gistMtpAuxHv": "20177832565449474772630743317224985532862797657496372535616634430055981993180", 454 | "gistMtpNoAux": "0", 455 | "proofType": "1", 456 | "issuerClaimMtp": [ 457 | "0", 458 | "0", 459 | "0", 460 | "0", 461 | "0", 462 | "0", 463 | "0", 464 | "0", 465 | "0", 466 | "0", 467 | "0", 468 | "0", 469 | "0", 470 | "0", 471 | "0", 472 | "0", 473 | "0", 474 | "0", 475 | "0", 476 | "0", 477 | "0", 478 | "0", 479 | "0", 480 | "0", 481 | "0", 482 | "0", 483 | "0", 484 | "0", 485 | "0", 486 | "0", 487 | "0", 488 | "0", 489 | "0", 490 | "0", 491 | "0", 492 | "0", 493 | "0", 494 | "0", 495 | "0", 496 | "0" 497 | ], 498 | "valueArraySize": 0, 499 | "issuerClaimClaimsTreeRoot": "0", 500 | "issuerClaimRevTreeRoot": "0", 501 | "issuerClaimRootsTreeRoot": "0", 502 | "issuerClaimIdenState": "0", 503 | "linkNonce": "0", 504 | "verifierID": "21929109382993718606847853573861987353620810345503358891473103689157378049", 505 | "nullifierSessionID": "32", 506 | "isBJJAuthEnabled": "1" 507 | } 508 | -------------------------------------------------------------------------------- /testdata/sigV2OnChain_inputs.json: -------------------------------------------------------------------------------- 1 | {"requestID":"23","userGenesisID":"26109404700696283154998654512117952420503675471097392618762221546565140481","profileNonce":"0","claimSubjectProfileNonce":"0","issuerID":"27918766665310231445021466320959318414450284884582375163563581940319453185","issuerClaim":["3583233690122716044519380227940806650830","26109404700696283154998654512117952420503675471097392618762221546565140481","10","0","30803922965249841627828060161","0","0","0"],"issuerClaimNonRevClaimsTreeRoot":"10304430946970870697981400054531724100803206948489006715521525892274350097449","issuerClaimNonRevRevTreeRoot":"0","issuerClaimNonRevRootsTreeRoot":"0","issuerClaimNonRevState":"20177832565449474772630743317224985532862797657496372535616634430055981993180","issuerClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerClaimNonRevMtpAuxHi":"0","issuerClaimNonRevMtpAuxHv":"0","issuerClaimNonRevMtpNoAux":"1","claimSchema":"180410020913331409885634153623124536270","issuerClaimSignatureR8x":"1651985418874087649697147889073653461168250997226887249132054770010575868904","issuerClaimSignatureR8y":"21186185889289266863036576968009990777000485497741800844819909873882380374550","issuerClaimSignatureS":"1462737848034339569304412491966425713268123077483712855404323511126257598464","issuerAuthClaim":["80551937543569765027552589160822318028","0","9582165609074695838007712438814613121302719752874385708394134542816240804696","18271435592817415588213874506882839610978320325722319742324814767882756910515","11203087622270641253","0","0","0"],"issuerAuthClaimMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerAuthClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerAuthClaimNonRevMtpAuxHi":"0","issuerAuthClaimNonRevMtpAuxHv":"0","issuerAuthClaimNonRevMtpNoAux":"1","issuerAuthClaimsTreeRoot":"10304430946970870697981400054531724100803206948489006715521525892274350097449","issuerAuthRevTreeRoot":"0","issuerAuthRootsTreeRoot":"0","isRevocationChecked":1,"claimPathNotExists":1,"claimPathMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"claimPathMtpNoAux":"1","claimPathMtpAuxHi":"0","claimPathMtpAuxHv":"0","claimPathKey":"0","claimPathValue":"0","operator":1,"slotIndex":2,"timestamp":1642074362,"value":["10","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"authClaim":["80551937543569765027552589160822318028","0","17640206035128972995519606214765283372613874593503528180869261482403155458945","20634138280259599560273310290025659992320584624461316485434108770067472477956","15930428023331155902","0","0","0"],"authClaimIncMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"authClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"authClaimNonRevMtpAuxHi":"0","authClaimNonRevMtpAuxHv":"0","authClaimNonRevMtpNoAux":"1","challenge":"10","challengeSignatureR8x":"2436614617352067078274240654647841101298221663194055411539273018411814965042","challengeSignatureR8y":"18597752099468941062473075570139025288787892531282848931228194191266230422780","challengeSignatureS":"1642466479083925938589665711747519202726798003514101885795868643287098549939","userClaimsTreeRoot":"9860409408344985873118363460916733946840214387455464863344022463808838582364","userRevTreeRoot":"0","userRootsTreeRoot":"0","userState":"1648710229725601204870171311149827592640182384459240511403224642152766848235","gistRoot":"11098939821764568131087645431296528907277253709936443029379587475821759259406","gistMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"gistMtpAuxHi":"27918766665310231445021466320959318414450284884582375163563581940319453185","gistMtpAuxHv":"20177832565449474772630743317224985532862797657496372535616634430055981993180","gistMtpNoAux":"0"} -------------------------------------------------------------------------------- /testdata/sigV2_inputs.json: -------------------------------------------------------------------------------- 1 | {"requestID":"23","userGenesisID":"26109404700696283154998654512117952420503675471097392618762221546565140481","profileNonce":"0","claimSubjectProfileNonce":"0","issuerID":"27918766665310231445021466320959318414450284884582375163563581940319453185","issuerClaim":["3583233690122716044519380227940806650830","26109404700696283154998654512117952420503675471097392618762221546565140481","10","0","30803922965249841627828060161","0","0","0"],"issuerClaimNonRevClaimsTreeRoot":"10304430946970870697981400054531724100803206948489006715521525892274350097449","issuerClaimNonRevRevTreeRoot":"0","issuerClaimNonRevRootsTreeRoot":"0","issuerClaimNonRevState":"20177832565449474772630743317224985532862797657496372535616634430055981993180","issuerClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerClaimNonRevMtpAuxHi":"0","issuerClaimNonRevMtpAuxHv":"0","issuerClaimNonRevMtpNoAux":"1","claimSchema":"180410020913331409885634153623124536270","issuerClaimSignatureR8x":"1651985418874087649697147889073653461168250997226887249132054770010575868904","issuerClaimSignatureR8y":"21186185889289266863036576968009990777000485497741800844819909873882380374550","issuerClaimSignatureS":"1462737848034339569304412491966425713268123077483712855404323511126257598464","issuerAuthClaim":["80551937543569765027552589160822318028","0","9582165609074695838007712438814613121302719752874385708394134542816240804696","18271435592817415588213874506882839610978320325722319742324814767882756910515","11203087622270641253","0","0","0"],"issuerAuthClaimMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerAuthClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerAuthClaimNonRevMtpAuxHi":"0","issuerAuthClaimNonRevMtpAuxHv":"0","issuerAuthClaimNonRevMtpNoAux":"1","issuerAuthClaimsTreeRoot":"10304430946970870697981400054531724100803206948489006715521525892274350097449","issuerAuthRevTreeRoot":"0","issuerAuthRootsTreeRoot":"0","isRevocationChecked":1,"claimPathNotExists":1,"claimPathMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"claimPathMtpNoAux":"1","claimPathMtpAuxHi":"0","claimPathMtpAuxHv":"0","claimPathKey":"0","claimPathValue":"0","operator":1,"slotIndex":2,"timestamp":1642074362,"value":["10","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"]} -------------------------------------------------------------------------------- /testdata/sybilMTP_inputs.json: -------------------------------------------------------------------------------- 1 | {"issuerClaim":["3583233690122716044519380227940806650830","26109404700696283154998654512117952420503675471097392618762221546565140481","10","0","30803922965249841627828060161","0","0","0"],"issuerClaimMtp":["0","10304430946970870697981400054531724100803206948489006715521525892274350097449","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerClaimClaimsRoot":"21551875744466996287712204148827400686061292275961899951444219768723484280073","issuerClaimRevRoot":"0","issuerClaimRootsRoot":"0","issuerClaimIdenState":"19157496396839393206871475267813888069926627705277243727237933406423274512449","issuerClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerClaimNonRevMtpNoAux":"1","issuerClaimNonRevMtpAuxHi":"0","issuerClaimNonRevMtpAuxHv":"0","issuerClaimNonRevClaimsRoot":"21551875744466996287712204148827400686061292275961899951444219768723484280073","issuerClaimNonRevRevRoot":"0","issuerClaimNonRevRootsRoot":"0","issuerClaimNonRevState":"19157496396839393206871475267813888069926627705277243727237933406423274512449","claimSchema":"180410020913331409885634153623124536270","stateCommitmentClaim":["262057681346829900854325169563380898778","0","0","0","145645","0","5555","0"],"stateCommitmentClaimMtp":["9860409408344985873118363460916733946840214387455464863344022463808838582364","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"stateCommitmentClaimClaimsRoot":"7703532505400389400255604879393247721138775472553428416949009325450288027762","stateCommitmentClaimRevRoot":"0","stateCommitmentClaimRootsRoot":"0","stateCommitmentClaimIdenState":"16226205761009011522208444155288863421486389282118677329074232956401954436576","gistRoot":"12237249731937050748239754514110031073443409881058925518681107238397055045148","gistMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"gistMtpAuxHi":"0","gistMtpAuxHv":"0","gistMtpNoAux":"0","crs":"249532670194878832589534456260980839355904887861263878269048090946773573111","userGenesisID":"26109404700696283154998654512117952420503675471097392618762221546565140481","profileNonce":"0","claimSubjectProfileNonce":"0","requestID":123,"issuerID":"27918766665310231445021466320959318414450284884582375163563581940319453185","timestamp":1642074362} -------------------------------------------------------------------------------- /testdata/sybilSig_inputs.json: -------------------------------------------------------------------------------- 1 | {"issuerAuthClaim":["80551937543569765027552589160822318028","0","9582165609074695838007712438814613121302719752874385708394134542816240804696","18271435592817415588213874506882839610978320325722319742324814767882756910515","11203087622270641253","0","0","0"],"issuerAuthClaimMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerAuthClaimsRoot":"10304430946970870697981400054531724100803206948489006715521525892274350097449","issuerAuthRevRoot":"0","issuerAuthRootsRoot":"0","issuerAuthClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerAuthClaimNonRevMtpAuxHi":"0","issuerAuthClaimNonRevMtpAuxHv":"0","issuerAuthClaimNonRevMtpNoAux":"1","issuerClaim":["3583233690122716044519380227940806650830","26109404700696283154998654512117952420503675471097392618762221546565140481","10","0","30803922965249841627828060161","0","0","0"],"issuerClaimNonRevClaimsRoot":"10304430946970870697981400054531724100803206948489006715521525892274350097449","issuerClaimNonRevRevRoot":"0","issuerClaimNonRevRootsRoot":"0","issuerClaimNonRevState":"20177832565449474772630743317224985532862797657496372535616634430055981993180","issuerClaimNonRevMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"issuerClaimNonRevMtpAuxHi":"0","issuerClaimNonRevMtpAuxHv":"0","issuerClaimNonRevMtpNoAux":"1","issuerClaimSignatureR8x":"1651985418874087649697147889073653461168250997226887249132054770010575868904","issuerClaimSignatureR8y":"21186185889289266863036576968009990777000485497741800844819909873882380374550","issuerClaimSignatureS":"1462737848034339569304412491966425713268123077483712855404323511126257598464","claimSchema":"180410020913331409885634153623124536270","stateCommitmentClaim":["262057681346829900854325169563380898778","0","0","0","145645","0","5555","0"],"stateCommitmentClaimMtp":["9860409408344985873118363460916733946840214387455464863344022463808838582364","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"stateCommitmentClaimClaimsRoot":"7703532505400389400255604879393247721138775472553428416949009325450288027762","stateCommitmentClaimRevRoot":"0","stateCommitmentClaimRootsRoot":"0","stateCommitmentClaimIdenState":"16226205761009011522208444155288863421486389282118677329074232956401954436576","gistRoot":"12237249731937050748239754514110031073443409881058925518681107238397055045148","gistMtp":["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"],"gistMtpAuxHi":"0","gistMtpAuxHv":"0","gistMtpNoAux":"0","crs":"249532670194878832589534456260980839355904887861263878269048090946773573111","userGenesisID":"26109404700696283154998654512117952420503675471097392618762221546565140481","profileNonce":"0","claimSubjectProfileNonce":"0","requestID":123,"issuerID":"27918766665310231445021466320959318414450284884582375163563581940319453185","timestamp":1642074362} -------------------------------------------------------------------------------- /testing/claim.go: -------------------------------------------------------------------------------- 1 | package testing 2 | 3 | import ( 4 | "encoding/hex" 5 | "math/big" 6 | "testing" 7 | "time" 8 | 9 | core "github.com/iden3/go-iden3-core/v2" 10 | ) 11 | 12 | func DefaultUserClaim(t testing.TB, subject core.ID) *core.Claim { 13 | dataSlotA, _ := core.NewElemBytesFromInt(big.NewInt(10)) 14 | nonce := 1 15 | var schemaHash core.SchemaHash 16 | schemaBytes, err := hex.DecodeString("ce6bb12c96bfd1544c02c289c6b4b987") 17 | if err != nil { 18 | t.Fatal(err) 19 | } 20 | copy(schemaHash[:], schemaBytes) 21 | 22 | claim, err := core.NewClaim( 23 | schemaHash, 24 | core.WithIndexID(subject), 25 | core.WithIndexData(dataSlotA, core.ElemBytes{}), 26 | core.WithExpirationDate(time.Unix(1669884010, 0)), //Thu Dec 01 2022 08:40:10 GMT+0000 27 | core.WithRevocationNonce(uint64(nonce))) 28 | if err != nil { 29 | t.Fatal(err) 30 | } 31 | 32 | return claim 33 | 34 | } 35 | 36 | func UserStateCommitmentClaim(t testing.TB, secret *big.Int) *core.Claim { 37 | dataSlotA, err := core.NewElemBytesFromInt(secret) 38 | if err != nil { 39 | t.Fatalf("failed get NewElemBytesFromInt %v", err) 40 | } 41 | 42 | nonce := 145645 43 | var schemaHash core.SchemaHash 44 | schemaBytes, err := hex.DecodeString("da5b2efc8386250550e458a33b7926c5") 45 | if err != nil { 46 | t.Fatalf("failed decode schema hash %v", err) 47 | } 48 | copy(schemaHash[:], schemaBytes) 49 | 50 | claim, err := core.NewClaim( 51 | schemaHash, 52 | core.WithValueData(dataSlotA, core.ElemBytes{}), 53 | core.WithRevocationNonce(uint64(nonce))) 54 | if err != nil { 55 | t.Fatalf("failed create new claim %v", err) 56 | } 57 | 58 | return claim 59 | } 60 | -------------------------------------------------------------------------------- /testing/utils.go: -------------------------------------------------------------------------------- 1 | package testing 2 | 3 | import ( 4 | "encoding/hex" 5 | "io" 6 | "math/big" 7 | "os" 8 | "testing" 9 | 10 | core "github.com/iden3/go-iden3-core/v2" 11 | "github.com/iden3/go-iden3-crypto/babyjub" 12 | "github.com/iden3/go-merkletree-sql/v2" 13 | ) 14 | 15 | func TestData(t *testing.T, fileName string, data string, generate bool) string { 16 | t.Helper() 17 | path := "testdata/" + fileName + ".json" 18 | 19 | f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0755) 20 | if err != nil { 21 | t.Fatalf("Error open a file %s: %s", path, err) 22 | } 23 | 24 | defer func() { 25 | err := f.Close() 26 | if err != nil { 27 | t.Error(err) 28 | } 29 | }() 30 | 31 | if generate { 32 | err = f.Truncate(0) 33 | if err != nil { 34 | t.Fatalf("Error truncate file %s: %s", path, err) 35 | } 36 | _, err = f.Seek(0, 0) 37 | if err != nil { 38 | t.Fatalf("Error seek file %s: %s", path, err) 39 | } 40 | _, err := f.WriteString(data) 41 | if err != nil { 42 | t.Fatalf("Error writing to file %s: %s", path, err) 43 | } 44 | 45 | return data 46 | } 47 | 48 | fileBytes, err := io.ReadAll(f) 49 | if err != nil { 50 | t.Fatalf("Error read file %s: %s", path, err) 51 | } 52 | return string(fileBytes) 53 | } 54 | 55 | // SignPoseidon signs prepared data ( value in field Q) 56 | func SignPoseidon(pk *babyjub.PrivateKey, data []byte) ([]byte, error) { 57 | 58 | if pk == nil { 59 | panic("pk is nil") 60 | } 61 | 62 | message := big.NewInt(0).SetBytes(data) 63 | 64 | signature := pk.SignPoseidon(message) 65 | 66 | compressed := signature.Compress() 67 | 68 | return compressed[:], nil 69 | } 70 | 71 | func SignBBJJ(key *babyjub.PrivateKey, sigInput []byte) (*babyjub.Signature, error) { 72 | signature, err := SignPoseidon(key, sigInput) 73 | if err != nil { 74 | return nil, err 75 | } 76 | 77 | var sig [64]byte 78 | copy(sig[:], signature) 79 | 80 | return new(babyjub.Signature).Decompress(sig) 81 | } 82 | 83 | type NodeAuxValue struct { 84 | Key *merkletree.Hash 85 | Value *merkletree.Hash 86 | NoAux string 87 | } 88 | 89 | func getNodeAuxValue(p *merkletree.Proof) NodeAuxValue { 90 | 91 | // proof of inclusion 92 | if p.Existence { 93 | return NodeAuxValue{ 94 | Key: &merkletree.HashZero, 95 | Value: &merkletree.HashZero, 96 | NoAux: "0", 97 | } 98 | } 99 | 100 | // proof of non-inclusion (NodeAux exists) 101 | if p.NodeAux != nil && p.NodeAux.Value != nil && p.NodeAux.Key != nil { 102 | return NodeAuxValue{ 103 | Key: p.NodeAux.Key, 104 | Value: p.NodeAux.Value, 105 | NoAux: "0", 106 | } 107 | } 108 | // proof of non-inclusion (NodeAux does not exist) 109 | return NodeAuxValue{ 110 | Key: &merkletree.HashZero, 111 | Value: &merkletree.HashZero, 112 | NoAux: "1", 113 | } 114 | } 115 | 116 | func PrepareProof(proof *merkletree.Proof) ([]string, NodeAuxValue) { 117 | return PrepareSiblingsStr(proof.AllSiblings(), 32), getNodeAuxValue(proof) 118 | } 119 | 120 | func ExtractPubXY(privKHex string) (key *babyjub.PrivateKey, x, y *big.Int) { 121 | // Extract pubKey 122 | var k babyjub.PrivateKey 123 | if _, err := hex.Decode(k[:], []byte(privKHex)); err != nil { 124 | panic(err) 125 | } 126 | pk := k.Public() 127 | return &k, pk.X, pk.Y 128 | } 129 | 130 | func PrepareSiblingsStr(siblings []*merkletree.Hash, levels int) []string { 131 | // siblings := mtproof.AllSiblings() 132 | // Add the rest of empty levels to the siblings 133 | for i := len(siblings); i < levels; i++ { 134 | siblings = append(siblings, &merkletree.HashZero) 135 | } 136 | return HashToStr(siblings) 137 | } 138 | 139 | func PrepareStrArray(siblings []string, levels int) []string { 140 | // Add the rest of empty levels to the array 141 | for i := len(siblings); i < levels; i++ { 142 | siblings = append(siblings, "0") 143 | } 144 | return siblings 145 | } 146 | 147 | func HashToStr(siblings []*merkletree.Hash) []string { 148 | siblingsStr := make([]string, len(siblings)) 149 | for i, sibling := range siblings { 150 | siblingsStr[i] = sibling.BigInt().String() 151 | } 152 | return siblingsStr 153 | } 154 | 155 | func IDFromState(state *big.Int) (*core.ID, error) { 156 | typ, err := core.BuildDIDType(core.DIDMethodIden3, core.ReadOnly, core.NoNetwork) 157 | if err != nil { 158 | return nil, err 159 | } 160 | // create new identity 161 | return core.NewIDFromIdenState(typ, state) 162 | } 163 | 164 | func IDFromStr(t testing.TB, idStr string) *core.ID { 165 | t.Helper() 166 | strID, b := new(big.Int).SetString(idStr, 10) 167 | if !b { 168 | t.Fatalf("can not convert {%s} to ID", strID) 169 | } 170 | id, err := core.IDFromInt(strID) 171 | if err != nil { 172 | t.Fatalf("can not convert {%s} to ID: %v", strID, err) 173 | } 174 | return &id 175 | } 176 | 177 | func MTHashFromStr(t testing.TB, hashStr string) *merkletree.Hash { 178 | t.Helper() 179 | hash, err := merkletree.NewHashFromString(hashStr) 180 | if err != nil { 181 | t.Fatal(err) 182 | } 183 | return hash 184 | } 185 | 186 | func CoreSchemaFromStr(t testing.TB, schemaIntStr string) core.SchemaHash { 187 | t.Helper() 188 | schemaInt, ok := big.NewInt(0).SetString(schemaIntStr, 10) 189 | if !ok { 190 | t.Fatalf("Error parsing schemaIntStr %s", schemaIntStr) 191 | } 192 | return core.NewSchemaHashFromInt(schemaInt) 193 | } 194 | 195 | func PrepareIntArray(arr []*big.Int, length int) []*big.Int { 196 | // Add the rest of empty levels to the array 197 | for i := len(arr); i < length; i++ { 198 | arr = append(arr, big.NewInt(0)) 199 | } 200 | return arr 201 | } 202 | -------------------------------------------------------------------------------- /types.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | core "github.com/iden3/go-iden3-core/v2" 5 | "github.com/iden3/go-iden3-crypto/babyjub" 6 | "github.com/iden3/go-merkletree-sql/v2" 7 | ) 8 | 9 | type ClaimWithSigAndMTPProof struct { 10 | IssuerID *core.ID `json:"issuerID"` 11 | Claim *core.Claim `json:"claim"` 12 | NonRevProof MTProof `json:"nonRevProof"` // Claim non revocation proof 13 | SignatureProof *BJJSignatureProof `json:"signatureProof"` 14 | IncProof *MTProof `json:"incProof"` // proof of inclusion `Claim` to the issuer claims tree 15 | } 16 | 17 | type ClaimWithSigProof struct { 18 | IssuerID *core.ID `json:"issuerID"` 19 | Claim *core.Claim `json:"claim"` 20 | NonRevProof MTProof `json:"nonRevProof"` // Claim non revocation proof 21 | SignatureProof BJJSignatureProof `json:"signatureProof"` 22 | } 23 | 24 | type ClaimWithMTPProof struct { 25 | IssuerID *core.ID `json:"issuerId"` 26 | Claim *core.Claim `json:"claim"` 27 | IncProof MTProof `json:"incProof"` // proof of inclusion `Claim` to the issuer claims tree 28 | NonRevProof MTProof `json:"nonRevProof"` // proof of non revocation of the `Claim` in the issuer revocation tree 29 | } 30 | 31 | // BJJSignatureProof is a proof of issuer AuthClaim signature over a claim 32 | type BJJSignatureProof struct { 33 | // Signature Signing the claim with the private key of the issuer associated with the issuerAuthClaim 34 | Signature *babyjub.Signature `json:"signature"` 35 | IssuerAuthClaim *core.Claim `json:"issuerAuthClaim"` // issuer AuthClaim 36 | // IssuerAuthIncProof proof of inclusion of issuer AuthClaim to 37 | // the issuer claims tree 38 | IssuerAuthIncProof MTProof `json:"issuerAuthIncProof"` 39 | // IssuerAuthNonRevProof proof of non revocation of issuer 40 | // AuthClaim in the issuer the latest state 41 | IssuerAuthNonRevProof MTProof `json:"issuerAuthNonRevProof"` 42 | } 43 | 44 | type MTProof struct { 45 | Proof *merkletree.Proof `json:"proof"` // Proof of inclusion to the Merkle Tree 46 | TreeState TreeState `json:"treeState"` // Identity state 47 | } 48 | 49 | // TreeState represents the identity state 50 | type TreeState struct { 51 | State *merkletree.Hash `json:"state"` // identity state 52 | ClaimsRoot *merkletree.Hash `json:"claimsRoot"` // claims tree root 53 | RevocationRoot *merkletree.Hash `json:"revocationRoot"` // revocation tree root 54 | RootOfRoots *merkletree.Hash `json:"rootOfRoots"` // root of roots tree root 55 | } 56 | 57 | // GISTProof global identity state tree proof represents the state of the global identities tree published on the 58 | // blockchain 59 | type GISTProof struct { 60 | Root *merkletree.Hash `json:"root"` // GIST root 61 | Proof *merkletree.Proof `json:"proof"` // proof of inclusion or non inclusion of the identity to the GIST 62 | } 63 | -------------------------------------------------------------------------------- /utils.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | "reflect" 7 | 8 | core "github.com/iden3/go-iden3-core/v2" 9 | "github.com/iden3/go-iden3-crypto/poseidon" 10 | "github.com/iden3/go-merkletree-sql/v2" 11 | "github.com/pkg/errors" 12 | ) 13 | 14 | // PrepareSiblings prepare siblings for zk zk 15 | func PrepareSiblings(siblings []*merkletree.Hash, levels int) []*big.Int { 16 | // siblings := mtproof.AllSiblings() 17 | // Add the rest of empty levels to the siblings 18 | for i := len(siblings); i < levels; i++ { 19 | siblings = append(siblings, &merkletree.HashZero) 20 | } 21 | siblingsBigInt := make([]*big.Int, len(siblings)) 22 | for i, sibling := range siblings { 23 | siblingsBigInt[i] = sibling.BigInt() 24 | } 25 | return siblingsBigInt 26 | } 27 | 28 | func PrepareSiblingsStr(siblings []*merkletree.Hash, levels int) []string { 29 | // siblings := mtproof.AllSiblings() 30 | // Add the rest of empty levels to the siblings 31 | for i := len(siblings); i < levels; i++ { 32 | siblings = append(siblings, &merkletree.HashZero) 33 | } 34 | return HashToStr(siblings) 35 | } 36 | 37 | // CircomSiblings returns the full siblings compatible with circom 38 | func CircomSiblings(proof *merkletree.Proof, levels int) []*merkletree.Hash { 39 | siblings := proof.AllSiblings() 40 | // Add the rest of empty levels to the siblings 41 | for i := len(siblings); i < levels; i++ { 42 | siblings = append(siblings, &merkletree.HashZero) 43 | } 44 | return siblings 45 | } 46 | 47 | func HashToStr(siblings []*merkletree.Hash) []string { 48 | siblingsStr := make([]string, len(siblings)) 49 | for i, sibling := range siblings { 50 | siblingsStr[i] = sibling.BigInt().String() 51 | } 52 | return siblingsStr 53 | } 54 | 55 | // PrepareCircuitArrayValues padding values to size. Validate array size and throw an exception if array is bigger 56 | // than size 57 | // if array is bigger circuit cannot compile because number of inputs does not match 58 | func PrepareCircuitArrayValues(arr []*big.Int, size int) ([]*big.Int, error) { 59 | if len(arr) > size { 60 | return nil, errors.Errorf("array size {%d} is bigger max expected size {%d}", 61 | len(arr), size) 62 | } 63 | 64 | // Add the empty values 65 | for i := len(arr); i < size; i++ { 66 | arr = append(arr, new(big.Int)) 67 | } 68 | 69 | return arr, nil 70 | } 71 | 72 | func bigIntArrayToStringArray(array []*big.Int) []string { 73 | res := make([]string, 0) 74 | for i := range array { 75 | res = append(res, array[i].String()) 76 | } 77 | return res 78 | } 79 | 80 | type NodeAuxValue struct { 81 | key *merkletree.Hash 82 | value *merkletree.Hash 83 | noAux string 84 | } 85 | 86 | func GetNodeAuxValue(p *merkletree.Proof) NodeAuxValue { 87 | 88 | // proof of inclusion 89 | if p.Existence { 90 | return NodeAuxValue{ 91 | key: &merkletree.HashZero, 92 | value: &merkletree.HashZero, 93 | noAux: "0", 94 | } 95 | } 96 | 97 | // proof of non-inclusion (NodeAux exists) 98 | if p.NodeAux != nil && p.NodeAux.Value != nil && p.NodeAux.Key != nil { 99 | return NodeAuxValue{ 100 | key: p.NodeAux.Key, 101 | value: p.NodeAux.Value, 102 | noAux: "0", 103 | } 104 | } 105 | // proof of non-inclusion (NodeAux does not exist) 106 | return NodeAuxValue{ 107 | key: &merkletree.HashZero, 108 | value: &merkletree.HashZero, 109 | noAux: "1", 110 | } 111 | } 112 | 113 | func idFromIntStr(s string) (*core.ID, error) { 114 | strID, b := new(big.Int).SetString(s, 10) 115 | if !b { 116 | return nil, fmt.Errorf("can not convert {%s} to ID", s) 117 | } 118 | id, err := core.IDFromInt(strID) 119 | if err != nil { 120 | return nil, err 121 | } 122 | 123 | return &id, nil 124 | } 125 | 126 | func toMap(in interface{}) map[string]interface{} { 127 | out := make(map[string]interface{}) 128 | 129 | value := reflect.ValueOf(in) 130 | if value.Kind() == reflect.Ptr { 131 | value = value.Elem() 132 | } 133 | 134 | typ := value.Type() 135 | for i := 0; i < value.NumField(); i++ { 136 | fi := typ.Field(i) 137 | if jsonTag := fi.Tag.Get("json"); jsonTag != "" { 138 | out[jsonTag] = value.Field(i).Interface() 139 | } 140 | } 141 | return out 142 | } 143 | 144 | func existenceToInt(b bool) int { 145 | if b { 146 | return 0 147 | } 148 | return 1 149 | } 150 | 151 | // BatchSize defined by poseidon hash implementation in Solidity 152 | const BatchSize = 5 153 | 154 | // PoseidonHashValue returns the solidity and circom implementation of poseidon hash 155 | func PoseidonHashValue(values []*big.Int) (*big.Int, error) { 156 | 157 | if values == nil { 158 | return nil, fmt.Errorf("values not provided") 159 | } 160 | 161 | if len(values) == 0 { 162 | return nil, fmt.Errorf("empty values") 163 | } 164 | 165 | iterationCount := 0 166 | var err error 167 | getValueByIndex := func(arr []*big.Int, idx, length int) *big.Int { 168 | if idx < length { 169 | return arr[idx] 170 | } 171 | return big.NewInt(0) 172 | } 173 | l := len(values) 174 | hashFnBatchSize := 6 175 | // first iteration to get the first hash (6 elements) 176 | fullHash, err := poseidon.Hash([]*big.Int{ 177 | getValueByIndex(values, 0, l), 178 | getValueByIndex(values, 1, l), 179 | getValueByIndex(values, 2, l), 180 | getValueByIndex(values, 3, l), 181 | getValueByIndex(values, 4, l), 182 | getValueByIndex(values, 5, l), 183 | }) 184 | 185 | restLength := l - hashFnBatchSize 186 | if restLength > BatchSize { 187 | r := restLength % BatchSize 188 | diff := 0 189 | if r != 0 { 190 | diff = BatchSize - r 191 | } 192 | iterationCount = (restLength + diff) / BatchSize 193 | } 194 | 195 | if err != nil { 196 | return nil, err 197 | } 198 | 199 | for i := 0; i < iterationCount; i++ { 200 | elemIdx := i*BatchSize + hashFnBatchSize 201 | fullHash, err = poseidon.Hash([]*big.Int{ 202 | fullHash, 203 | getValueByIndex(values, elemIdx, l), 204 | getValueByIndex(values, elemIdx+1, l), 205 | getValueByIndex(values, elemIdx+2, l), 206 | getValueByIndex(values, elemIdx+3, l), 207 | getValueByIndex(values, elemIdx+4, l), 208 | }) 209 | if err != nil { 210 | return nil, err 211 | } 212 | } 213 | return fullHash, nil 214 | } 215 | 216 | func contains(s []int, e int) bool { 217 | for _, a := range s { 218 | if a == e { 219 | return true 220 | } 221 | } 222 | return false 223 | } 224 | -------------------------------------------------------------------------------- /utils_test.go: -------------------------------------------------------------------------------- 1 | package circuits 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func TestPrepareCircuitArrayValues(t *testing.T) { 12 | 13 | arr := []*big.Int{new(big.Int).SetInt64(1), new(big.Int).SetInt64(2)} 14 | 15 | arr, err := PrepareCircuitArrayValues(arr, 5) 16 | 17 | require.NoError(t, err) 18 | 19 | exp := []*big.Int{new(big.Int).SetInt64(1), new(big.Int).SetInt64(2), new(big.Int), new(big.Int), new(big.Int)} 20 | require.EqualValues(t, exp, arr) 21 | 22 | } 23 | 24 | func TestPrepareCircuitArrayValuesErr(t *testing.T) { 25 | 26 | arr := []*big.Int{new(big.Int).SetInt64(1), new(big.Int).SetInt64(2)} 27 | 28 | _, err := PrepareCircuitArrayValues(arr, 1) 29 | 30 | require.Errorf(t, err, "array size 2 is bigger max expected size 1") 31 | } 32 | 33 | func Test_existenceToInt(t *testing.T) { 34 | require.True(t, existenceToInt(true) == 0) 35 | require.True(t, existenceToInt(false) == 1) 36 | } 37 | 38 | func Test_PoseidonValueHash(t *testing.T) { 39 | 40 | getBigintArray := func(l int, f func(idx int) int) []*big.Int { 41 | result := make([]*big.Int, l) 42 | for i := 0; i < l; i++ { 43 | result[i] = big.NewInt(int64(f(i))) 44 | } 45 | return result 46 | } 47 | 48 | testCases := []struct { 49 | name string 50 | input []*big.Int 51 | expected string 52 | }{ 53 | { 54 | name: "PoseidonValueHash all zeros", 55 | input: getBigintArray(64, func(idx int) int { 56 | return 0 57 | }), 58 | expected: "7368935780301629035733097554153370898490964345621267223639562510928947240459", 59 | }, 60 | { 61 | name: "PoseidonValueHash 63 idx + 1", 62 | input: getBigintArray(63, func(idx int) int { 63 | return idx + 1 64 | }), 65 | expected: "3027148895471770401984833121350831002277377476084832804937751928355120074994", 66 | }, 67 | { 68 | name: "PoseidonValueHash 60 items", 69 | input: getBigintArray(60, func(idx int) int { 70 | return 60 - idx 71 | }), 72 | expected: "13254546416358473313457812414193018870743005197521155619424967381510427667259", 73 | }, 74 | { 75 | name: "PoseidonValueHash 5 vals", 76 | input: getBigintArray(5, func(idx int) int { 77 | return idx + 1 78 | }), 79 | expected: "6186895146109816025093019628248576250523388957868658785525378722128520330607", 80 | }, 81 | { 82 | name: "PoseidonValueHash 1 value", 83 | input: getBigintArray(1, func(idx int) int { 84 | return 0 85 | }), 86 | expected: "14408838593220040598588012778523101864903887657864399481915450526643617223637", 87 | }, 88 | { 89 | name: "PoseidonValueHash 6 vals", 90 | input: getBigintArray(6, func(idx int) int { 91 | return idx + 1 92 | }), 93 | expected: "20400040500897583745843009878988256314335038853985262692600694741116813247201", 94 | }, 95 | { 96 | name: "PoseidonValueHash 16 vals", 97 | input: getBigintArray(16, func(idx int) int { 98 | return idx + 1 99 | }), 100 | expected: "5605330091169856132381694679994923791994681609858984566508182442210285386845", 101 | }, 102 | } 103 | 104 | for _, tc := range testCases { 105 | t.Run(tc.name, func(t *testing.T) { 106 | poseidonValueHash, err := PoseidonHashValue(tc.input) 107 | require.NoError(t, err) 108 | fmt.Println("PoseidonValueHash:", poseidonValueHash.String()) 109 | require.Equal(t, tc.expected, poseidonValueHash.String()) 110 | }) 111 | } 112 | } 113 | --------------------------------------------------------------------------------