diff --git a/x/ssi/ld-context/context.go b/x/ssi/ld-context/context.go index 5d5b35f..f828255 100644 --- a/x/ssi/ld-context/context.go +++ b/x/ssi/ld-context/context.go @@ -11,6 +11,7 @@ const CredentialStatusContext string = "https://raw.githubusercontent.com/hypers 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. @@ -842,4 +843,23 @@ var ContextUrlMap map[string]contextObject = map[string]contextObject{ }, }, }, + 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/types.go b/x/ssi/ld-context/types.go index e4f1fd8..5c4a816 100644 --- a/x/ssi/ld-context/types.go +++ b/x/ssi/ld-context/types.go @@ -287,13 +287,17 @@ func NewJsonLdCredentialSchemaBJJ(credSchema *types.CredentialSchemaDocument, do // `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"` - Proof JsonLdDocumentProof `json:"proof,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 { @@ -318,8 +322,6 @@ func NewJsonLdDidDocumentWithoutVM(didDoc *types.DidDocument, docProof *types.Do 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{} @@ -345,12 +347,31 @@ func NewJsonLdDidDocumentWithoutVM(didDoc *types.DidDocument, docProof *types.Do 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/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 }