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

Support for V3 circuits #45

Merged
merged 6 commits into from
Nov 30, 2023
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
22 changes: 22 additions & 0 deletions cmd/polygonid/polygonid.go
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,28 @@ func PLGNAtomicQueryMtpV2OnChainInputs(jsonResponse **C.char, in *C.char,
jsonResponse, in, cfg, status)
}

// PLGNAtomicQueryV3Inputs returns the inputs for the credentialAtomicQueryV3
// circuit with optional selective disclosure.
//
//export PLGNAtomicQueryV3Inputs
func PLGNAtomicQueryV3Inputs(jsonResponse **C.char, in *C.char,
cfg *C.char, status **C.PLGNStatus) bool {

return prepareInputs(c_polygonid.AtomicQueryV3InputsFromJson, jsonResponse,
in, cfg, status)
}

// PLGNAtomicQueryV3OnChainInputs returns the inputs for the
// credentialAtomicQueryV3OnChain circuit with optional selective disclosure.
//
//export PLGNAtomicQueryV3OnChainInputs
func PLGNAtomicQueryV3OnChainInputs(jsonResponse **C.char, in *C.char,
cfg *C.char, status **C.PLGNStatus) bool {

return prepareInputs(c_polygonid.AtomicQueryV3OnChainInputsFromJson,
jsonResponse, in, cfg, status)
}

