Skip to content

Commit

Permalink
Merge pull request #391 from hypersign-protocol/bjj-ed255
Browse files Browse the repository at this point in the history
Multiple KeyPair support   in didDocument , Service type restriction removed
  • Loading branch information
Pratap2018 authored Oct 3, 2024
2 parents d21d04c + d9574b1 commit 6bdcbc6
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 42 deletions.
20 changes: 20 additions & 0 deletions x/ssi/ld-context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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",
},
},
},
},
}
39 changes: 30 additions & 9 deletions x/ssi/ld-context/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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{}

Expand All @@ -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
}

Expand Down
186 changes: 185 additions & 1 deletion x/ssi/tests/verification_method_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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})
Expand Down Expand Up @@ -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()
}

}
6 changes: 3 additions & 3 deletions x/ssi/types/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
53 changes: 24 additions & 29 deletions x/ssi/types/diddoc_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}

0 comments on commit 6bdcbc6

Please sign in to comment.