diff --git a/did/document.go b/did/document.go index 6f5fb31..79be618 100644 --- a/did/document.go +++ b/did/document.go @@ -7,10 +7,10 @@ import ( "errors" "fmt" - "github.com/nuts-foundation/go-did" + "github.com/multiformats/go-multibase" + ssi "github.com/nuts-foundation/go-did" "github.com/lestrrat-go/jwx/jwk" - "github.com/shengdoushi/base58" "github.com/nuts-foundation/go-did/internal/marshal" ) @@ -303,11 +303,11 @@ func (s Service) UnmarshalServiceEndpoint(target interface{}) error { // VerificationMethod represents a DID Verification Method as specified by the DID Core specification (https://www.w3.org/TR/did-core/#verification-methods). type VerificationMethod struct { - ID DID `json:"id"` - Type ssi.KeyType `json:"type,omitempty"` - Controller DID `json:"controller,omitempty"` - PublicKeyBase58 string `json:"publicKeyBase58,omitempty"` - PublicKeyJwk map[string]interface{} `json:"publicKeyJwk,omitempty"` + ID DID `json:"id"` + Type ssi.KeyType `json:"type,omitempty"` + Controller DID `json:"controller,omitempty"` + PublicKeyMultibase string `json:"publicKeyMultibase,omitempty"` + PublicKeyJwk map[string]interface{} `json:"publicKeyJwk,omitempty"` } // NewVerificationMethod is a convenience method to easily create verificationMethods based on a set of given params. @@ -343,8 +343,14 @@ func NewVerificationMethod(id DID, keyType ssi.KeyType, controller DID, key cryp if !ok { return nil, errors.New("wrong key type") } - encodedKey := base58.Encode(ed25519Key, base58.BitcoinAlphabet) - vm.PublicKeyBase58 = encodedKey + + // Keep Base58 as the default encoding, but use multibase encode it + // to keep in line with the DID-core spec. + encodedKey, err := multibase.Encode(multibase.Base58BTC, ed25519Key) + if err != nil { + return nil, err + } + vm.PublicKeyMultibase = encodedKey } return vm, nil @@ -367,7 +373,7 @@ func (v VerificationMethod) PublicKey() (crypto.PublicKey, error) { var pubKey crypto.PublicKey switch v.Type { case ssi.ED25519VerificationKey2018: - keyBytes, err := base58.Decode(v.PublicKeyBase58, base58.BitcoinAlphabet) + _, keyBytes, err := multibase.Decode(v.PublicKeyMultibase) if err != nil { return nil, err } diff --git a/did/document_test.go b/did/document_test.go index 37cafc1..4df32c7 100644 --- a/did/document_test.go +++ b/did/document_test.go @@ -6,9 +6,11 @@ import ( "crypto/elliptic" "crypto/rand" "encoding/json" + "testing" + + "github.com/multiformats/go-multibase" ssi "github.com/nuts-foundation/go-did" "github.com/stretchr/testify/require" - "testing" "github.com/stretchr/testify/assert" @@ -702,3 +704,29 @@ func TestDocument_IsController(t *testing.T) { assert.False(t, Document{Controller: []DID{*id456}}.IsController(*id123)) }) } + +func TestNewVerificationMethod_Multibase(t *testing.T) { + // Prepare test data + id, _ := ParseDID("did:example:123") + keyType := ssi.ED25519VerificationKey2018 + controller, _ := ParseDID("did:example:controller") + + publicKey, _, err := ed25519.GenerateKey(nil) + assert.NoError(t, err) + // Call the function under test + verificationMethod, err := NewVerificationMethod(*id, keyType, *controller, publicKey) + assert.NoError(t, err) + + // Test whether PublicKeyMultibase is correctly encoded + if verificationMethod.PublicKeyMultibase == "" { + assert.NoError(t, err) + } + + // Decode using multibase and compare the results + decodedBase, decodedKey, err := multibase.Decode(verificationMethod.PublicKeyMultibase) + assert.NoError(t, err) + + // Check base and key + assert.Equal(t, multibase.Base58BTC, decodedBase) + assert.Equal(t, publicKey, ed25519.PublicKey(decodedKey)) +} diff --git a/did/test/did1-expected.json b/did/test/did1-expected.json index 6883fdf..edccf64 100644 --- a/did/test/did1-expected.json +++ b/did/test/did1-expected.json @@ -34,7 +34,7 @@ { "id": "did:nuts:04cf1e20-378a-4e38-ab1b-401a5018c9ff#added-assertion-method-1", "controller": "did:nuts:04cf1e20-378a-4e38-ab1b-401a5018c9ff", - "publicKeyBase58": "GGRj8PAR5tRgD5xqAhPna1bLa3UoYuxNEEhRmcYCPBm5", + "publicKeyMultibase": "z2mHtQNrd4Hjes5qXpSPvQSVprwoKSZU37UqAfkU7FRbzThiNupaGuKxCtaCPA1", "type": "Ed25519VerificationKey2018" } ], diff --git a/did/test/did1.json b/did/test/did1.json index 9aeaab7..7cbcd7c 100644 --- a/did/test/did1.json +++ b/did/test/did1.json @@ -36,7 +36,7 @@ { "id": "did:nuts:04cf1e20-378a-4e38-ab1b-401a5018c9ff#added-assertion-method-1", "controller": "did:nuts:04cf1e20-378a-4e38-ab1b-401a5018c9ff", - "publicKeyBase58": "GGRj8PAR5tRgD5xqAhPna1bLa3UoYuxNEEhRmcYCPBm5", + "publicKeyMultibase": "z2mHtQNrd4Hjes5qXpSPvQSVprwoKSZU37UqAfkU7FRbzThiNupaGuKxCtaCPA1", "type": "Ed25519VerificationKey2018" } ], diff --git a/go.mod b/go.mod index 33c4f13..f280106 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/lestrrat-go/jwx v1.2.26 - github.com/shengdoushi/base58 v1.0.0 + github.com/multiformats/go-multibase v0.2.0 github.com/stretchr/testify v1.8.4 ) @@ -17,6 +17,9 @@ require ( github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/option v1.0.1 // indirect + github.com/mr-tron/base58 v1.1.0 // indirect + github.com/multiformats/go-base32 v0.0.3 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/crypto v0.9.0 // indirect diff --git a/go.sum b/go.sum index 7646568..08331a0 100644 --- a/go.sum +++ b/go.sum @@ -19,12 +19,18 @@ github.com/lestrrat-go/jwx v1.2.26/go.mod h1:MaiCdGbn3/cckbOFSCluJlJMmp9dmZm5hDu github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= +github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/shengdoushi/base58 v1.0.0 h1:tGe4o6TmdXFJWoI31VoSWvuaKxf0Px3gqa3sUWhAxBs= -github.com/shengdoushi/base58 v1.0.0/go.mod h1:m5uIILfzcKMw6238iWAhP4l3s5+uXyF3+bJKUNhAL9I= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=