Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/value arr size input #69

Merged
merged 16 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 58 additions & 53 deletions auth_test.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ 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.2-0.20240131165639-deb061a1b3e6
github.com/iden3/go-circuits/v2 v2.1.0
github.com/iden3/go-iden3-core/v2 v2.0.3
github.com/iden3/go-iden3-crypto v0.0.15
github.com/iden3/go-jwz/v2 v2.0.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ 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.2-0.20240131165639-deb061a1b3e6 h1:DoyzPqOZWkUBGAQc2UQbddWAD3HYF5QX1zP9b+KmSH8=
github.com/iden3/go-circuits/v2 v2.0.2-0.20240131165639-deb061a1b3e6/go.mod h1:VIFIp51+IH0hOzjnKhb84bCeyq7hq76zX/C14ua6zh4=
github.com/iden3/go-circuits/v2 v2.1.0 h1:Dk+noXGXOJYFjj2iWu3KLPd/KLoIhZ3eT6qYEfKyocc=
github.com/iden3/go-circuits/v2 v2.1.0/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=
Expand Down
2 changes: 1 addition & 1 deletion pubsignals/atomicMtpV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (c *AtomicQueryMTPV2) VerifyQuery(
IsRevocationChecked: c.IsRevocationChecked,
}

err := query.Check(ctx, schemaLoader, &pubSig, verifiablePresentation, false, opts...)
err := query.Check(ctx, schemaLoader, &pubSig, verifiablePresentation, circuits.AtomicQueryMTPV2CircuitID, opts...)
return CircuitVerificationResult{}, err
}

Expand Down
3 changes: 1 addition & 2 deletions pubsignals/atomicSigV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ func (c *AtomicQuerySigV2) VerifyQuery(
Merklized: c.Merklized,
ClaimPathKey: c.ClaimPathKey,
ClaimPathNotExists: c.ClaimPathNotExists,
ValueArraySize: c.ValueArraySize,
IsRevocationChecked: c.IsRevocationChecked,
}
err := query.Check(ctx, schemaLoader, &pubSig, verifiablePresentation, false, opts...)
err := query.Check(ctx, schemaLoader, &pubSig, verifiablePresentation, circuits.AtomicQuerySigV2CircuitID, opts...)
return CircuitVerificationResult{}, err
}

