Skip to content

Commit

Permalink
fix: bjjsignature (add docProof to merklization)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pratap2018 committed Sep 27, 2024
1 parent ad30181 commit fd18495
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 8 deletions.
97 changes: 97 additions & 0 deletions x/ssi/ld-context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const X25519KeyAgreementKeyEIP5630Context string = "https://raw.githubuserconten
const CredentialStatusContext string = "https://raw.githubusercontent.com/hypersign-protocol/hypersign-contexts/main/CredentialStatus.jsonld"
const CredentialSchemaContext string = "https://raw.githubusercontent.com/hypersign-protocol/hypersign-contexts/main/CredentialSchema.jsonld"
const BabyJubJubKey2021Context string = "https://raw.githubusercontent.com/hypersign-protocol/hypersign-contexts/main/BabyJubJubKey2021.jsonld"
const BJJSignature2021Context string = "https://raw.githubusercontent.com/hypersign-protocol/hypersign-contexts/main/BJJSignature2021.jsonld"

// As hid-node is not supposed to perform any GET request, the complete Context body of their
// respective Context urls has been maintained below.
Expand Down Expand Up @@ -745,4 +746,100 @@ var ContextUrlMap map[string]contextObject = map[string]contextObject{
},
},
},

BJJSignature2021Context: {
"@version": 1.1,
"id": "@id",
"type": "@type",
"proof": map[string]interface{}{
"@id": "https://w3id.org/security#proof",
"@type": "@id",
"@container": "@graph",
},
"BJJSignature2021": map[string]interface{}{
"@id": "https://w3id.org/security#BJJSignature2021",
"@context": map[string]interface{}{
"@version": 1.1,
"@protected": true,
"id": "@id",
"type": "@type",
"challenge": "https://w3id.org/security#challenge",
"created": map[string]interface{}{
"@id": "http://purl.org/dc/terms/created",
"@type": "http://www.w3.org/2001/XMLSchema#dateTime",
},
"domain": "https://w3id.org/security#domain",
"proofValue": "https://w3id.org/security#proofValue",
"credentialRoot": "https://w3id.org/security#credentialRoot",
"nonce": "https://w3id.org/security#nonce",
"proofPurpose": map[string]interface{}{
"@id": "https://w3id.org/security#proofPurpose",
"@type": "@vocab",
"@context": map[string]interface{}{
"@version": 1.1,
"@protected": true,
"id": "@id",
"type": "@type",
"assertionMethod": map[string]interface{}{
"@id": "https://w3id.org/security#assertionMethod",
"@type": "@id",
"@container": "@set",
},
"authentication": map[string]interface{}{
"@id": "https://w3id.org/security#authenticationMethod",
"@type": "@id",
"@container": "@set",
},
},
},
"verificationMethod": map[string]interface{}{
"@id": "https://w3id.org/security#verificationMethod",
"@type": "@id",
},
},
},
"BabyJubJubSignatureProof2021": map[string]interface{}{
"@id": "https://w3id.org/security#BabyJubJubSignatureProof2021",
"@context": map[string]interface{}{
"@version": 1.1,
"@protected": true,
"id": "@id",
"type": "@type",
"challenge": "https://w3id.org/security#challenge",
"created": map[string]interface{}{
"@id": "http://purl.org/dc/terms/created",
"@type": "http://www.w3.org/2001/XMLSchema#dateTime",
},
"domain": "https://w3id.org/security#domain",
"nonce": "https://w3id.org/security#nonce",
"proofPurpose": map[string]interface{}{
"@id": "https://w3id.org/security#proofPurpose",
"@type": "@vocab",
"@context": map[string]interface{}{
"@version": 1.1,
"@protected": true,
"id": "@id",
"type": "@type",
"sec": "https://w3id.org/security#",
"assertionMethod": map[string]interface{}{
"@id": "https://w3id.org/security#assertionMethod",
"@type": "@id",
"@container": "@set",
},
"authentication": map[string]interface{}{
"@id": "https://w3id.org/security#authenticationMethod",
"@type": "@id",
"@container": "@set",
},
},
},
"proofValue": "https://w3id.org/security#proofValue",
"credentialRoot": "https://w3id.org/security#credentialRoot",
"verificationMethod": map[string]interface{}{
"@id": "https://w3id.org/security#verificationMethod",
"@type": "@id",
},
},
},
},
}
10 changes: 6 additions & 4 deletions x/ssi/ld-context/cryptosuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,23 +129,25 @@ func EcdsaSecp256k1Signature2019Normalize(ssiMsg types.SsiMsg, docProof *types.D

// BJJSignature2021Normalize performs canonization of SSI documents
// based on the spec: https://iden3-communication.io/BJJSignature2021/
func BJJSignature2021Normalize(ssiMsg types.SsiMsg) ([]byte, error) {
func BJJSignature2021Normalize(ssiMsg types.SsiMsg, docProof *types.DocumentProof) ([]byte, error) {
var jsonLDString string
switch doc := ssiMsg.(type) {
case *types.DidDocument:
jsonLDBytes, err := json.Marshal(NewJsonLdDidDocumentWithoutVM(doc))
jsonLDBytes, err := json.Marshal(NewJsonLdDidDocumentWithoutVM(doc, docProof))
if err != nil {
return nil, err
}
jsonLDString = string(jsonLDBytes)
case *types.CredentialSchemaDocument:
jsonLDBytes, err := json.Marshal(NewJsonLdCredentialSchema(doc))
credentialSchemaDocument := NewJsonLdCredentialSchemaBJJ(doc, docProof)
jsonLDBytes, err := json.Marshal(credentialSchemaDocument)
if err != nil {
return nil, err
}
jsonLDString = string(jsonLDBytes)
case *types.CredentialStatusDocument:
jsonLDBytes, err := json.Marshal(NewJsonLdCredentialStatus(doc))
credentialStatusDocument := NewJsonLdCredentialStatusBJJ(doc, docProof)
jsonLDBytes, err := json.Marshal(credentialStatusDocument)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion x/ssi/ld-context/normalize.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func NormalizeByProofType(ssiMsg types.SsiMsg, didDocumentProof *types.DocumentP
}
return msgBytes, nil
case types.BJJSignature2021:
msgBytes, err := BJJSignature2021Normalize(ssiMsg)
msgBytes, err := BJJSignature2021Normalize(ssiMsg, didDocumentProof)
if err != nil {
return nil, err
}
Expand Down
101 changes: 100 additions & 1 deletion x/ssi/ld-context/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,22 @@ func (doc *JsonLdCredentialStatus) GetContext() []contextObject {
return doc.Context
}

type JsonLdCredentialStatusBJJ struct {
Context []contextObject `json:"@context,omitempty"`
Id string `json:"id,omitempty"`
Revoked bool `json:"revoked,omitempty"`
Suspended bool `json:"suspended,omitempty"`
Remarks string `json:"remarks,omitempty"`
Issuer string `json:"issuer,omitempty"`
IssuanceDate string `json:"issuanceDate,omitempty"`
CredentialMerkleRootHash string `json:"credentialMerkleRootHash,omitempty"`
Proof JsonLdDocumentProof `json:"proof,omitempty"`
}

func (doc *JsonLdCredentialStatusBJJ) GetContext() []contextObject {
return doc.Context
}

// NewJsonLdCredentialStatus returns a new JsonLdCredentialStatus struct from input Credential Status
func NewJsonLdCredentialStatus(credStatusDoc *types.CredentialStatusDocument) *JsonLdCredentialStatus {
if len(credStatusDoc.Context) == 0 {
Expand Down Expand Up @@ -108,6 +124,37 @@ func NewJsonLdCredentialStatus(credStatusDoc *types.CredentialStatusDocument) *J
return jsonLdCredentialStatus
}

func NewJsonLdCredentialStatusBJJ(credStatusDoc *types.CredentialStatusDocument, docProof *types.DocumentProof) *JsonLdCredentialStatusBJJ {
if len(credStatusDoc.Context) == 0 {
panic("atleast one context url must be provided in the Credential Status Document for Canonization")
}

var jsonLdCredentialStatus *JsonLdCredentialStatusBJJ = &JsonLdCredentialStatusBJJ{}

for _, url := range credStatusDoc.Context {
contextObj, ok := ContextUrlMap[url]
if !ok {
panic(fmt.Sprintf("invalid or unsupported context url: %v", url))
}
jsonLdCredentialStatus.Context = append(jsonLdCredentialStatus.Context, contextObj)
}

jsonLdCredentialStatus.Id = credStatusDoc.Id
jsonLdCredentialStatus.Revoked = credStatusDoc.Revoked
jsonLdCredentialStatus.Remarks = credStatusDoc.Remarks
jsonLdCredentialStatus.Suspended = credStatusDoc.Suspended
jsonLdCredentialStatus.Issuer = credStatusDoc.Issuer
jsonLdCredentialStatus.IssuanceDate = credStatusDoc.IssuanceDate
jsonLdCredentialStatus.CredentialMerkleRootHash = credStatusDoc.CredentialMerkleRootHash

jsonLdCredentialStatus.Proof.Type = docProof.Type
jsonLdCredentialStatus.Proof.Created = docProof.Created
jsonLdCredentialStatus.Proof.ProofPurpose = docProof.ProofPurpose
jsonLdCredentialStatus.Proof.VerificationMethod = docProof.VerificationMethod

return jsonLdCredentialStatus
}

// Document Proof

type JsonLdDocumentProof struct {
Expand Down Expand Up @@ -163,6 +210,22 @@ func (doc *JsonLdCredentialSchema) GetContext() []contextObject {
return doc.Context
}

type JsonLdCredentialSchemaBJJ struct {
Context []contextObject `json:"@context,omitempty"`
Type string `json:"type,omitempty"`
ModelVersion string `json:"modelVersion,omitempty"`
Id string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Author string `json:"author,omitempty"`
Authored string `json:"authored,omitempty"`
Schema *types.CredentialSchemaProperty `json:"schema,omitempty"`
Proof JsonLdDocumentProof `json:"proof,omitempty"`
}

func (doc *JsonLdCredentialSchemaBJJ) GetContext() []contextObject {
return doc.Context
}

func NewJsonLdCredentialSchema(credSchema *types.CredentialSchemaDocument) *JsonLdCredentialSchema {
if len(credSchema.Context) == 0 {
panic("atleast one context url must be provided for DID Document for Canonization")
Expand All @@ -189,6 +252,37 @@ func NewJsonLdCredentialSchema(credSchema *types.CredentialSchemaDocument) *Json
return jsonLdDoc
}

func NewJsonLdCredentialSchemaBJJ(credSchema *types.CredentialSchemaDocument, docProof *types.DocumentProof) *JsonLdCredentialSchemaBJJ {
if len(credSchema.Context) == 0 {
panic("atleast one context url must be provided for DID Document for Canonization")
}

var jsonLdDoc *JsonLdCredentialSchemaBJJ = &JsonLdCredentialSchemaBJJ{}

for _, url := range credSchema.Context {
contextObj, ok := ContextUrlMap[url]
if !ok {
panic(fmt.Sprintf("invalid or unsupported context url: %v", url))
}
jsonLdDoc.Context = append(jsonLdDoc.Context, contextObj)
}

jsonLdDoc.Type = credSchema.Type
jsonLdDoc.ModelVersion = credSchema.ModelVersion
jsonLdDoc.Id = credSchema.Id
jsonLdDoc.Name = credSchema.Name
jsonLdDoc.Author = credSchema.Author
jsonLdDoc.Authored = credSchema.Authored
jsonLdDoc.Schema = credSchema.Schema

jsonLdDoc.Proof.Type = docProof.Type
jsonLdDoc.Proof.Created = docProof.Created
jsonLdDoc.Proof.ProofPurpose = docProof.ProofPurpose
jsonLdDoc.Proof.VerificationMethod = docProof.VerificationMethod

return jsonLdDoc
}

// It is a similar to `Did` struct, with the exception that the `context` attribute is of type
// `contextObject` instead of `[]string`, which is meant for accomodating Context JSON body
// having arbritrary attributes. It should be used for performing Canonization.
Expand All @@ -199,14 +293,15 @@ type JsonLdDidDocumentWithoutVM struct {
AlsoKnownAs []string `json:"alsoKnownAs,omitempty"`
Authentication []verificationMethodWithoutController `json:"authentication,omitempty"`
AssertionMethod []verificationMethodWithoutController `json:"assertionMethod,omitempty"`
Proof JsonLdDocumentProof `json:"proof,omitempty"`
}

func (doc *JsonLdDidDocumentWithoutVM) GetContext() []contextObject {
return doc.Context
}

// NewJsonLdDidDocument returns a new JsonLdDid struct from input Did
func NewJsonLdDidDocumentWithoutVM(didDoc *types.DidDocument) *JsonLdDidDocumentWithoutVM {
func NewJsonLdDidDocumentWithoutVM(didDoc *types.DidDocument, docProof *types.DocumentProof) *JsonLdDidDocumentWithoutVM {
if len(didDoc.Context) == 0 {
panic("atleast one context url must be provided for DID Document for Canonization")
}
Expand Down Expand Up @@ -252,6 +347,10 @@ func NewJsonLdDidDocumentWithoutVM(didDoc *types.DidDocument) *JsonLdDidDocument
}
}

jsonLdDoc.Proof.Type = docProof.Type
jsonLdDoc.Proof.Created = docProof.Created
jsonLdDoc.Proof.ProofPurpose = docProof.ProofPurpose
jsonLdDoc.Proof.VerificationMethod = docProof.VerificationMethod + docProof.ProofPurpose
return jsonLdDoc
}

Expand Down
4 changes: 2 additions & 2 deletions x/ssi/tests/crypto/signature.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package crypto

import (
ldcontext "github.com/hypersign-protocol/hid-node/x/ssi/ld-context"
cli "github.com/hypersign-protocol/hid-node/x/ssi/client/cli"
ldcontext "github.com/hypersign-protocol/hid-node/x/ssi/ld-context"
"github.com/hypersign-protocol/hid-node/x/ssi/types"
)

Expand Down Expand Up @@ -70,7 +70,7 @@ func GetDocumentSignature(doc types.SsiMsg, docProof *types.DocumentProof, priva
}
case types.BJJSignature2021:
var docBytes []byte
docBytes, err := ldcontext.BJJSignature2021Normalize(doc)
docBytes, err := ldcontext.BJJSignature2021Normalize(doc, docProof)
if err != nil {
return "", err
}
Expand Down

0 comments on commit fd18495

Please sign in to comment.