diff --git a/README.md b/README.md index 1e77e3d..8be4d79 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The Hypersign Identity Network is a permissionless blockchain network to manage - Stake `$HID` tokens - Submit Governance Proposals - Transfer `$HID` tokens within and across different Tendermint-based blockchains using IBC -- Deploy CosmWasm Smart Contracts (Governance Based) +- Deploy CosmWasm Smart Contracts ## Prerequisite diff --git a/cmd/hid-noded/cmd/debug_extensions_utils.go b/cmd/hid-noded/cmd/debug_extensions_utils.go index febde80..58295cb 100644 --- a/cmd/hid-noded/cmd/debug_extensions_utils.go +++ b/cmd/hid-noded/cmd/debug_extensions_utils.go @@ -84,7 +84,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 } diff --git a/x/ssi/ld-context/context.go b/x/ssi/ld-context/context.go index f41ee33..f828255 100644 --- a/x/ssi/ld-context/context.go +++ b/x/ssi/ld-context/context.go @@ -10,6 +10,8 @@ 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" +const LinkedDomainsContext string = "https://raw.githubusercontent.com/hypersign-protocol/hypersign-contexts/main/LinkedDomains.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. @@ -745,4 +747,119 @@ 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", + }, + }, + }, + }, + LinkedDomainsContext: { + + "@protected": true, + "id": "@id", + "type": "@type", + "LinkedDomains": map[string]interface{}{ + "@id": "https://www.w3.org/ns/did#LinkedDomains", + "@type": "@id", + "@context": map[string]interface{}{ + "@protected": true, + "id": "@id", + "type": "@type", + "serviceEndpoint": map[string]interface{}{ + "@id": "https://www.w3.org/ns/did#serviceEndpoint", + "@type": "@id", + }, + }, + }, + }, } diff --git a/x/ssi/ld-context/cryptosuite.go b/x/ssi/ld-context/cryptosuite.go index 79f039b..b2cfd1d 100644 --- a/x/ssi/ld-context/cryptosuite.go +++ b/x/ssi/ld-context/cryptosuite.go @@ -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 } diff --git a/x/ssi/ld-context/normalize.go b/x/ssi/ld-context/normalize.go index 5d8ee53..9e6fb42 100644 --- a/x/ssi/ld-context/normalize.go +++ b/x/ssi/ld-context/normalize.go @@ -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 } diff --git a/x/ssi/ld-context/types.go b/x/ssi/ld-context/types.go index 7fbbd25..5c4a816 100644 --- a/x/ssi/ld-context/types.go +++ b/x/ssi/ld-context/types.go @@ -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 { @@ -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 { @@ -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") @@ -189,16 +252,52 @@ 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. type JsonLdDidDocumentWithoutVM struct { - Context []contextObject `json:"@context,omitempty"` - Id string `json:"id,omitempty"` - Controller []string `json:"controller,omitempty"` - AlsoKnownAs []string `json:"alsoKnownAs,omitempty"` - Authentication []verificationMethodWithoutController `json:"authentication,omitempty"` - AssertionMethod []verificationMethodWithoutController `json:"assertionMethod,omitempty"` + Context []contextObject `json:"@context,omitempty"` + Id string `json:"id,omitempty"` + Controller []string `json:"controller,omitempty"` + // AlsoKnownAs []string `json:"alsoKnownAs,omitempty"` + Authentication []verificationMethodWithoutController `json:"authentication,omitempty"` + AssertionMethod []verificationMethodWithoutController `json:"assertionMethod,omitempty"` + CapabilityDelegation []verificationMethodWithoutController `json:"capabilityDelegation,omitempty"` + CapabilityInvocation []verificationMethodWithoutController `json:"capabilityInvocation,omitempty"` + KeyAgreement []verificationMethodWithoutController `json:"keyAgreement,omitempty"` + Proof JsonLdDocumentProof `json:"proof,omitempty"` + Service []*types.Service `protobuf:"bytes,11,rep,name=service,proto3" json:"service,omitempty"` } func (doc *JsonLdDidDocumentWithoutVM) GetContext() []contextObject { @@ -206,7 +305,7 @@ func (doc *JsonLdDidDocumentWithoutVM) GetContext() []contextObject { } // 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") } @@ -223,8 +322,6 @@ func NewJsonLdDidDocumentWithoutVM(didDoc *types.DidDocument) *JsonLdDidDocument jsonLdDoc.Id = didDoc.Id jsonLdDoc.Controller = didDoc.Controller - jsonLdDoc.AlsoKnownAs = didDoc.AlsoKnownAs - // Replace verification method ids with their corresponding Verification Method object var vmMap map[string]verificationMethodWithoutController = map[string]verificationMethodWithoutController{} @@ -250,8 +347,31 @@ func NewJsonLdDidDocumentWithoutVM(didDoc *types.DidDocument) *JsonLdDidDocument jsonLdDoc.AssertionMethod = append(jsonLdDoc.AssertionMethod, vmObj) jsonLdDoc.AssertionMethod[len(jsonLdDoc.AssertionMethod)-1].Id = jsonLdDoc.AssertionMethod[len(jsonLdDoc.AssertionMethod)-1].Id + "assertionMethod" } + + for _, vmId := range didDoc.CapabilityDelegation { + vmObj := vmMap[vmId] + jsonLdDoc.CapabilityDelegation = append(jsonLdDoc.CapabilityDelegation, vmObj) + jsonLdDoc.CapabilityDelegation[len(jsonLdDoc.CapabilityDelegation)-1].Id = jsonLdDoc.CapabilityDelegation[len(jsonLdDoc.CapabilityDelegation)-1].Id + "capabilityDelegation" + } + + for _, vmId := range didDoc.CapabilityInvocation { + vmObj := vmMap[vmId] + jsonLdDoc.CapabilityInvocation = append(jsonLdDoc.CapabilityInvocation, vmObj) + jsonLdDoc.CapabilityInvocation[len(jsonLdDoc.CapabilityInvocation)-1].Id = jsonLdDoc.CapabilityInvocation[len(jsonLdDoc.CapabilityInvocation)-1].Id + "capabilityInvocation" + } + + for _, vmId := range didDoc.KeyAgreement { + vmObj := vmMap[vmId] + jsonLdDoc.KeyAgreement = append(jsonLdDoc.KeyAgreement, vmObj) + jsonLdDoc.KeyAgreement[len(jsonLdDoc.KeyAgreement)-1].Id = jsonLdDoc.KeyAgreement[len(jsonLdDoc.KeyAgreement)-1].Id + "keyAgreement" + } } + jsonLdDoc.Proof.Type = docProof.Type + jsonLdDoc.Proof.Created = docProof.Created + jsonLdDoc.Proof.ProofPurpose = docProof.ProofPurpose + jsonLdDoc.Proof.VerificationMethod = docProof.VerificationMethod + docProof.ProofPurpose + jsonLdDoc.Service = didDoc.Service return jsonLdDoc } diff --git a/x/ssi/tests/crypto/signature.go b/x/ssi/tests/crypto/signature.go index 361dff7..e70368c 100644 --- a/x/ssi/tests/crypto/signature.go +++ b/x/ssi/tests/crypto/signature.go @@ -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" ) @@ -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 } diff --git a/x/ssi/tests/ssi/credential_schema.go b/x/ssi/tests/ssi/credential_schema.go index fee604e..e7f5c1a 100644 --- a/x/ssi/tests/ssi/credential_schema.go +++ b/x/ssi/tests/ssi/credential_schema.go @@ -12,12 +12,11 @@ import ( func GenerateSchema(keyPair testcrypto.IKeyPair, authorId string) *types.CredentialSchemaDocument { var schemaId = "sch:" + testconstants.DidMethod + ":" + testconstants.ChainNamespace + ":" + strings.Split(authorId, ":")[3] + ":" + "1.0" - var vmContextUrl = GetContextFromKeyPair(keyPair) + var vmContextUrls = GetContextFromKeyPair(keyPair) var credentialSchema *types.CredentialSchemaDocument = &types.CredentialSchemaDocument{ - Context: []string{ + Context: []string{ ldcontext.CredentialSchemaContext, - vmContextUrl, }, Type: "https://w3c-ccg.github.io/vc-json-schemas/v1/schema/1.0/schema.json", ModelVersion: "1.0", @@ -34,6 +33,7 @@ func GenerateSchema(keyPair testcrypto.IKeyPair, authorId string) *types.Credent AdditionalProperties: false, }, } + credentialSchema.Context = append(credentialSchema.Context, vmContextUrls...) return credentialSchema } diff --git a/x/ssi/tests/ssi/credential_status.go b/x/ssi/tests/ssi/credential_status.go index 8b295ef..7423b74 100644 --- a/x/ssi/tests/ssi/credential_status.go +++ b/x/ssi/tests/ssi/credential_status.go @@ -14,12 +14,11 @@ import ( func GenerateCredentialStatus(keyPair testcrypto.IKeyPair, issuerId string) *types.CredentialStatusDocument { var credentialId = "vc:" + testconstants.DidMethod + ":" + testconstants.ChainNamespace + ":" + strings.Split(issuerId, ":")[3] var credHash = sha256.Sum256([]byte("Hash1234")) - var vmContextUrl = GetContextFromKeyPair(keyPair) + var vmContextUrls = GetContextFromKeyPair(keyPair) var credentialStatus *types.CredentialStatusDocument = &types.CredentialStatusDocument{ Context: []string{ ldcontext.CredentialStatusContext, - vmContextUrl, }, Id: credentialId, Remarks: "Live", @@ -29,6 +28,7 @@ func GenerateCredentialStatus(keyPair testcrypto.IKeyPair, issuerId string) *typ IssuanceDate: "2022-04-10T04:07:12Z", CredentialMerkleRootHash: hex.EncodeToString(credHash[:]), } + credentialStatus.Context = append(credentialStatus.Context, vmContextUrls...) return credentialStatus } diff --git a/x/ssi/tests/ssi/did_document.go b/x/ssi/tests/ssi/did_document.go index a8aa980..2df6360 100644 --- a/x/ssi/tests/ssi/did_document.go +++ b/x/ssi/tests/ssi/did_document.go @@ -3,7 +3,7 @@ package ssi import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/hypersign-protocol/hid-node/x/ssi/keeper" - + testconstants "github.com/hypersign-protocol/hid-node/x/ssi/tests/constants" testcrypto "github.com/hypersign-protocol/hid-node/x/ssi/tests/crypto" "github.com/hypersign-protocol/hid-node/x/ssi/types" @@ -83,7 +83,7 @@ func GenerateDidDoc(keyPair testcrypto.IKeyPair) *types.DidDocument { var verificationMethodId string = didId + "#" + "key-1" - var vmType string = keyPair.GetType() + var vmType string = keyPair.GetType() var vm = &types.VerificationMethod{ Id: verificationMethodId, @@ -101,12 +101,11 @@ func GenerateDidDoc(keyPair testcrypto.IKeyPair) *types.DidDocument { vm.BlockchainAccountId = "cosmos:prajna:" + optionalID } } - - vmContextUrl := GetContextFromKeyPair(keyPair) + + vmContextUrls := GetContextFromKeyPair(keyPair) var didDocument *types.DidDocument = &types.DidDocument{ Context: []string{ "https://www.w3.org/ns/did/v1", - vmContextUrl, }, Id: didId, Controller: []string{}, @@ -114,7 +113,7 @@ func GenerateDidDoc(keyPair testcrypto.IKeyPair) *types.DidDocument { vm, }, } - + didDocument.Context = append(didDocument.Context, vmContextUrls...) return didDocument } diff --git a/x/ssi/tests/ssi/utils.go b/x/ssi/tests/ssi/utils.go index 0d4199d..3aa7604 100644 --- a/x/ssi/tests/ssi/utils.go +++ b/x/ssi/tests/ssi/utils.go @@ -5,18 +5,18 @@ import ( testcrypto "github.com/hypersign-protocol/hid-node/x/ssi/tests/crypto" ) -func GetContextFromKeyPair(kp testcrypto.IKeyPair) string { +func GetContextFromKeyPair(kp testcrypto.IKeyPair) []string { switch kp.(type) { case *testcrypto.Ed25519KeyPair: - return ldcontext.Ed25519Context2020 + return []string{ldcontext.Ed25519Context2020} case *testcrypto.Secp256k1Pair: - return ldcontext.Secp256k12019Context + return []string{ldcontext.Secp256k12019Context} case *testcrypto.Secp256k1RecoveryPair: - return ldcontext.Secp256k1Recovery2020Context + return []string{ldcontext.Secp256k1Recovery2020Context} case *testcrypto.BabyJubJubKeyPair: - return ldcontext.BabyJubJubKey2021Context + return []string{ldcontext.BabyJubJubKey2021Context, ldcontext.BJJSignature2021Context} case *testcrypto.BbsBlsKeyPair: - return ldcontext.BbsSignature2020Context + return []string{ldcontext.BbsSignature2020Context} default: panic("Unsupported IKeyPair type") } diff --git a/x/ssi/tests/verification_method_test.go b/x/ssi/tests/verification_method_test.go index a1cda72..ec9eafd 100644 --- a/x/ssi/tests/verification_method_test.go +++ b/x/ssi/tests/verification_method_test.go @@ -5,6 +5,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/hypersign-protocol/hid-node/x/ssi/keeper" + ldcontext "github.com/hypersign-protocol/hid-node/x/ssi/ld-context" + "github.com/hypersign-protocol/hid-node/x/ssi/types" testcrypto "github.com/hypersign-protocol/hid-node/x/ssi/tests/crypto" testssi "github.com/hypersign-protocol/hid-node/x/ssi/tests/ssi" @@ -24,7 +26,11 @@ func TestEcdsaSecp256k1VerificationKey2019(t *testing.T) { alice_didDoc := testssi.GenerateDidDoc(alice_kp) alice_didDoc.Controller = append(alice_didDoc.Controller, alice_didDoc.Id) - + var service types.Service + service.Id = alice_didDoc.Id + "#ServiceType" + service.Type = "ServiceType" + service.ServiceEndpoint = "https://example.com" + alice_didDoc.Service = append(alice_didDoc.Service, &service) alice_kp.VerificationMethodId = alice_didDoc.VerificationMethod[0].Id didDocTx := testssi.GetRegisterDidDocumentRPC(alice_didDoc, []testcrypto.IKeyPair{alice_kp}) @@ -240,3 +246,181 @@ func TestBbsBls(t *testing.T) { t.FailNow() } } + +func TestBJJAndEd25519(t *testing.T) { + k, ctx := TestKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + goCtx := sdk.WrapSDKContext(ctx) + + alice_kp := testcrypto.GenerateBabyJubJubKeyPair() + + t.Log("Register DID Document BJJ,Ed25519 Keys") + + alice_didDoc := testssi.GenerateDidDoc(alice_kp) + alice_didDoc.Controller = append(alice_didDoc.Controller, alice_didDoc.Id) + alice_kp.VerificationMethodId = alice_didDoc.VerificationMethod[0].Id + + bob_kp := testcrypto.GenerateEd25519KeyPair() + bob_kp.VerificationMethodId = alice_didDoc.Id + "#key-2" + + var vm types.VerificationMethod + vm.Id = alice_didDoc.Id + "#key-2" + vm.Controller = alice_didDoc.Id + vm.Type = bob_kp.Type + vm.PublicKeyMultibase = bob_kp.PublicKey + alice_didDoc.CapabilityDelegation = []string{} + alice_didDoc.CapabilityInvocation = []string{} + alice_didDoc.AlsoKnownAs = []string{} + + alice_didDoc.AssertionMethod = append(alice_didDoc.AssertionMethod, alice_didDoc.Id+"#key-2") + alice_didDoc.Authentication = append(alice_didDoc.Authentication, alice_didDoc.Id+"#key-2") + + alice_didDoc.VerificationMethod = append(alice_didDoc.VerificationMethod, &vm) + context25519 := testssi.GetContextFromKeyPair(bob_kp) + alice_didDoc.Context = append(alice_didDoc.Context, context25519...) + didDocTx := testssi.GetRegisterDidDocumentRPC(alice_didDoc, []testcrypto.IKeyPair{bob_kp, alice_kp}) + _, err := msgServer.RegisterDID(goCtx, didDocTx) + if err != nil { + t.Log(err) + t.FailNow() + } + + didDocFromState := testssi.QueryDid(k, ctx, alice_didDoc.Id) + t.Log("Did from state", didDocFromState) +} + +func TestEd25519AndBJJ(t *testing.T) { + k, ctx := TestKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + goCtx := sdk.WrapSDKContext(ctx) + + alice_kp := testcrypto.GenerateEd25519KeyPair() + + t.Log("Register DID Document Ed25519,BJJ Keys") + + alice_didDoc := testssi.GenerateDidDoc(alice_kp) + alice_didDoc.Controller = append(alice_didDoc.Controller, alice_didDoc.Id) + + alice_kp.VerificationMethodId = alice_didDoc.VerificationMethod[0].Id + bob_kp := testcrypto.GenerateBabyJubJubKeyPair() + bob_kp.VerificationMethodId = alice_didDoc.Id + "#key-2" + + var vm types.VerificationMethod + vm.Id = alice_didDoc.Id + "#key-2" + vm.Controller = alice_didDoc.Id + vm.Type = bob_kp.Type + vm.PublicKeyMultibase = bob_kp.PublicKey + alice_didDoc.CapabilityDelegation = []string{} + alice_didDoc.CapabilityInvocation = []string{} + alice_didDoc.AlsoKnownAs = []string{} + + alice_didDoc.AssertionMethod = append(alice_didDoc.AssertionMethod, alice_didDoc.Id+"#key-2") + alice_didDoc.Authentication = append(alice_didDoc.Authentication, alice_didDoc.Id+"#key-2") + + alice_didDoc.VerificationMethod = append(alice_didDoc.VerificationMethod, &vm) + bjjContext := testssi.GetContextFromKeyPair(bob_kp) + alice_didDoc.Context = append(alice_didDoc.Context, bjjContext...) + didDocTx := testssi.GetRegisterDidDocumentRPC(alice_didDoc, []testcrypto.IKeyPair{bob_kp, alice_kp}) + _, err := msgServer.RegisterDID(goCtx, didDocTx) + if err != nil { + t.Log(err) + t.FailNow() + } + + didDocFromState := testssi.QueryDid(k, ctx, alice_didDoc.Id) + t.Log("Did from state", didDocFromState) +} + +func TestBJJAndEd25519WithService(t *testing.T) { + k, ctx := TestKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + goCtx := sdk.WrapSDKContext(ctx) + + alice_kp := testcrypto.GenerateBabyJubJubKeyPair() + + t.Log("Register DID Document BJJ,Ed25519 Keys and With Service attached") + + alice_didDoc := testssi.GenerateDidDoc(alice_kp) + alice_didDoc.Controller = append(alice_didDoc.Controller, alice_didDoc.Id) + + var service types.Service + service.Id = alice_didDoc.Id + "#ServiceTypeAny" + service.Type = "LinkedDomains" + service.ServiceEndpoint = "https://example.com" + alice_didDoc.Service = append(alice_didDoc.Service, &service) + + alice_kp.VerificationMethodId = alice_didDoc.VerificationMethod[0].Id + + bob_kp := testcrypto.GenerateEd25519KeyPair() + bob_kp.VerificationMethodId = alice_didDoc.Id + "#key-2" + + var vm types.VerificationMethod + vm.Id = alice_didDoc.Id + "#key-2" + vm.Controller = alice_didDoc.Id + vm.Type = bob_kp.Type + vm.PublicKeyMultibase = bob_kp.PublicKey + alice_didDoc.CapabilityDelegation = []string{} + alice_didDoc.CapabilityInvocation = []string{} + alice_didDoc.AlsoKnownAs = []string{} + + alice_didDoc.AssertionMethod = append(alice_didDoc.AssertionMethod, alice_didDoc.Id+"#key-2") + alice_didDoc.Authentication = append(alice_didDoc.Authentication, alice_didDoc.Id+"#key-2") + + alice_didDoc.VerificationMethod = append(alice_didDoc.VerificationMethod, &vm) + context25519 := testssi.GetContextFromKeyPair(bob_kp) + alice_didDoc.Context = append(alice_didDoc.Context, context25519...) + alice_didDoc.Context = append(alice_didDoc.Context, ldcontext.LinkedDomainsContext) + didDocTx := testssi.GetRegisterDidDocumentRPC(alice_didDoc, []testcrypto.IKeyPair{bob_kp, alice_kp}) + _, err := msgServer.RegisterDID(goCtx, didDocTx) + if err != nil { + t.Log(err) + t.FailNow() + } + +} +func TestEd25519AndBJJWithService(t *testing.T) { + k, ctx := TestKeeper(t) + msgServer := keeper.NewMsgServerImpl(*k) + goCtx := sdk.WrapSDKContext(ctx) + + alice_kp := testcrypto.GenerateEd25519KeyPair() + + t.Log("Register DID Document Ed25519,BJJ Keys and With Service attached") + + alice_didDoc := testssi.GenerateDidDoc(alice_kp) + alice_didDoc.Controller = append(alice_didDoc.Controller, alice_didDoc.Id) + + alice_kp.VerificationMethodId = alice_didDoc.VerificationMethod[0].Id + var service types.Service + service.Id = alice_didDoc.Id + "#ServiceType" + service.Type = "LinkedDomains" + service.ServiceEndpoint = "https://example.com" + alice_didDoc.Service = append(alice_didDoc.Service, &service) + + bob_kp := testcrypto.GenerateBabyJubJubKeyPair() + bob_kp.VerificationMethodId = alice_didDoc.Id + "#key-2" + + var vm types.VerificationMethod + vm.Id = alice_didDoc.Id + "#key-2" + vm.Controller = alice_didDoc.Id + vm.Type = bob_kp.Type + vm.PublicKeyMultibase = bob_kp.PublicKey + alice_didDoc.CapabilityDelegation = []string{} + alice_didDoc.CapabilityInvocation = []string{} + alice_didDoc.AlsoKnownAs = []string{} + + alice_didDoc.AssertionMethod = append(alice_didDoc.AssertionMethod, alice_didDoc.Id+"#key-2") + alice_didDoc.Authentication = append(alice_didDoc.Authentication, alice_didDoc.Id+"#key-2") + + alice_didDoc.VerificationMethod = append(alice_didDoc.VerificationMethod, &vm) + bjjContext := testssi.GetContextFromKeyPair(bob_kp) + alice_didDoc.Context = append(alice_didDoc.Context, bjjContext...) + alice_didDoc.Context = append(alice_didDoc.Context, ldcontext.LinkedDomainsContext) + didDocTx := testssi.GetRegisterDidDocumentRPC(alice_didDoc, []testcrypto.IKeyPair{bob_kp, alice_kp}) + _, err := msgServer.RegisterDID(goCtx, didDocTx) + if err != nil { + t.Log(err) + t.FailNow() + } + +} diff --git a/x/ssi/types/common.go b/x/ssi/types/common.go index 41ff7a2..c3cdeff 100644 --- a/x/ssi/types/common.go +++ b/x/ssi/types/common.go @@ -42,9 +42,9 @@ var supportedVerificationMethodTypes []string = func() []string { }() // Supported Service Types -var SupportedServiceTypes = []string{ - "LinkedDomains", -} +// var SupportedServiceTypes = []string{ +// "LinkedDomains", +// } // Did Document ID const DocumentIdentifierDid = "did" diff --git a/x/ssi/types/diddoc_validation.go b/x/ssi/types/diddoc_validation.go index d27f3bd..f88b12a 100644 --- a/x/ssi/types/diddoc_validation.go +++ b/x/ssi/types/diddoc_validation.go @@ -228,15 +228,15 @@ func validateServices(services []*Service) error { } // validate service Type - foundType := false - for _, sType := range SupportedServiceTypes { - if service.Type == sType { - foundType = true - } - } - if !foundType { - return fmt.Errorf("service Type %s is Invalid", service.Type) - } + // foundType := false + // for _, sType := range SupportedServiceTypes { + // if service.Type == sType { + // foundType = true + // } + // } + // if !foundType { + // return fmt.Errorf("service Type %s is Invalid", service.Type) + // } } // check if any duplicate service id exists @@ -417,24 +417,24 @@ func validateBlockchainAccountId(blockchainAccountId string) error { } // isBabyJubJubKey2021PresentAlongWithOtherVMTypes checks if both BabyJubJubKey2021 and other VM Types are present at once -func isBabyJubJubKey2021PresentAlongWithOtherVMTypes(verificationMethods []*VerificationMethod) error { - babyJubJubKey2021Count := 0 - nonBabyJubJubKey2021Count := 0 +// func isBabyJubJubKey2021PresentAlongWithOtherVMTypes(verificationMethods []*VerificationMethod) error { +// babyJubJubKey2021Count := 0 +// nonBabyJubJubKey2021Count := 0 - for _, vm := range verificationMethods { - if vm.Type == BabyJubJubKey2021 { - babyJubJubKey2021Count += 1 - } else { - nonBabyJubJubKey2021Count += 1 - } - } +// for _, vm := range verificationMethods { +// if vm.Type == BabyJubJubKey2021 { +// babyJubJubKey2021Count += 1 +// } else { +// nonBabyJubJubKey2021Count += 1 +// } +// } - if babyJubJubKey2021Count > 0 && nonBabyJubJubKey2021Count > 0 { - return fmt.Errorf("BabyJubJubKey2021 should not be paired with other VM types in a single DID Document") - } +// if babyJubJubKey2021Count > 0 && nonBabyJubJubKey2021Count > 0 { +// return fmt.Errorf("BabyJubJubKey2021 should not be paired with other VM types in a single DID Document") +// } - return nil -} +// return nil +// } // ValidateDidDocument validates the DID Document func (didDoc *DidDocument) ValidateDidDocument() error { @@ -470,10 +470,5 @@ func (didDoc *DidDocument) ValidateDidDocument() error { return err } - // TODO: This is a temporary measure due to technical challenges in merklizing DID Document - if err := isBabyJubJubKey2021PresentAlongWithOtherVMTypes(didDoc.VerificationMethod); err != nil { - return err - } - return nil }