diff --git a/auth.go b/auth.go index 7f926d7..e81df67 100644 --- a/auth.go +++ b/auth.go @@ -20,6 +20,7 @@ import ( "github.com/iden3/go-iden3-auth/v2/proofs" "github.com/iden3/go-iden3-auth/v2/pubsignals" "github.com/iden3/go-iden3-auth/v2/state" + "github.com/iden3/go-iden3-core/v2/w3c" "github.com/iden3/go-jwz/v2" schemaloaders "github.com/iden3/go-schema-processor/v2/loaders" "github.com/iden3/go-schema-processor/v2/merklize" @@ -321,6 +322,10 @@ func (v *Verifier) VerifyAuthResponse( return errors.Errorf("message for request id %v was not presented in the response", request.ID) } + if request.From != response.To { + return errors.Errorf("sender of the request is not a target of response - expected %s, given %s", request.From, response.To) + } + for _, proofRequest := range request.Body.Scope { proofResponse := findProofByRequestID(response.Body.Scope, proofRequest.ID) if proofResponse == nil { @@ -370,7 +375,16 @@ func (v *Verifier) VerifyAuthResponse( rawMessage = nil } - err = cv.VerifyQuery(ctx, query, v.documentLoader, rawMessage, opts...) + if proofRequest.Params == nil { + proofRequest.Params = make(map[string]interface{}) + } + verifierDID, err := w3c.ParseDID(request.From) // TODO: this is assuming that response.TO is always DID. + if err != nil { + return err + } + proofRequest.Params[pubsignals.ParamNameVerifierDID] = verifierDID + + err = cv.VerifyQuery(ctx, query, v.documentLoader, rawMessage, proofRequest.Params, opts...) if err != nil { return err } @@ -379,6 +393,7 @@ func (v *Verifier) VerifyAuthResponse( if err != nil { return err } + } return nil diff --git a/auth_test.go b/auth_test.go index d41fe0a..faa856c 100644 --- a/auth_test.go +++ b/auth_test.go @@ -424,7 +424,7 @@ func TestVerifier_VerifyJWZ(t *testing.T) { func TestVerifier_FullVerify(t *testing.T) { // request - verifierID := "did:polygonid:polygon:mumbai:2qEevY9VnKdNsVDdXRv3qSLHRqoMGMRRdE5Gmc6iA7" + verifierID := "did:polygonid:polygon:mumbai:2qJ689kpoJxcSzB5sAFJtPsSBSrHF5dq722BHMqURL" callbackURL := "https://test.com/callback" reason := "age verification" @@ -487,7 +487,7 @@ func TestVerifier_FullVerify_JWS(t *testing.T) { "type": "KYCAgeCredential", } request.Body.Scope = append(request.Body.Scope, sigReq) - request.From = "did:iden3:polygon:mumbai:x4jcHP4XHTK3vX58AHZPyHE8kYjneyE6FZRfz7K29" + request.From = "did:polygonid:polygon:mumbai:2qLPqvayNQz9TA2r5VPxUugoF18teGU583zJ859wfy" request.To = "did:polygonid:polygon:mumbai:2qEevY9VnKdNsVDdXRv3qSLHRqoMGMRRdE5Gmc6iA7" token := `eyJhbGciOiJFUzI1NkstUiIsImtpZCI6ImRpZDpwa2g6cG9seToweDcxNDFFNGQyMEY3NjQ0REM4YzBBZENBOGE1MjBFQzgzQzZjQUJENjUjUmVjb3ZlcnkyMDIwIiwidHlwIjoiYXBwbGljYXRpb24vaWRlbjNjb21tLXNpZ25lZC1qc29uIn0.eyJpZCI6IjJjOGQ5NzQ3LTQ0MTAtNGU5My1iZjg0LTRlYTNjZmY4MmY0MCIsInR5cCI6ImFwcGxpY2F0aW9uL2lkZW4zY29tbS1zaWduZWQtanNvbiIsInR5cGUiOiJodHRwczovL2lkZW4zLWNvbW11bmljYXRpb24uaW8vYXV0aG9yaXphdGlvbi8xLjAvcmVzcG9uc2UiLCJ0aGlkIjoiN2YzOGExOTMtMDkxOC00YTQ4LTlmYWMtMzZhZGZkYjhiNTQyIiwiYm9keSI6eyJzY29wZSI6W3siaWQiOjEsImNpcmN1aXRJZCI6ImNyZWRlbnRpYWxBdG9taWNRdWVyeVNpZ1YyIiwicHJvb2YiOnsicGlfYSI6WyIxMzI3Njk4Nzc5MjQ5MjM0OTA2MDcxMDc3NTEyOTUxMjYxNzY1NjMzODcxMDkxMzE3NDA0NzE0NTcyMDY4Mjk4NzU0MzUwNjY3NDY0IiwiMjA1NDcyOTI1MzQ0MDgxNzA4NDQwODc3MzY2MDQ0OTYyNjQ3MzI2NjUxNDkxMDEzMzMxNzk3NTg5NTAwMjM0NTgwMjA1Njg5NzMzNTYiLCIxIl0sInBpX2IiOltbIjcyNTI1MDEyNjE5ODM1NTYwMjM1NjA3MzI1MjIzODk2MjIxMDY4MTA5OTUxNzkxNjI0MjY2NzcyNDM2MjQwNTQ0Mzc2Nzc1ODI4MCIsIjgyNDU2MTQzMTExNjUzNTUyNzcyNTgyNTg1NTA0MTI5MTUzNjAzNTc2MjEyMDY5OTA0Mjk3NTE3ODk2NTgwNTI1ODY0Mjc2NjgyMDMiXSxbIjg0MjA4OTI3MTI5OTMyMTU5OTU3NjkwMDQ3MzU2Njc5MzY3MDk4MzY5MTY4MzU4MDM2Njc2NjI1NzQxMTcyNjEzNjI2OTgxMzI1MjkiLCIxMDgyOTQzMjI5MDkyODY3MjM1NjAzNjExMTgxNjE4NTQ0MDU3NTgwMDI1NDQzODAyMzUzNTA3MzUzNTY1ODMzOTE0MzMzODAzNDAyNyJdLFsiMSIsIjAiXV0sInBpX2MiOlsiMTIwNTc1NzM1NDQ2Mzc1NDA1MzE2MjIxNDc2NDg2NjE0MDc1NzM1MzY2MjU0MjM0MzY1ODE0MTk2OTY3NzYwOTMxOTY5Nzc5OTg2MzkiLCIxNTIwMzMwMjIxNjcyOTEzOTcwNjQyNjcyMzc5Mzk5Mjk0MjI5NjY1NTU0NDA4MTEwODkzMTE2MjIwMTQxOTcxNzI0MjU4NTQzOTg2NSIsIjEiXSwicHJvdG9jb2wiOiJncm90aDE2IiwiY3VydmUiOiJibjEyOCJ9LCJwdWJfc2lnbmFscyI6WyIxIiwiMjgwMTg1ODg4MjE0NzE5Mzk2MjQ3MTE0MjE5MjIwNzkzOTU0NTE1MDc3NTQzNzU5Nzg0MDgyMzA1MjQ3OTI3ODY4NjI5OTc1MDMiLCIxNDE5MzMwNDc0NzUwMTMzMTE4MTgwOTcxNTkxMjQ4NzIzNjUyNzAwMzkyNTA4MjEwNjc1MjM3Njc5NjA5OTg5MDIwMTkyODE4NTY5MCIsIjEiLCIyMjk0MjU5NDE1NjI2NjY2NTQyNjYxMzQ2Mjc3MTcyNTMyNzMxNDM4MjY0NzQyNjk1OTA0NDg2MzQ0Njg2NjYxMzAwMzc1MTkzOCIsIjEiLCIzMTY5NjEyMzY4MDg3OTA1MzQyNzg2NTE0MDk5NDQ5Mjk3NDA0MzgzODc0MzcxMzU2OTI0ODI4MDgyMTQzNjExOTUzNjIxODU5NzU5IiwiMTY4NzQzMzc0OCIsIjI2NzgzMTUyMTkyMjU1ODAyNzIwNjA4MjM5MDA0MzMyMTc5Njk0NCIsIjAiLCIyMDM3NjAzMzgzMjM3MTEwOTE3NzY4MzA0ODQ1NjAxNDUyNTkwNTExOTE3MzY3NDk4NTg0MzkxNTQ0NTYzNDcyNjE2NzQ1MDk4OTYzMCIsIjIiLCIyIiwiMjAwMDAxMDEiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiXX1dfSwiZnJvbSI6ImRpZDpwa2g6cG9seToweDcxNDFFNGQyMEY3NjQ0REM4YzBBZENBOGE1MjBFQzgzQzZjQUJENjUiLCJ0byI6ImRpZDpwb2x5Z29uaWQ6cG9seWdvbjptdW1iYWk6MnFMUHF2YXlOUXo5VEEycjVWUHhVdWdvRjE4dGVHVTU4M3pKODU5d2Z5In0.bWc2ECABj7nvHatD8AXWNJM2VtfhkIjNwz5BBIK9zBMsP0-UWLEWdAWcosiLkYoL0KWwZpgEOrPPepl6T5gC-AA` @@ -712,7 +712,7 @@ func TestCreateAuthorizationRequestWithMessage(t *testing.T) { func TestVerifier_FullVerifySelectiveDisclosure(t *testing.T) { // request - verifierID := "did:polygonid:polygon:mumbai:2qEevY9VnKdNsVDdXRv3qSLHRqoMGMRRdE5Gmc6iA7" + verifierID := "did:polygonid:polygon:mumbai:2qJ689kpoJxcSzB5sAFJtPsSBSrHF5dq722BHMqURL" callbackURL := "https://test.com/callback" reason := "age verification" @@ -752,7 +752,7 @@ func TestVerifier_FullVerifySelectiveDisclosure(t *testing.T) { func TestEmptyCredentialSubject(t *testing.T) { // request - verifierID := "did:polygonid:polygon:mumbai:2qEevY9VnKdNsVDdXRv3qSLHRqoMGMRRdE5Gmc6iA7" + verifierID := "did:polygonid:polygon:mumbai:2qJ689kpoJxcSzB5sAFJtPsSBSrHF5dq722BHMqURL" callbackURL := "https://test.com/callback" reason := "age verification" @@ -794,3 +794,349 @@ func loadSchema(name string) string { } return string(bs) } + +func TestVerifyV3MessageWithSigProof_NonMerkalized(t *testing.T) { + verifierID := "did:polygonid:polygon:mumbai:2qEevY9VnKdNsVDdXRv3qSLHRqoMGMRRdE5Gmc6iA7" + callbackURL := "https://test.com/callback" + reason := "test" + + var mtpProofRequest protocol.ZeroKnowledgeProofRequest + mtpProofRequest.ID = 84239 + mtpProofRequest.CircuitID = string(circuits.AtomicQueryV3CircuitID) + opt := true + mtpProofRequest.Optional = &opt + mtpProofRequest.Query = map[string]interface{}{ + "allowedIssuers": []string{"*"}, + "credentialSubject": map[string]interface{}{ + "documentType": map[string]interface{}{ + "$eq": 99, + }, + }, + "context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-nonmerklized.jsonld", + "type": "KYCAgeCredential", + "proofType": "BJJSignature2021", + } + request := CreateAuthorizationRequestWithMessage(reason, "message to sign", verifierID, callbackURL) + request.Body.Scope = append(request.Body.Scope, mtpProofRequest) + + userID := "did:polygonid:polygon:mumbai:2qFXWZVHKTaYX1vmTGtStgRq1s8vUWhQ7HLjtqb2fV" + responseUUID := uuid.New() + + // response + var message protocol.AuthorizationResponseMessage + message.Typ = packers.MediaTypePlainMessage + message.Type = protocol.AuthorizationResponseMessageType + message.From = userID + message.To = verifierID + message.ID = responseUUID.String() + message.ThreadID = request.ThreadID + message.Body = protocol.AuthorizationMessageResponseBody{ + Message: "message to sign", + Scope: []protocol.ZeroKnowledgeProofResponse{ + { + ID: 84239, + CircuitID: mtpProofRequest.CircuitID, + ZKProof: types.ZKProof{ + Proof: &types.ProofData{ + A: []string{ + "15208931239306667614189217356426367087296508213411046833716711442163868780112", + "20490648944065703271613941501811057996992005137106581261392868037192830801319", + "1", + }, + B: [][]string{ + { + "9658837325736932089175519161219586340790605854199431170964132439402760343882", + "2229712957417570067219766417050901639838551011053815708957384652110672096636", + }, + { + "8001092431519117455354797520811940294780537362771012429305941024017334317686", + "14862879727984936294040948959940841120433831193863247939940900720892674782281", + }, + { + "1", + "0", + }}, + C: []string{ + "10979201893913563932568403855542624651100292054247823659266571152101750130209", + "21286864035525845180147694216456377751365547090829007463506610939813242720910", + "1", + }, + Protocol: "groth16", + }, + PubSignals: []string{ + "0", + "22466018227912887497595444357663749526852544754809814096731120723497783810", + "7232286365358812826682228661780467195854751779823604018938921042558237169817", + "0", + "0", + "0", + "1", + "84239", + "26675680708205250151451142983868154544835349648265874601395279235340702210", + "1", + "7232286365358812826682228661780467195854751779823604018938921042558237169817", + "1702457100", + "198285726510688200335207273836123338699", + "1", + "0", + "3", + "1", + "99", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "22728440853100433399211827098349696449620101147489499428101651758549307906", + "0", + }, + }, + }, + }, + } + + schemaLoader := &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-nonmerklized.jsonld": loadSchema("kyc-nonmerklized.jsonld"), + }, + } + authInstance, err := NewVerifier(verificationKeyloader, stateResolvers, + WithDocumentLoader(schemaLoader)) + require.NoError(t, err) + err = authInstance.VerifyAuthResponse(context.Background(), message, request, + pubsignals.WithAcceptedProofGenerationDelay(proofGenerationDelay), + ) + require.Nil(t, err) + schemaLoader.assert(t) +} + +func TestVerifyV3MessageWithMtpProof_Merkalized(t *testing.T) { + verifierID := "did:polygonid:polygon:mumbai:2qEevY9VnKdNsVDdXRv3qSLHRqoMGMRRdE5Gmc6iA7" + callbackURL := "https://test.com/callback" + reason := "test" + + var mtpProofRequest protocol.ZeroKnowledgeProofRequest + mtpProofRequest.ID = 84239 + mtpProofRequest.CircuitID = string(circuits.AtomicQueryV3CircuitID) + opt := true + mtpProofRequest.Optional = &opt + mtpProofRequest.Query = map[string]interface{}{ + "allowedIssuers": []string{"did:polygonid:polygon:mumbai:2qKKc4jxAhabrdFrAF3iC7boycfdQmWXq2qTBU4sPc"}, + "credentialSubject": map[string]interface{}{ + "ZKPexperiance": map[string]interface{}{ + "$eq": true, + }, + }, + "context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld", + "type": "KYCEmployee", + "proofType": "Iden3SparseMerkleTreeProof", + } + + request := CreateAuthorizationRequestWithMessage(reason, "message to sign", verifierID, callbackURL) + request.Body.Scope = append(request.Body.Scope, mtpProofRequest) + + userID := "did:polygonid:polygon:mumbai:2qFXWZVHKTaYX1vmTGtStgRq1s8vUWhQ7HLjtqb2fV" + responseUUID := uuid.New() + + // response + var message protocol.AuthorizationResponseMessage + message.Typ = packers.MediaTypePlainMessage + message.Type = protocol.AuthorizationResponseMessageType + message.From = userID + message.To = verifierID + message.ID = responseUUID.String() + message.ThreadID = request.ThreadID + message.Body = protocol.AuthorizationMessageResponseBody{ + Message: "message to sign", + Scope: []protocol.ZeroKnowledgeProofResponse{ + { + ID: 84239, + CircuitID: mtpProofRequest.CircuitID, + ZKProof: types.ZKProof{ + Proof: &types.ProofData{ + A: []string{ + "2191675399003747228361650328748147195525067334657244384911902711268678817802", + "19948479904115663964234685946314006853666845209972027887002197866333362304394", + "1", + }, + B: [][]string{ + { + "422189606437031219571968003421368368386938453003241975855652752251201163758", + "9263822572774254449054388930060153687464515712228765747368750307969672340141", + }, + { + "19293339395101879017873172109004141351276884864694548105955158013357482683356", + "2779213239514041287265984937924693652347623320831272361142245115033321578990", + }, + { + "1", + "0", + }}, + C: []string{ + "3805936274754036854895936107504061566835912493410231954955974762213052034636", + "11817318886045212940702535466395270095280111730105021796772613798925818134104", + "1", + }, + Protocol: "groth16", + }, + PubSignals: []string{ + "1", + "22466018227912887497595444357663749526852544754809814096731120723497783810", + "16501727979801979045409842472064689783782600072880560178348889772807800718289", + "0", + "0", + "0", + "2", + "84239", + "26675680708205250151451142983868154544835349648265874601395279235340702210", + "1", + "16501727979801979045409842472064689783782600072880560178348889772807800718289", + "1702457550", + "219578617064540016234161640375755865412", + "0", + "1944808975288007371356450257872165609440470546066507760733183342797918372827", + "0", + "1", + "18586133768512220936620570745912940619677854269274689475585506675881198879027", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "22728440853100433399211827098349696449620101147489499428101651758549307906", + "0", + }, + }, + }, + }, + } + + schemaLoader := &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld": loadSchema("kyc-v101.json-ld"), + }, + } + authInstance, err := NewVerifier(verificationKeyloader, stateResolvers, + WithDocumentLoader(schemaLoader)) + require.NoError(t, err) + err = authInstance.VerifyAuthResponse(context.Background(), message, request, + pubsignals.WithAcceptedProofGenerationDelay(proofGenerationDelay)) + require.Nil(t, err) + schemaLoader.assert(t) +} diff --git a/go.mod b/go.mod index 00f4c15..f13713a 100644 --- a/go.mod +++ b/go.mod @@ -8,14 +8,14 @@ require ( github.com/golang/mock v1.6.0 github.com/google/uuid v1.3.0 github.com/iden3/contracts-abi/state/go/abi v1.0.0-beta.3 - github.com/iden3/go-circuits/v2 v2.0.0 - github.com/iden3/go-iden3-core/v2 v2.0.0 - github.com/iden3/go-jwz/v2 v2.0.0 + github.com/iden3/go-circuits/v2 v2.0.1 + github.com/iden3/go-iden3-core/v2 v2.0.3 + github.com/iden3/go-jwz/v2 v2.0.1 github.com/iden3/go-rapidsnark/types v0.0.3 github.com/iden3/go-rapidsnark/verifier v0.0.5 - github.com/iden3/go-schema-processor/v2 v2.0.0 - github.com/iden3/iden3comm/v2 v2.0.0 - github.com/ipfs/go-ipfs-api v0.6.0 + github.com/iden3/go-schema-processor/v2 v2.1.1 + github.com/iden3/iden3comm/v2 v2.1.0 + github.com/ipfs/go-ipfs-api v0.7.0 github.com/piprate/json-gold v0.5.1-0.20230111113000-6ddbe6e6f19f github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.8.4 @@ -23,6 +23,7 @@ require ( require ( github.com/benbjohnson/clock v1.3.5 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect github.com/btcsuite/btcd v0.23.3 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect @@ -43,7 +44,7 @@ require ( github.com/iden3/go-rapidsnark/prover v0.0.10 // indirect github.com/iden3/go-rapidsnark/witness/v2 v2.0.0 // indirect github.com/iden3/go-rapidsnark/witness/wazero v0.0.0-20230524142950-0986cf057d4e // indirect - github.com/ipfs/boxo v0.8.0 // indirect + github.com/ipfs/boxo v0.12.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/lestrrat-go/blackmagic v1.0.1 // indirect @@ -63,7 +64,7 @@ require ( github.com/multiformats/go-multiaddr v0.9.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multicodec v0.9.0 // indirect - github.com/multiformats/go-multihash v0.2.2 // indirect + github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -75,7 +76,6 @@ require ( github.com/tetratelabs/wazero v1.1.0 // indirect github.com/tklauser/go-sysconf v0.3.11 // indirect github.com/tklauser/numcpus v0.6.0 // indirect - github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect golang.org/x/crypto v0.12.0 // indirect golang.org/x/sys v0.11.0 // indirect diff --git a/go.sum b/go.sum index 273c83b..9392cec 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBA github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.0/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY= @@ -107,14 +109,14 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= github.com/iden3/contracts-abi/state/go/abi v1.0.0-beta.3 h1:ZHFnK2dU3NJglY+igY48JLHWtNGN/Vhf5/L/qrFk/tM= github.com/iden3/contracts-abi/state/go/abi v1.0.0-beta.3/go.mod h1:TxgIrXCvxms3sbOdsy8kTvffUCIpEEifNy0fSXdkU4w= -github.com/iden3/go-circuits/v2 v2.0.0 h1:Bw0mpsqeip06d6I2ktgfhTVB7Jk9mSHi8myHZWkoc6w= -github.com/iden3/go-circuits/v2 v2.0.0/go.mod h1:VIFIp51+IH0hOzjnKhb84bCeyq7hq76zX/C14ua6zh4= -github.com/iden3/go-iden3-core/v2 v2.0.0 h1:sQEuuq3RLfyYSY8qPiqxQ6YBpGbiAwepHJD/vjf1adA= -github.com/iden3/go-iden3-core/v2 v2.0.0/go.mod h1:L9PxhWPvoS9qTb3inEkZBm1RpjHBt+VTwvxssdzbAdw= +github.com/iden3/go-circuits/v2 v2.0.1 h1:tcJtBE8aLJsf9qpBoTUKE143Mne025cunQnSExMXaKo= +github.com/iden3/go-circuits/v2 v2.0.1/go.mod h1:VIFIp51+IH0hOzjnKhb84bCeyq7hq76zX/C14ua6zh4= +github.com/iden3/go-iden3-core/v2 v2.0.3 h1:ce9Jbw10zDsinWXFc05SiK2Hof/wu4zV4/ai5gQy29k= +github.com/iden3/go-iden3-core/v2 v2.0.3/go.mod h1:L9PxhWPvoS9qTb3inEkZBm1RpjHBt+VTwvxssdzbAdw= github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4= github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E= -github.com/iden3/go-jwz/v2 v2.0.0 h1:VsU2PrmcchPMx/V0IhamMZRNjiQYZoyJopO8K8uSZOY= -github.com/iden3/go-jwz/v2 v2.0.0/go.mod h1:JBJ58Cef8h+4Uz8qaVRsNjiT/Ubqb800dGKTZt66NkU= +github.com/iden3/go-jwz/v2 v2.0.1 h1:y8HccYGaI5JULVTOfKRPsQ2pGRx8pfgkdCz0kQA8jQE= +github.com/iden3/go-jwz/v2 v2.0.1/go.mod h1:+DRKSnFk3IsDvcKZA5EDeJFOSxjXm1kWAp588Kf+FN8= github.com/iden3/go-merkletree-sql/v2 v2.0.4 h1:Dp089P3YNX1BE8+T1tKQHWTtnk84Y/Kr7ZAGTqwscoY= github.com/iden3/go-merkletree-sql/v2 v2.0.4/go.mod h1:kRhHKYpui5DUsry5RpveP6IC4XMe6iApdV9VChRYuEk= github.com/iden3/go-rapidsnark/prover v0.0.10 h1:NvOfRPpex/k646UsqOcUy7a7uVl17t4ok9kWvpQg4+k= @@ -127,16 +129,16 @@ github.com/iden3/go-rapidsnark/witness/v2 v2.0.0 h1:mkY6VDfwKVJc83QGKmwVXY2LYepi github.com/iden3/go-rapidsnark/witness/v2 v2.0.0/go.mod h1:3JRjqUfW1hgI9hzLDO0v8z/DUkR0ZUehhYLlnIfRxnA= github.com/iden3/go-rapidsnark/witness/wazero v0.0.0-20230524142950-0986cf057d4e h1:WeiFCrpj5pLRtSA4Mg03yTrSZhHHqN/k5b6bwxd9/tY= github.com/iden3/go-rapidsnark/witness/wazero v0.0.0-20230524142950-0986cf057d4e/go.mod h1:UEBifEzw62T6VzIHJeHuUgeLg2U/J9ttf7hOwQEqnYk= -github.com/iden3/go-schema-processor/v2 v2.0.0 h1:izbC5+rd7rV1np+tjCqDe016qlOKu6JF7r8LQvdObWM= -github.com/iden3/go-schema-processor/v2 v2.0.0/go.mod h1:eWRQDbxixZ/9k/uPlciKIy6TUYlKX/6hdqyTuAQi3wE= -github.com/iden3/iden3comm/v2 v2.0.0 h1:cFDfF6aJ589ENg5zlTBEPK6Qqv4I11C/gliAWZORpyY= -github.com/iden3/iden3comm/v2 v2.0.0/go.mod h1:wrXoxi8eoQSLopatRW5+hYF9lDRvzGL2As9ZE88q/kA= -github.com/ipfs/boxo v0.8.0 h1:UdjAJmHzQHo/j3g3b1bAcAXCj/GM6iTwvSlBDvPBNBs= -github.com/ipfs/boxo v0.8.0/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= +github.com/iden3/go-schema-processor/v2 v2.1.1 h1:kS9D2ynuF2hgLM9e+IHV0kt6Tz4W/wXv+TXwUVQQi6M= +github.com/iden3/go-schema-processor/v2 v2.1.1/go.mod h1:wIa6h8BPWnXBImIIElYu5eLVW513pHjyTOj6KyVHenQ= +github.com/iden3/iden3comm/v2 v2.1.0 h1:op2X3y/H9khizcdoYKf3iRAQFt/l5dsip47sJu1kv7Q= +github.com/iden3/iden3comm/v2 v2.1.0/go.mod h1:G+ufR/M28O3PKMVrkUqCuoYfjiEkGFWvf8oF2BmFC6c= +github.com/ipfs/boxo v0.12.0 h1:AXHg/1ONZdRQHQLgG5JHsSC3XoE4DjCAMgK+asZvUcQ= +github.com/ipfs/boxo v0.12.0/go.mod h1:xAnfiU6PtxWCnRqu7dcXQ10bB5/kvI1kXRotuGqGBhg= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= -github.com/ipfs/go-ipfs-api v0.6.0 h1:JARgG0VTbjyVhO5ZfesnbXv9wTcMvoKRBLF1SzJqzmg= -github.com/ipfs/go-ipfs-api v0.6.0/go.mod h1:iDC2VMwN9LUpQV/GzEeZ2zNqd8NUdRmWcFM+K/6odf0= +github.com/ipfs/go-ipfs-api v0.7.0 h1:CMBNCUl0b45coC+lQCXEVpMhwoqjiaCwUIrM+coYW2Q= +github.com/ipfs/go-ipfs-api v0.7.0/go.mod h1:AIxsTNB0+ZhkqIfTZpdZ0VR/cpX5zrXjATa3prSay3g= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -190,8 +192,8 @@ github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivnc github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= -github.com/multiformats/go-multihash v0.2.2 h1:Uu7LWs/PmWby1gkj1S1DXx3zyd3aVabA4FiMKn/2tAc= -github.com/multiformats/go-multihash v0.2.2/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= +github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= +github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= @@ -249,8 +251,6 @@ github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYm github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= -github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b h1:wA3QeTsaAXybLL2kb2cKhCAQTHgYTMwuI8lBlJSv5V8= -github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b/go.mod h1:xT1Y5p2JR2PfSZihE0s4mjdJaRGp1waCTf5JzhQLBck= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= diff --git a/pubsignals/atomicMtpV2.go b/pubsignals/atomicMtpV2.go index b44d548..f430565 100644 --- a/pubsignals/atomicMtpV2.go +++ b/pubsignals/atomicMtpV2.go @@ -25,6 +25,7 @@ func (c *AtomicQueryMTPV2) VerifyQuery( query Query, schemaLoader ld.DocumentLoader, verifiablePresentation json.RawMessage, + _ map[string]interface{}, opts ...VerifyOpt, ) error { return query.Check(ctx, schemaLoader, &CircuitOutputs{ @@ -39,7 +40,7 @@ func (c *AtomicQueryMTPV2) VerifyQuery( ClaimPathNotExists: c.ClaimPathNotExists, ValueArraySize: c.ValueArraySize, IsRevocationChecked: c.IsRevocationChecked, - }, verifiablePresentation, opts...) + }, verifiablePresentation, false, opts...) } // VerifyStates verifies user state and issuer claim issuance state in the smart contract. @@ -82,7 +83,7 @@ func (c *AtomicQueryMTPV2) VerifyStates(ctx context.Context, if !issuerNonRevStateResolved.Latest && time.Since( time.Unix(issuerNonRevStateResolved.TransitionTimestamp, 0), - ) > cfg.acceptedStateTransitionDelay { + ) > cfg.AcceptedStateTransitionDelay { return ErrIssuerNonRevocationClaimStateIsNotValid } diff --git a/pubsignals/atomicSigV2.go b/pubsignals/atomicSigV2.go index 0076fe8..b8ac6d1 100644 --- a/pubsignals/atomicSigV2.go +++ b/pubsignals/atomicSigV2.go @@ -25,6 +25,7 @@ func (c *AtomicQuerySigV2) VerifyQuery( query Query, schemaLoader ld.DocumentLoader, verifiablePresentation json.RawMessage, + _ map[string]interface{}, opts ...VerifyOpt, ) error { err := query.Check(ctx, schemaLoader, &CircuitOutputs{ @@ -39,7 +40,7 @@ func (c *AtomicQuerySigV2) VerifyQuery( ClaimPathNotExists: c.ClaimPathNotExists, ValueArraySize: c.ValueArraySize, IsRevocationChecked: c.IsRevocationChecked, - }, verifiablePresentation, opts...) + }, verifiablePresentation, false, opts...) if err != nil { return err } @@ -85,7 +86,7 @@ func (c *AtomicQuerySigV2) VerifyStates(ctx context.Context, stateResolvers map[ if !issuerNonRevStateResolved.Latest && time.Since( time.Unix(issuerNonRevStateResolved.TransitionTimestamp, 0), - ) > cfg.acceptedStateTransitionDelay { + ) > cfg.AcceptedStateTransitionDelay { return ErrIssuerNonRevocationClaimStateIsNotValid } diff --git a/pubsignals/atomicV3.go b/pubsignals/atomicV3.go new file mode 100644 index 0000000..2d8057b --- /dev/null +++ b/pubsignals/atomicV3.go @@ -0,0 +1,170 @@ +package pubsignals + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "time" + + "github.com/iden3/go-circuits/v2" + core "github.com/iden3/go-iden3-core/v2" + "github.com/iden3/go-iden3-core/v2/w3c" + verifiable "github.com/iden3/go-schema-processor/v2/verifiable" + "github.com/piprate/json-gold/ld" + "github.com/pkg/errors" +) + +// AtomicQueryV3 is a wrapper for circuits.AtomicQueryV3PubSignals. +type AtomicQueryV3 struct { + circuits.AtomicQueryV3PubSignals +} + +// VerifyQuery verifies query for atomic query V3 circuit. +func (c *AtomicQueryV3) VerifyQuery( + ctx context.Context, + query Query, + schemaLoader ld.DocumentLoader, + verifiablePresentation json.RawMessage, + params map[string]interface{}, + opts ...VerifyOpt, +) error { + err := query.Check(ctx, schemaLoader, &CircuitOutputs{ + IssuerID: c.IssuerID, + ClaimSchema: c.ClaimSchema, + SlotIndex: c.SlotIndex, + Operator: c.Operator, + Value: c.Value, + Timestamp: c.Timestamp, + Merklized: c.Merklized, + ClaimPathKey: c.ClaimPathKey, + ClaimPathNotExists: c.ClaimPathNotExists, + ValueArraySize: c.ValueArraySize, + IsRevocationChecked: c.IsRevocationChecked, + // V3 NEW + LinkID: c.LinkID, + VerifierID: c.VerifierID, + NullifierSessionID: c.NullifierSessionID, + OperatorOutput: c.OperatorOutput, + Nullifier: c.Nullifier, + ProofType: c.ProofType, + }, verifiablePresentation, true, opts...) + if err != nil { + return err + } + + // V3 NEW + switch query.ProofType { + case string(verifiable.BJJSignatureProofType): + if c.ProofType != 1 { + return ErrWronProofType + } + case string(verifiable.Iden3SparseMerkleTreeProofType): + if c.ProofType != 2 { + return ErrWronProofType + } + default: + } + + if params != nil { + nullifierSessionIDparam, ok := params[ParamNameNullifierSessionID].(string) + if ok { + verifierDID, ok := params[ParamNameVerifierDID].(*w3c.DID) + if !ok { + return errors.New("verifier did is mandatory if nullifier session is set in the request") + } + id, err := core.IDFromDID(*verifierDID) + if err != nil { + return err + } + if c.VerifierID.BigInt().Cmp(id.BigInt()) != 0 { + return errors.New("wrong verifier is used for nullification") + } + + nullifierSessionID, ok := new(big.Int).SetString(nullifierSessionIDparam, 10) + if !ok { + return errors.New("nullifier session is not a valid big integer") + } + if c.NullifierSessionID.Cmp(nullifierSessionID) != 0 { + return errors.Errorf("wrong verifier session id is used for nullification: expected %s given %s,", nullifierSessionID.String(), c.NullifierSessionID.String()) + } + } else if c.NullifierSessionID != nil && c.NullifierSessionID.Int64() != 0 { + // if no nullifierSessionID in params - we need to verify that nullifier is zero + return errors.New("nullifier id is generated but wasn't requested") + } + + } + + if query.GroupID != 0 && c.LinkID == nil { + return errors.New("proof doesn't contain link id, but group id is provided") + } + + return nil +} + +// VerifyStates verifies user state and issuer auth claim state in the smart contract. +func (c *AtomicQueryV3) VerifyStates(ctx context.Context, stateResolvers map[string]StateResolver, opts ...VerifyOpt) error { + blockchain, err := core.BlockchainFromID(*c.IssuerID) + if err != nil { + return err + } + networkID, err := core.NetworkIDFromID(*c.IssuerID) + if err != nil { + return err + } + resolver, ok := stateResolvers[fmt.Sprintf("%s:%s", blockchain, networkID)] + if !ok { + return errors.Errorf("%s resolver not found", resolver) + } + + issuerStateResolved, err := resolver.Resolve(ctx, c.IssuerID.BigInt(), c.IssuerState.BigInt()) + if err != nil { + return err + } + if issuerStateResolved == nil { + return ErrIssuerClaimStateIsNotValid + } + + // if IsRevocationChecked is set to 0. Skip validation revocation status of issuer. + if c.IsRevocationChecked == 0 { + return nil + } + issuerNonRevStateResolved, err := resolver.Resolve(ctx, c.IssuerID.BigInt(), c.IssuerClaimNonRevState.BigInt()) + if err != nil { + return err + } + + cfg := defaultProofVerifyOpts + for _, o := range opts { + o(&cfg) + } + + if !issuerNonRevStateResolved.Latest && time.Since( + time.Unix(issuerNonRevStateResolved.TransitionTimestamp, 0), + ) > cfg.AcceptedStateTransitionDelay { + return ErrIssuerNonRevocationClaimStateIsNotValid + } + + return nil +} + +// VerifyIDOwnership returns error if ownership id wasn't verified in circuit. +func (c *AtomicQueryV3) VerifyIDOwnership(sender string, requestID *big.Int) error { + if c.RequestID.Cmp(requestID) != 0 { + return errors.New("invalid requestID in proof") + } + + did, err := w3c.ParseDID(sender) + if err != nil { + return errors.Wrap(err, "sender must be a valid did") + } + senderID, err := core.IDFromDID(*did) + if err != nil { + return err + } + + if senderID.String() != c.UserID.String() { + return errors.Errorf("sender is not used for proof creation, expected %s, user from public signals: %s}", senderID.String(), c.UserID.String()) + } + return nil +} diff --git a/pubsignals/authV2.go b/pubsignals/authV2.go index 39cb161..40cfd95 100644 --- a/pubsignals/authV2.go +++ b/pubsignals/authV2.go @@ -25,6 +25,7 @@ func (c *AuthV2) VerifyQuery( _ Query, _ ld.DocumentLoader, _ json.RawMessage, + _ map[string]interface{}, _ ...VerifyOpt) error { return errors.New("authV2 circuit doesn't support queries") } @@ -55,7 +56,7 @@ func (c *AuthV2) VerifyStates(ctx context.Context, stateResolvers map[string]Sta o(&cfg) } - if !resolvedState.Latest && time.Since(time.Unix(resolvedState.TransitionTimestamp, 0)) > cfg.acceptedStateTransitionDelay { + if !resolvedState.Latest && time.Since(time.Unix(resolvedState.TransitionTimestamp, 0)) > cfg.AcceptedStateTransitionDelay { return ErrGlobalStateIsNotValid } return nil diff --git a/pubsignals/circuitVerifier.go b/pubsignals/circuitsVerifier.go similarity index 87% rename from pubsignals/circuitVerifier.go rename to pubsignals/circuitsVerifier.go index 79206f9..7fc6c3d 100644 --- a/pubsignals/circuitVerifier.go +++ b/pubsignals/circuitsVerifier.go @@ -18,7 +18,7 @@ type StateResolver interface { // Verifier is interface for verification of public signals of zkp type Verifier interface { - VerifyQuery(ctx context.Context, query Query, schemaLoader ld.DocumentLoader, verifiablePresentation json.RawMessage, opts ...VerifyOpt) error + VerifyQuery(ctx context.Context, query Query, schemaLoader ld.DocumentLoader, verifiablePresentation json.RawMessage, circuitParams map[string]interface{}, opts ...VerifyOpt) error VerifyStates(ctx context.Context, resolvers map[string]StateResolver, opts ...VerifyOpt) error VerifyIDOwnership(userIdentifier string, challenge *big.Int) error diff --git a/pubsignals/query.go b/pubsignals/query.go index 6584530..b066970 100644 --- a/pubsignals/query.go +++ b/pubsignals/query.go @@ -19,12 +19,16 @@ import ( ) var allOperations = map[int]struct{}{ - circuits.EQ: {}, - circuits.LT: {}, - circuits.GT: {}, - circuits.IN: {}, - circuits.NIN: {}, - circuits.NE: {}, + circuits.EQ: {}, + circuits.LT: {}, + circuits.LTE: {}, + circuits.GT: {}, + circuits.GTE: {}, + circuits.IN: {}, + circuits.NIN: {}, + circuits.NE: {}, + circuits.BETWEEN: {}, + circuits.NULLIFY: {}, } var availableTypesOperations = map[string]map[int]struct{}{ @@ -63,6 +67,8 @@ type Query struct { Type string `json:"type"` ClaimID string `json:"claimId,omitempty"` SkipClaimRevocationCheck bool `json:"skipClaimRevocationCheck,omitempty"` + ProofType string `json:"proofType"` + GroupID int `json:"groupId"` } // CircuitOutputs pub signals from circuit. @@ -78,6 +84,14 @@ type CircuitOutputs struct { ClaimPathNotExists int ValueArraySize int IsRevocationChecked int + // V3 NEW + LinkID *big.Int + VerifierID *core.ID + NullifierSessionID *big.Int + + OperatorOutput *big.Int + Nullifier *big.Int + ProofType int } // Check checks if proof was created for this query. @@ -88,6 +102,7 @@ func (q Query) Check( loader ld.DocumentLoader, pubSig *CircuitOutputs, verifiablePresentation json.RawMessage, + supportSdOperator bool, opts ...VerifyOpt, ) error { if err := q.verifyIssuer(pubSig); err != nil { @@ -109,7 +124,7 @@ func (q Query) Check( } if err := q.verifyCredentialSubject(pubSig, verifiablePresentation, - schemaBytes, loader); err != nil { + schemaBytes, loader, supportSdOperator); err != nil { return err } @@ -124,7 +139,7 @@ func (q Query) Check( if time.Since( time.Unix(pubSig.Timestamp, 0), - ) > cfg.acceptedProofGenerationDelay { + ) > cfg.AcceptedProofGenerationDelay { return ErrProofGenerationOutdated } @@ -212,6 +227,7 @@ func (q Query) verifyCredentialSubject( verifiablePresentation json.RawMessage, ctxBytes []byte, schemaLoader ld.DocumentLoader, + supportSdOperator bool, ) error { fieldName, predicate, err := extractQueryFields(q.CredentialSubject) if err != nil { @@ -231,7 +247,7 @@ func (q Query) verifyCredentialSubject( if q.isSelectivityDisclosure(predicate) { ctx := context.Background() return q.validateDisclosure(ctx, pubSig, fieldName, - verifiablePresentation, schemaLoader) + verifiablePresentation, schemaLoader, supportSdOperator) } // validate empty credential subject request @@ -275,22 +291,12 @@ func (q Query) verifyCredentialSubject( func (q Query) validateDisclosure(ctx context.Context, pubSig *CircuitOutputs, key string, verifiablePresentation json.RawMessage, - schemaLoader ld.DocumentLoader) error { + schemaLoader ld.DocumentLoader, suppordSdOperator bool) error { if verifiablePresentation == nil { return errors.New("selective disclosure value is missed") } - if pubSig.Operator != circuits.EQ { - return errors.New("selective disclosure available only for equal operation") - } - - for i := 1; i < len(pubSig.Value); i++ { - if pubSig.Value[i].Cmp(big.NewInt(0)) != 0 { - return errors.New("selective disclosure not available for array of values") - } - } - mz, err := merklize.MerklizeJSONLD(ctx, bytes.NewBuffer(verifiablePresentation), merklize.WithDocumentLoader(schemaLoader)) @@ -318,8 +324,35 @@ func (q Query) validateDisclosure(ctx context.Context, pubSig *CircuitOutputs, return errors.Errorf("failed to hash value: %v", err) } - if pubSig.Value[0].Cmp(mvBig) != 0 { - return errors.New("different value between proof and disclosure value") + if !suppordSdOperator { + if pubSig.Operator != circuits.EQ { + return errors.New("selective disclosure available only for equal operation") + } + + for i := 1; i < len(pubSig.Value); i++ { + if pubSig.Value[i].Cmp(big.NewInt(0)) != 0 { + return errors.New("selective disclosure not available for array of values") + } + } + + if pubSig.Value[0].Cmp(mvBig) != 0 { + return errors.New("different value between proof and disclosure value") + } + + } else { + if pubSig.Operator != circuits.SD { + return errors.New("invalid pub signal operator for selective disclosure") + } + + if pubSig.OperatorOutput == nil || pubSig.OperatorOutput.Cmp(mvBig) != 0 { + return errors.New("operator output should be equal to disclosed value") + } + for i := 0; i < len(pubSig.Value); i++ { + if pubSig.Value[i].Cmp(big.NewInt(0)) != 0 { + return errors.New("selective disclosure values should be zero") + } + } + } return nil diff --git a/pubsignals/query_test.go b/pubsignals/query_test.go index 9f3b716..94bf65a 100644 --- a/pubsignals/query_test.go +++ b/pubsignals/query_test.go @@ -289,7 +289,7 @@ func TestCheckRequest_Success(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := tt.query.Check(context.Background(), tt.loader, tt.pubSig, tt.vp) + err := tt.query.Check(context.Background(), tt.loader, tt.pubSig, tt.vp, false) require.NoError(t, err) tt.loader.assert(t) }) @@ -399,6 +399,7 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { loader: &mockJSONLDSchemaLoader{ schemas: map[string]string{ "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + "https://www.w3.org/2018/credentials/v1": loadSchema("credentials-v1.json-ld"), }, }, }, @@ -430,6 +431,7 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { loader: &mockJSONLDSchemaLoader{ schemas: map[string]string{ "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + "https://www.w3.org/2018/credentials/v1": loadSchema("credentials-v1.json-ld"), }, }, }, @@ -501,7 +503,7 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := tt.query.Check(context.Background(), tt.loader, tt.pubSig, tt.vp) + err := tt.query.Check(context.Background(), tt.loader, tt.pubSig, tt.vp, false) require.EqualError(t, err, tt.expErr.Error()) tt.loader.assert(t) }) @@ -791,7 +793,7 @@ func TestCheckRequest_Error(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := tt.query.Check(context.Background(), tt.loader, tt.pubSig, nil) + err := tt.query.Check(context.Background(), tt.loader, tt.pubSig, nil, false) require.EqualError(t, err, tt.expErr.Error()) tt.loader.assert(t) }) diff --git a/pubsignals/signals.go b/pubsignals/signals.go index 73fc6a2..1cd8adf 100644 --- a/pubsignals/signals.go +++ b/pubsignals/signals.go @@ -20,6 +20,8 @@ var ( ErrIssuerNonRevocationClaimStateIsNotValid = errors.New("issuer state for non-revocation proofs is not valid") // ErrProofGenerationOutdated declares that generated proof is outdated. ErrProofGenerationOutdated = errors.New("generated proof is outdated") + // ErrWronProofType declares that query proof type doesn't match circuit proof type + ErrWronProofType = errors.New("invalid proof type") ) // RegisterVerifier is factory for public signals init. @@ -36,6 +38,7 @@ func init() { RegisterVerifier(circuits.AuthV2CircuitID, reflect.TypeOf(AuthV2{})) RegisterVerifier(circuits.AtomicQuerySigV2CircuitID, reflect.TypeOf(AtomicQuerySigV2{})) RegisterVerifier(circuits.AtomicQueryMTPV2CircuitID, reflect.TypeOf(AtomicQueryMTPV2{})) + RegisterVerifier(circuits.AtomicQueryV3CircuitID, reflect.TypeOf(AtomicQueryV3{})) } // GetVerifier return specific public signals verifier diff --git a/pubsignals/verifyopts.go b/pubsignals/verifyopts.go index fcb0cb6..62b0e49 100644 --- a/pubsignals/verifyopts.go +++ b/pubsignals/verifyopts.go @@ -1,24 +1,26 @@ package pubsignals -import "time" +import ( + "time" +) var ( - defaultAuthVerifyOpts = VerifyConfig{acceptedStateTransitionDelay: time.Minute * 5} - defaultProofVerifyOpts = VerifyConfig{acceptedStateTransitionDelay: time.Hour, - acceptedProofGenerationDelay: time.Hour * 24} + defaultAuthVerifyOpts = VerifyConfig{AcceptedStateTransitionDelay: time.Minute * 5} + defaultProofVerifyOpts = VerifyConfig{AcceptedStateTransitionDelay: time.Hour, + AcceptedProofGenerationDelay: time.Hour * 24} ) // WithAcceptedStateTransitionDelay sets the delay of the revoked state. func WithAcceptedStateTransitionDelay(duration time.Duration) VerifyOpt { return func(v *VerifyConfig) { - v.acceptedStateTransitionDelay = duration + v.AcceptedStateTransitionDelay = duration } } // WithAcceptedProofGenerationDelay sets the delay of the proof generation. func WithAcceptedProofGenerationDelay(duration time.Duration) VerifyOpt { return func(v *VerifyConfig) { - v.acceptedProofGenerationDelay = duration + v.AcceptedProofGenerationDelay = duration } } @@ -28,6 +30,12 @@ type VerifyOpt func(v *VerifyConfig) // VerifyConfig verifiers options. type VerifyConfig struct { // is the period of time that a revoked state remains valid. - acceptedStateTransitionDelay time.Duration - acceptedProofGenerationDelay time.Duration + AcceptedStateTransitionDelay time.Duration + AcceptedProofGenerationDelay time.Duration } + +// ParamNameVerifierDID is a verifier did - specific circuit param for V3, but can be utilized by other circuits +const ParamNameVerifierDID = "verifierDid" + +// ParamNameNullifierSessionID is a nullifier session id - specific circuit param for V3 to generate nullifier +const ParamNameNullifierSessionID = "nullifierSessionId" diff --git a/testdata/credentialAtomicQueryV3-beta.0.json b/testdata/credentialAtomicQueryV3-beta.0.json new file mode 100644 index 0000000..9df5226 --- /dev/null +++ b/testdata/credentialAtomicQueryV3-beta.0.json @@ -0,0 +1,495 @@ +{ + "protocol": "groth16", + "curve": "bn128", + "nPublic": 83, + "vk_alpha_1": [ + "20491192805390485299153009773594534940189261866228447918068658471970481763042", + "9383485363053290200918347156157836566562967994039712273449902621266178545958", + "1" + ], + "vk_beta_2": [ + [ + "6375614351688725206403948262868962793625744043794305715222011528459656738731", + "4252822878758300859123897981450591353533073413197771768651442665752259397132" + ], + [ + "10505242626370262277552901082094356697409835680220590971873171140371331206856", + "21847035105528745403288232691147584728191162732299865338377159692350059136679" + ], + ["1", "0"] + ], + "vk_gamma_2": [ + [ + "10857046999023057135944570762232829481370756359578518086990519993285655852781", + "11559732032986387107991004021392285783925812861821192530917403151452391805634" + ], + [ + "8495653923123431417604973247489272438418190587263600148770280649306958101930", + "4082367875863433681332203403145435568316851327593401208105741076214120093531" + ], + ["1", "0"] + ], + "vk_delta_2": [ + [ + "11976799972565142046928779679957496331111056027783421694970403823131728845628", + "17707424727119423375544455359434696364814068883852168005475757719311070982813" + ], + [ + "2832668973881097889983213316880550353175106432551138266777535433609451803545", + "19119233422256945561384224299248913519024909380224405207620923295628013133273" + ], + ["1", "0"] + ], + "vk_alphabeta_12": [ + [ + [ + "2029413683389138792403550203267699914886160938906632433982220835551125967885", + "21072700047562757817161031222997517981543347628379360635925549008442030252106" + ], + [ + "5940354580057074848093997050200682056184807770593307860589430076672439820312", + "12156638873931618554171829126792193045421052652279363021382169897324752428276" + ], + [ + "7898200236362823042373859371574133993780991612861777490112507062703164551277", + "7074218545237549455313236346927434013100842096812539264420499035217050630853" + ] + ], + [ + [ + "7077479683546002997211712695946002074877511277312570035766170199895071832130", + "10093483419865920389913245021038182291233451549023025229112148274109565435465" + ], + [ + "4595479056700221319381530156280926371456704509942304414423590385166031118820", + "19831328484489333784475432780421641293929726139240675179672856274388269393268" + ], + [ + "11934129596455521040620786944827826205713621633706285934057045369193958244500", + "8037395052364110730298837004334506829870972346962140206007064471173334027475" + ] + ] + ], + "IC": [ + [ + "16411062099636080551704499640416617658167063863113344239852521764433532329940", + "9451828059270734079207650131845887761726300020570233083410640572477379887259", + "1" + ], + [ + "12607552600455602907851199880386583903392217581022149049138906800307577981079", + "12922078419506665803212536930852522853718666478130249673391608917945147728257", + "1" + ], + [ + "5293435528193175878301988034762133865600461491387527029332623216512525777332", + "17526903323073212534405500622248315265456190790052501948369591980523440834417", + "1" + ], + [ + "17111278324684729881239440048152194688755107186387340394286572327160272613953", + "1260550312339989167243927441942975863425165385765055946330052611107585686338", + "1" + ], + [ + "20448141033331056458778640069454373263234599430950604954029227404589918024755", + "15498711218006278205815213741886908870344213864784638413980747776286332358651", + "1" + ], + [ + "15394002529950264277539024435516826647439868224391792810704004814804807891954", + "2351906294661424078411953356127460578031167289038137687322814642643059017221", + "1" + ], + [ + "16448400853311308722740447364699700525420095790803657766725302708809792428398", + "19999734838192024513602538088857419051120224406703632662595576723924769986822", + "1" + ], + [ + "8486640758980724110391526836485003589280095713996996571677356573786368213044", + "17278260653973275150999558501184790307383160595916825526424951191480703554629", + "1" + ], + [ + "9655308842478367747380567935741616739537287794086134661628962769395385166911", + "12734994963229284597800944882312123859546235248378068181801944653203239238373", + "1" + ], + [ + "11864346718208489097650319646131085268644595787201364611278202123322753045642", + "15972904016675328815277380596506154319266104800818625120851125590568908504718", + "1" + ], + [ + "14930512661971597346940568084743926817661669777617039328353865400342798992338", + "21823013844529546179632215154512510859648879632330101965380568256556465943774", + "1" + ], + [ + "19580431231791573486512993964860242307922354630870505256669584996531609692435", + "7570428626156808229984465454515624447295653855945859069842146889594552318297", + "1" + ], + [ + "12301872881232443435487319905131170856538368793509266093762872059382483215139", + "15394994591506901420054401439876610824678849944194343286638110806726670746776", + "1" + ], + [ + "10758954833317157157402718223866506203664092021520107027711073478816106175974", + "20515690403870892479732942990814861752434545906490365264605183518749124440633", + "1" + ], + [ + "318052593563524287039408871119299860196486584734829520369906120383637654200", + "10726977207982360528088747892914587586919766423909041551014580587700824051034", + "1" + ], + [ + "20886316910662321541601313404654680895174664909216503300631698405519252834311", + "10280964215971127045832411409270638674942403090317110657041195511012117644407", + "1" + ], + [ + "19389895982762368162390918791540582507756049726057607325582157461707544394038", + "892564819033279037177637279364073212004664284387533388527949296157162259504", + "1" + ], + [ + "17575477041383011517666197906095938506765436835373826124401810079407712752841", + "12330770229028140531700974573059843214543612937406230781778171870485982503824", + "1" + ], + [ + "17176389741526930697999869403210769944657734895796939781510893686577275816467", + "4015745410344157832141293994016606359857012673498750859656365146352221270017", + "1" + ], + [ + "10795991726546161592463943089100790191559463523422331262280784695394029539853", + "19959632337006120240497251571637627081914622058912589675598461131525950524752", + "1" + ], + [ + "17712664479778813108091436605950199003284416456214651156220144256525097971912", + "15662699700237685855397681112508272863219714064333603731780787712176355082985", + "1" + ], + [ + "6073381442968225763712210092690877545973986197161788687154396659907857263726", + "9373665933165658361382525191052152421826733302951946524585453815639530085397", + "1" + ], + [ + "7096518327234546130936330279434264058209221426446043300654825659032374885734", + "15034063797066696036452165550386252057326821558027241593290826202833402608992", + "1" + ], + [ + "3379864014621452779649753211934465514114591337174299220163148590562506138191", + "17097395067540631392076877417497702237813216875534822217360991495548732703466", + "1" + ], + [ + "19784567607350202502019588565332897449809653343063894800465186319693602827075", + "21860444017676143676333986446618134164803389891422254304347769134617193260779", + "1" + ], + [ + "20390718455309771842311699406228577961279853005550399914459606212079552071922", + "21137552439717078325510707605558742276432906378854972014069946041369373774436", + "1" + ], + [ + "16894879668774247708075375280653918036361649779256718177625607502344148833069", + "9678355058028445160691522551624063074330029275696504939931217336961048064374", + "1" + ], + [ + "8456130989924308909704121350932134594228074534874229582103470841969471058021", + "837809436038901067017521912218341562742010886029537872535247669531141354141", + "1" + ], + [ + "11959079384270025561940402116179709274046514370432877147825466754199523397143", + "4801670132379502690471403614071765949217066543646605589165661872980011500339", + "1" + ], + [ + "16696829422661816039960000803152877854021790704979714412268271066637947506695", + "16928012745842950886811965155587462907150437517308115684749563193488426663043", + "1" + ], + [ + "5308050553998100600889304964016941056436948463244143405819650069410916660408", + "16351132394820825356833852235384576073203141168226622794838691856829750851749", + "1" + ], + [ + "3699715024378460400294040015635958249712583116845259595116928313593930386828", + "16436818887958963845638448482037741322572281636522596894393350749707590362873", + "1" + ], + [ + "3286349162286118079692919216557863775580692481850163864894326200097820405756", + "13767616552687607434845739476041733966977373395063216247977194683533250854118", + "1" + ], + [ + "10643844918587577656182809271152075219741951036492351011222342110671223604076", + "17902072207646847425749244556280663155846538039933881584636993865796467561198", + "1" + ], + [ + "5241421547802225440788429589915867399146408013364605085214057386906842575530", + "2244699796970242463278868874548018295369118028491512838466674797251796801231", + "1" + ], + [ + "20830939366204663272241435813657283317648043209469932475029074277309331304719", + "19454164894454900711334487397781864303970861498974411881529471457453597046531", + "1" + ], + [ + "9774948749696285059224404866357880289461804814347165161682087575073691428645", + "14200004459632804646261103801272584400121226662767011856544576458977474967315", + "1" + ], + [ + "5961158151084398322378648559000929565533753791501123175740373315394951665784", + "9062789855398404756098089752143157365741797314052589470873316036022787669091", + "1" + ], + [ + "12361184621311843591637144342884308293273952289629467108428881025321516814085", + "13926924217686112114067773699626456526599232140284440249273387157569034465684", + "1" + ], + [ + "1718170463555167158322047912269803963985456203818145005914813025793832925928", + "10294314652669195674048313063192916244335273575406013309421049914117632258591", + "1" + ], + [ + "2728766647562382005851120046062744433203945391984640470518096807608312807393", + "11574643682911353802738742358467804331282016093308100551469778675943466877351", + "1" + ], + [ + "2312593225526865613045957416018215600627489458830988646868250509390229937885", + "9444770284692284411356829754309224182055097274337685817111810424562032921630", + "1" + ], + [ + "2911713757932870049533606429042323926308838492819742021626304869653370689588", + "20425711357199319063155646862284477975791978052195876093795393529983582682732", + "1" + ], + [ + "21332215548661793474914771184942807675542127555922505681633154782414041327543", + "12277069986288949363328617945885139619102264006931098017304728133189484345395", + "1" + ], + [ + "15468626808314655645567512551095953912747397682330538176503257372406656939230", + "21143774187870203301601568175587188641807272840775723432762135077240016288370", + "1" + ], + [ + "17866352988085548331932241913094045718055016849847613084704681243234233548989", + "10043384240187626100305111512660391577129872130367027200559190302084220933341", + "1" + ], + [ + "10369920945495888899719574693760646857027598141158330973195696890086532677793", + "19717198607887215291329801792823110840432062138896047972485456222770170436074", + "1" + ], + [ + "5580833303498204024280126966170669871310063365849390388396281599482449218956", + "13970442152817366935542314075747676776702319016401379419706030065246705296323", + "1" + ], + [ + "8702171294011663140241009227601491700997618314866754935222407071360696693143", + "1283586721071251222788457662455598626684959710797388880940014463870074231345", + "1" + ], + [ + "6354726383515865903747552194873967667669602239497754755365613044541673229135", + "11666771206689386981046314569441021765481006439719929249528721086726146251024", + "1" + ], + [ + "7304044624134625073016959366200164879235138462118353346465884318148005208452", + "18814965016249359706096642183206991810912398421641824337408323841933512071571", + "1" + ], + [ + "12681010443298513852622921567902198358091523737062777360701308967344556070900", + "20752716303491890156554878960157180689018916148405497084573683160256911467771", + "1" + ], + [ + "20950842053479965502835887656317502693249802666899820327596494012069755305189", + "8185968536955015510810760124638426335993395048697040911054623793758909716913", + "1" + ], + [ + "12844511776247886884803950969172570274716797930225844526305420951807762826834", + "16750661910928871718797292677245457802593859066887608400679826555710479643404", + "1" + ], + [ + "15347242958315504915628088037754261793868737744087157368275903229129573992271", + "13804014769033171750844953758033973846429446146296997947445711043647411830448", + "1" + ], + [ + "6277806592086692534656217975647398967821449347762297097322046918907739285579", + "13349909387200051372930219099167164525406254397065867318286239919326317478022", + "1" + ], + [ + "2446915707134644645070673386501731736539796224965699761332708791068066981496", + "7789840868788566511170606550552634120113682055363044265085385915768291613853", + "1" + ], + [ + "6077523510490289216599867456781293287986482165909915870503616800474153025150", + "20870125729933024777255147902622247081819568155317300628535981114124163154969", + "1" + ], + [ + "13347875271714976792849858321177226613605671969495982660797179126259497266113", + "16561057658613786180491387506390823411271760970345238019480798135138722771302", + "1" + ], + [ + "4611176371539926391856367617184608423345741037486676803361905920315958172762", + "11807726844513220922688821380450200503704949409911542010500453365079640295551", + "1" + ], + [ + "15875290867443079155340742251996164820309474327998519653710070401283400615181", + "18621607423025585495177586076198324942715258542651029673369379338058416566806", + "1" + ], + [ + "20516860187781438405763046979335979357827775031400389249534025413586427784431", + "7729395273395732105479942853910058917299435651927058461573332725932889995143", + "1" + ], + [ + "18129003983856167086390869063415159362494820580961273907768622167127949118358", + "14255254524041521667329551801429841887956788628159333853727242585181099521221", + "1" + ], + [ + "3719907264632641847051527557884146866661106488175908365366402407013612195451", + "11152235795513812874029815250253082326816010690681437312509855002904038402407", + "1" + ], + [ + "4313072667696549650019694568395820039784523638281643013014951776583984556529", + "2484149927913081831048762664956253229934703912890656288987153280104396064366", + "1" + ], + [ + "10307974784879764009651977110101532842624271890178401699259199664424826469418", + "14798927875667198802043595132556695721825761585490323221790715477789671693957", + "1" + ], + [ + "21493196572805173604123918884211167297502608143602917431152022941336145548971", + "14521575043395400775836322732410001591805574142533158434317443510667339551821", + "1" + ], + [ + "247959905865837624990663971761896668783383154088922485783923694177375235452", + "5638823162123714833972784102187889193293268496788712516337013031879225605963", + "1" + ], + [ + "14107388578257935466028828590494394824644004696665591427817538026382913141992", + "11335633709432241845794733360120654803703676816187244323554178741246410238914", + "1" + ], + [ + "14688301464710086543396368151803162399248978566162274505524355123915695115077", + "17340926076522969836707328956547918108757923744640977319834734007119742854715", + "1" + ], + [ + "7130749217142715604814437987245403792735311644376117400919587135178053856062", + "11625946315259186884804480328791756234364229206393720493883830823852646577352", + "1" + ], + [ + "18582284576585163573311434278349270443579180553288299798427090299437636665528", + "6558274393367263076938849655342792297279598414602027254082957418675706566432", + "1" + ], + [ + "13632040540044186822733507653938147478520889191388476078118289316896120437642", + "7212861166883342838996434212866065793257057716357780532184698945169433499596", + "1" + ], + [ + "11184494983250809306000724987292785076927513430323994224213249091648261718397", + "17146210937762865434056279774068128999807247248517653385512028295500714642841", + "1" + ], + [ + "21227328880457327183599695047226166126649751480941577471715958859395733767325", + "8991824628454001933984292590850949555801010469000773003291815386878686617161", + "1" + ], + [ + "6936134978016989909859143521948521597562557765012732373537852089157484133061", + "20642942407427533006943253155098453215344356071516032229761020247212402952764", + "1" + ], + [ + "3705047264039540543533532133836147843460769426400887545868076423140361332983", + "19282158743886368423740199478718910814131348687507229720265644463544468963603", + "1" + ], + [ + "1141981974135949858075631358253043901778549084777525516132487180424534059213", + "21885899594247424464819275113693873669091898114887188890224995635875730307744", + "1" + ], + [ + "8069474624534236414245412173808175970703365086618350532076061467121427516963", + "21331246074736881669944208250988059441369250397915991535533778200238201799083", + "1" + ], + [ + "18322179655400855892956086927591270952648426251403236475423285241075136776068", + "13655797032225994084449078116919723048350130828631156226811163595914673627438", + "1" + ], + [ + "12894357314193224900875526825984387941171759143759506397843181068804447946292", + "20006675197250894625321723402091855151064520801503391060335310710565912186379", + "1" + ], + [ + "12721895697370307148374110902302002796866624765262185938278051901510749535939", + "13601130578756397155211415731764216131718900035286619180130138410061400583009", + "1" + ], + [ + "2784545168796731639250061646866035244330982448652093671520103034699914140661", + "1626699532748248231222256160673507739230327216733314452235176764239012587244", + "1" + ], + [ + "21836910675208860153060845564894510999401426573179072539304338611430077210266", + "18424854911004869420103882207975270069687102910848814864626705581355083352811", + "1" + ] + ] +}