Expand Down
5 changes: 2 additions & 3 deletions pubsignals/atomicV3.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ func (c *AtomicQueryV3) VerifyQuery(
Timestamp: c.Timestamp,
Merklized: c.Merklized,
ClaimPathKey: c.ClaimPathKey,
ClaimPathNotExists: c.ClaimPathNotExists,
ValueArraySize: c.ValueArraySize,
ValueArraySize: c.ActualValueArraySize,
IsRevocationChecked: c.IsRevocationChecked,
// V3 NEW
LinkID: c.LinkID,
Expand All @@ -52,7 +51,7 @@ func (c *AtomicQueryV3) VerifyQuery(
Nullifier: c.Nullifier,
ProofType: c.ProofType,
}
err := query.Check(ctx, schemaLoader, &pubSig, verifiablePresentation, true, opts...)
err := query.Check(ctx, schemaLoader, &pubSig, verifiablePresentation, circuits.AtomicQueryV3CircuitID, opts...)
if err != nil {
return output, err
}
Expand Down
129 changes: 114 additions & 15 deletions pubsignals/common.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package pubsignals

import (
"bytes"
"context"
"encoding/json"
"fmt"
"math/big"
"strconv"

"github.com/iden3/go-circuits/v2"
"github.com/iden3/go-iden3-crypto/poseidon"
Expand Down Expand Up @@ -52,6 +54,14 @@ func ParseCredentialSubject(_ context.Context, credentialSubject any) (out []Pro
if !ok {
return nil, errors.New("Failed to convert credential subject to JSONObject")
}
if len(jsonObject) == 0 {
return []PropertyQuery{
{
Operator: circuits.NOOP,
FieldName: "",
},
}, nil
}

for fieldName, fieldReq := range jsonObject {
fieldReqEntries, ok := fieldReq.(map[string]interface{})
Expand Down Expand Up @@ -79,21 +89,24 @@ func ParseCredentialSubject(_ context.Context, credentialSubject any) (out []Pro

// ParseQueryMetadata parse property query and return query metadata
func ParseQueryMetadata(ctx context.Context, propertyQuery PropertyQuery, ldContextJSON, credentialType string, options merklize.Options) (query *QueryMetadata, err error) {
datatype, err := options.TypeFromContext([]byte(ldContextJSON), fmt.Sprintf("%s.%s", credentialType, propertyQuery.FieldName))
if err != nil {
return nil, err
}

query = &QueryMetadata{
PropertyQuery: propertyQuery,
SlotIndex: 0,
MerklizedSchema: false,
Datatype: datatype,
Datatype: "",
ClaimPathKey: big.NewInt(0),
Values: []*big.Int{},
Path: &merklize.Path{},
}

if query.FieldName != "" {
query.Datatype, err = options.TypeFromContext([]byte(ldContextJSON), fmt.Sprintf("%s.%s", credentialType, propertyQuery.FieldName))
if err != nil {
return nil, err
}
}

var ctxObj map[string]interface{}
err = json.Unmarshal([]byte(ldContextJSON), &ctxObj)
if err != nil {
Expand Down Expand Up @@ -139,14 +152,17 @@ func ParseQueryMetadata(ctx context.Context, propertyQuery PropertyQuery, ldCont
query.Path = &path
}

if propertyQuery.OperatorValue != nil {
if !IsValidOperation(datatype, propertyQuery.Operator) {
if propertyQuery.OperatorValue != nil && query.Datatype != "" {
if !IsValidOperation(query.Datatype, propertyQuery.Operator) {
operatorName, _ := getKeyByValue(circuits.QueryOperators, propertyQuery.Operator)
return nil, fmt.Errorf("invalid operation '%s' for field type '%s'", operatorName, datatype)
return nil, fmt.Errorf("invalid operation '%s' for field type '%s'", operatorName, query.Datatype)
}
}

query.Values, err = transformQueryValueToBigInts(ctx, propertyQuery.OperatorValue, datatype)
if propertyQuery.Operator == circuits.EXISTS {
query.Values, err = transformQueryValueToBigInts(ctx, propertyQuery.OperatorValue, ld.XSDBoolean) // TODO: refactor
} else {
query.Values, err = transformQueryValueToBigInts(ctx, propertyQuery.OperatorValue, query.Datatype)
}
if err != nil {
return nil, err
}
Expand All @@ -155,7 +171,7 @@ func ParseQueryMetadata(ctx context.Context, propertyQuery PropertyQuery, ldCont
}

// ParseQueriesMetadata parse credential subject and return array of query metadata
func ParseQueriesMetadata(ctx context.Context, credentialType, ldContextJSON string, credentialSubject any, options merklize.Options) (out []QueryMetadata, err error) {
func ParseQueriesMetadata(ctx context.Context, credentialType, ldContextJSON string, credentialSubject map[string]interface{}, options merklize.Options) (out []QueryMetadata, err error) {
queriesMetadata, err := ParseCredentialSubject(ctx, credentialSubject)
if err != nil {
return nil, err
Expand All @@ -172,8 +188,12 @@ func ParseQueriesMetadata(ctx context.Context, credentialType, ldContextJSON str
}

func transformQueryValueToBigInts(_ context.Context, value any, ldType string) (out []*big.Int, err error) {
if ldType == "" {
return []*big.Int{}, nil
}

if value == nil {
return out, nil
return make([]*big.Int, 0), nil
}

listOfValues, ok := value.([]interface{})
Expand Down Expand Up @@ -201,6 +221,33 @@ func transformQueryValueToBigInts(_ context.Context, value any, ldType string) (
return []*big.Int{hashValue}, err
}

func isPositiveInteger(v interface{}) bool {
number, err := strconv.ParseFloat(fmt.Sprintf("%v", v), 64)
if err != nil {
// value is not a number
return true
}
return number >= 0
}

// IsValidOperation checks if operation and type are supported.
func IsValidOperation(typ string, op int) bool {
if op == circuits.NOOP {
return true
}

ops, ok := availableTypesOperations[typ]
if !ok {
// by default all unknown types will be considered as string
ops = availableTypesOperations[ld.XSDString]
_, ok = ops[op]
return ok
}

_, ok = ops[op]
return ok
}

func getKeyByValue(m map[string]int, targetValue int) (string, bool) {
for key, value := range m {
if value == targetValue {
Expand All @@ -217,7 +264,14 @@ func CalculateQueryHash(
slotIndex int,
operator int,
claimPathKey *big.Int,
claimPathNotExists *big.Int) (*big.Int, error) {
isMerklized bool,
) (*big.Int, error) {
merklized := big.NewInt(0)
if isMerklized {
merklized.SetInt64(1)
}

valArrSize := big.NewInt(int64(len(values)))
circuitValues, err := circuits.PrepareCircuitArrayValues(values, 64)
if err != nil {
return nil, err
Expand All @@ -227,13 +281,58 @@ func CalculateQueryHash(
if err != nil {
return nil, err
}
return poseidon.Hash([]*big.Int{
firstPart, err := poseidon.Hash([]*big.Int{
schemaHash,
big.NewInt(int64(slotIndex)),
big.NewInt(int64(operator)),
claimPathKey,
claimPathNotExists,
merklized,
valueHash,
})
if err != nil {
return nil, err
}
return poseidon.Hash([]*big.Int{
firstPart,
valArrSize,
big.NewInt(0),
big.NewInt(0),
big.NewInt(0),
big.NewInt(0),
})

}

func fieldValueFromVerifiablePresentation(ctx context.Context, verifiablePresentation json.RawMessage, schemaLoader ld.DocumentLoader, key string) (*big.Int, error) {
if verifiablePresentation == nil {
return nil, errors.New("selective disclosure value is missed")
}

mz, err := merklize.MerklizeJSONLD(ctx,
bytes.NewBuffer(verifiablePresentation),
merklize.WithDocumentLoader(schemaLoader))
if err != nil {
return nil, errors.Errorf("failed to merklize doc: %v", err)
}

merklizedPath, err := merklize.Options{DocumentLoader: schemaLoader}.
NewPathFromDocument(verifiablePresentation,
fmt.Sprintf("verifiableCredential.credentialSubject.%s", key))
if err != nil {
return nil, errors.Errorf("failed build path to '%s' key: %v", key, err)
}

proof, valueByPath, err := mz.Proof(ctx, merklizedPath)
if err != nil {
return nil, errors.Errorf("failed get raw value: %v", err)
}
if !proof.Existence {
return nil, errors.Errorf("path '%v' doesn't exist in document", merklizedPath.Parts())
}

mvBig, err := valueByPath.MtEntry()
if err != nil {
return nil, errors.Errorf("failed to hash value: %v", err)
}
return mvBig, nil
}
Loading
Loading