//export PLGNFreeStatus
func PLGNFreeStatus(status *C.PLGNStatus) {
if status == nil {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/ethereum/go-ethereum v1.12.0
github.com/iden3/contracts-abi/onchain-credential-status-resolver/go/abi v0.0.0-20230911113809-c58b7e7a69b0
github.com/iden3/contracts-abi/state/go/abi v0.0.0-20230405152923-4a25f6f1f0f4
github.com/iden3/go-circuits/v2 v2.0.0
github.com/iden3/go-circuits/v2 v2.0.1-0.20231121174851-c7d45cd9baec
github.com/iden3/go-iden3-core/v2 v2.0.0
github.com/iden3/go-iden3-crypto v0.0.15
github.com/iden3/go-merkletree-sql/v2 v2.0.6
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ github.com/iden3/contracts-abi/onchain-credential-status-resolver/go/abi v0.0.0-
github.com/iden3/contracts-abi/onchain-credential-status-resolver/go/abi v0.0.0-20230911113809-c58b7e7a69b0/go.mod h1:8fkd2xyUG/V7ovpvZRyD2LyK2zZ4ALbgf5vJGyhzKdg=
github.com/iden3/contracts-abi/state/go/abi v0.0.0-20230405152923-4a25f6f1f0f4 h1:iPvYa/AhhGo3juoUFDm/fBE2CZKy4WfQu7JY90tRf9Q=
github.com/iden3/contracts-abi/state/go/abi v0.0.0-20230405152923-4a25f6f1f0f4/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-circuits/v2 v2.0.1-0.20231121174851-c7d45cd9baec h1:ORXPivdUzGKSOkunZPtv9Gm+O6II7zpb/sRDJJ4C7Yc=
github.com/iden3/go-circuits/v2 v2.0.1-0.20231121174851-c7d45cd9baec/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-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4=
Expand Down
249 changes: 245 additions & 4 deletions inputs_sig.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ func resolveRevocationStatusFromIssuerService(ctx context.Context,
return out, nil
}

type errProofNotFound verifiable.ProofType

func (e errProofNotFound) Error() string {
return fmt.Sprintf("proof not found: %v", string(e))
}

func claimWithSigProofFromObj(ctx context.Context, cfg EnvConfig,
w3cCred verifiable.W3CCredential,
skipClaimRevocationCheck bool) (circuits.ClaimWithSigProof, error) {
Expand All @@ -200,8 +206,7 @@ func claimWithSigProofFromObj(ctx context.Context, cfg EnvConfig,

proofI := findProofByType(w3cCred, verifiable.BJJSignatureProofType)
if proofI == nil {
return out, fmt.Errorf("no %v proofs found",
verifiable.BJJSignatureProofType)
return out, errProofNotFound(verifiable.BJJSignatureProofType)
}

var err error
Expand Down Expand Up @@ -759,6 +764,179 @@ func AtomicQuerySigV2OnChainInputsFromJson(ctx context.Context, cfg EnvConfig,
return out, nil
}

func AtomicQueryV3OnChainInputsFromJson(ctx context.Context, cfg EnvConfig,
in []byte) (AtomicQueryInputsResponse, error) {

var out AtomicQueryInputsResponse
var inpMarsh circuits.AtomicQueryV3OnChainInputs

var obj onChainInputsRequest
err := json.Unmarshal(in, &obj)
if err != nil {
return out, err
}

inpMarsh.RequestID, err = bigIntByPath(obj.Request, "id", true)
if err != nil {
return out, err
}

if obj.ID == nil {
return out, errors.New(`"id" field is required`)
}

inpMarsh.ID = obj.ID
inpMarsh.ProfileNonce = obj.ProfileNonce.BigInt()
inpMarsh.ClaimSubjectProfileNonce = obj.ClaimSubjectProfileNonce.BigInt()

inpMarsh.AuthClaim = obj.AuthClaim
inpMarsh.AuthClaimIncMtp = obj.AuthClaimIncMtp
inpMarsh.AuthClaimNonRevMtp = obj.AuthClaimNonRevMtp

if obj.TreeState == nil {
return out, errors.New("treeState is required")
}
inpMarsh.TreeState = *obj.TreeState

if obj.GistProof == nil {
return out, errors.New("gistProof is required")
}
inpMarsh.GISTProof = *obj.GistProof

inpMarsh.Signature = (*babyjub.Signature)(obj.Signature)
inpMarsh.Challenge = obj.Challenge.BigInt()

circuitID, err := stringByPath(obj.Request, "circuitId")
if err != nil {
return out, err
}
if circuitID != string(circuits.AtomicQueryV3OnChainCircuitID) {
return out, errors.New("wrong circuit")
}
var w3cCred verifiable.W3CCredential
err = json.Unmarshal(obj.VerifiableCredentials, &w3cCred)
if err != nil {
return out, err
}

inpMarsh.SkipClaimRevocationCheck, err = querySkipRevocation(obj.Request)
if err != nil {
return out, err
}

reqProofType, err := queryProofType(obj.Request)
if err != nil {
return out, err
}

inpMarsh.Claim, inpMarsh.ProofType, err = claimWithSigAndMtpProofFromObj(
ctx, cfg, w3cCred, inpMarsh.SkipClaimRevocationCheck, reqProofType)
if err != nil {
return out, err
}

inpMarsh.Query, out.VerifiablePresentation, err = queryFromObj(ctx, w3cCred,
obj.Request, inpMarsh.Claim.Claim, cfg.documentLoader())
if err != nil {
return out, err
}

inpMarsh.CurrentTimeStamp = time.Now().Unix()

out.Inputs = inpMarsh

return out, nil
}

func AtomicQueryV3InputsFromJson(ctx context.Context, cfg EnvConfig,
in []byte) (AtomicQueryInputsResponse, error) {

var out AtomicQueryInputsResponse
var inpMarsh circuits.AtomicQueryV3Inputs

var obj inputsRequest
err := json.Unmarshal(in, &obj)
if err != nil {
return out, err
}

inpMarsh.RequestID, err = bigIntByPath(obj.Request, "id", true)
if err != nil {
return out, err
}
inpMarsh.ID = &obj.ID
inpMarsh.ProfileNonce = obj.ProfileNonce.BigInt()
inpMarsh.ClaimSubjectProfileNonce = obj.ClaimSubjectProfileNonce.BigInt()

circuitID, err := stringByPath(obj.Request, "circuitId")
if err != nil {
return out, err
}
if circuitID != string(circuits.AtomicQueryV3CircuitID) {
return out, errors.New("wrong circuit")
}
var w3cCred verifiable.W3CCredential
err = json.Unmarshal(obj.VerifiableCredentials, &w3cCred)
if err != nil {
return out, err
}

inpMarsh.SkipClaimRevocationCheck, err = querySkipRevocation(obj.Request)
if err != nil {
return out, err
}

reqProofType, err := queryProofType(obj.Request)
if err != nil {
return out, err
}

inpMarsh.Claim, inpMarsh.ProofType, err = claimWithSigAndMtpProofFromObj(
ctx, cfg, w3cCred, inpMarsh.SkipClaimRevocationCheck, reqProofType)
if err != nil {
return out, err
}

inpMarsh.Query, out.VerifiablePresentation, err = queryFromObj(ctx, w3cCred,
obj.Request, inpMarsh.Claim.Claim, cfg.documentLoader())
if err != nil {
return out, err
}

inpMarsh.CurrentTimeStamp = time.Now().Unix()

// TODO: what to do with LinkNonce, VerifierID, VerifierSessionID

out.Inputs = inpMarsh

return out, nil
}

// return empty circuits.ProofType if not found
func queryProofType(requestObj jsonObj) (circuits.ProofType, error) {
result, err := getByPath(requestObj, "query.proofType")
if errors.As(err, &errPathNotFound{}) {
return "", nil
}
if err != nil {
return "", err
}

resS, ok := result.(string)
if !ok {
return "", errors.New("value of proofType is not string")
}

switch circuits.ProofType(resS) {
case circuits.Iden3SparseMerkleTreeProofType:
return circuits.Iden3SparseMerkleTreeProofType, nil
case circuits.BJJSignatureProofType:
return circuits.BJJSignatureProofType, nil
}
return "", fmt.Errorf("unknown proofType: %v", resS)

}

func buildQueryPath(ctx context.Context, contextURL string, contextType string,
field string,
documentLoader ld.DocumentLoader) (path merklize.Path, err error) {
Expand Down Expand Up @@ -1145,8 +1323,7 @@ func claimWithMtpProofFromObj(ctx context.Context, cfg EnvConfig,
} else if proofI = findProofByType(w3cCred, verifiable.ProofType(verifiable.Iden3OnchainSparseMerkleTreeProof2023)); proofI != nil {

} else {
return out, fmt.Errorf("no %v proofs found",
verifiable.Iden3SparseMerkleTreeProofType)
return out, errProofNotFound(verifiable.Iden3SparseMerkleTreeProofType)
}

issuerID, err := core.IDFromDID(*issuerDID)
Expand Down Expand Up @@ -1174,6 +1351,70 @@ func claimWithMtpProofFromObj(ctx context.Context, cfg EnvConfig,
return out, nil
}

func v3ProofFromMTP(
p circuits.ClaimWithMTPProof) circuits.ClaimWithSigAndMTPProof {
return circuits.ClaimWithSigAndMTPProof{
IssuerID: p.IssuerID,
Claim: p.Claim,
NonRevProof: p.NonRevProof,
IncProof: &p.IncProof,
}
}

func v3ProofFromSig(p circuits.ClaimWithSigProof) circuits.ClaimWithSigAndMTPProof {
return circuits.ClaimWithSigAndMTPProof{
IssuerID: p.IssuerID,
Claim: p.Claim,
NonRevProof: p.NonRevProof,
SignatureProof: &p.SignatureProof,
}

}

func claimWithSigAndMtpProofFromObj(ctx context.Context, cfg EnvConfig,
w3cCred verifiable.W3CCredential, skipClaimRevocationCheck bool,
proofType circuits.ProofType) (circuits.ClaimWithSigAndMTPProof, circuits.ProofType, error) {

switch proofType {
case circuits.Iden3SparseMerkleTreeProofType:
claimWithMtpProof, err := claimWithMtpProofFromObj(ctx, cfg, w3cCred,
skipClaimRevocationCheck)
if err != nil {
return circuits.ClaimWithSigAndMTPProof{}, proofType, err
}
return v3ProofFromMTP(claimWithMtpProof), proofType, nil
case circuits.BJJSignatureProofType:
claimWithSigProof, err := claimWithSigProofFromObj(ctx, cfg, w3cCred,
skipClaimRevocationCheck)
if err != nil {
return circuits.ClaimWithSigAndMTPProof{}, proofType, err
}
return v3ProofFromSig(claimWithSigProof), proofType, nil
case "":
claimWithMtpProof, err := claimWithMtpProofFromObj(ctx, cfg, w3cCred,
skipClaimRevocationCheck)
var tErr errProofNotFound
switch {
case errors.As(err, &tErr):
claimWithSigProof, err := claimWithSigProofFromObj(ctx, cfg,
w3cCred, skipClaimRevocationCheck)
if err != nil {
return circuits.ClaimWithSigAndMTPProof{}, proofType, err
}
return v3ProofFromSig(claimWithSigProof),
circuits.BJJSignatureProofType, nil
case err != nil:
return circuits.ClaimWithSigAndMTPProof{}, proofType, err
}

return v3ProofFromMTP(claimWithMtpProof),
circuits.Iden3SparseMerkleTreeProofType, nil
default:
return circuits.ClaimWithSigAndMTPProof{}, proofType,
fmt.Errorf("unknown proofType: %v", proofType)
}
}

func circuitsTreeStateFromSchemaState(
state verifiable.State) (ts circuits.TreeState, err error) {

Expand Down
Loading
Loading