feat(did): add to/from public key
This commit is contained in:
39
did/crypto.go
Normal file
39
did/crypto.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package did
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
crypto "github.com/libp2p/go-libp2p/core/crypto"
|
||||
"github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
"github.com/multiformats/go-multicodec"
|
||||
"github.com/multiformats/go-varint"
|
||||
)
|
||||
|
||||
func FromPrivKey(privKey crypto.PrivKey) (DID, error) {
|
||||
return FromPubKey(privKey.GetPublic())
|
||||
}
|
||||
|
||||
func FromPubKey(pubKey crypto.PubKey) (DID, error) {
|
||||
code, ok := map[pb.KeyType]multicodec.Code{
|
||||
pb.KeyType_Ed25519: multicodec.Ed25519Pub,
|
||||
pb.KeyType_RSA: multicodec.RsaPub,
|
||||
pb.KeyType_Secp256k1: multicodec.Secp256k1Pub,
|
||||
pb.KeyType_ECDSA: multicodec.Es256,
|
||||
}[pubKey.Type()]
|
||||
if !ok {
|
||||
return Undef, errors.New("Blah")
|
||||
}
|
||||
|
||||
buf := varint.ToUvarint(uint64(code))
|
||||
|
||||
pubBytes, err := pubKey.Raw()
|
||||
if err != nil {
|
||||
return Undef, err
|
||||
}
|
||||
|
||||
return DID{
|
||||
str: string(append(buf, pubBytes...)),
|
||||
code: uint64(code),
|
||||
key: true,
|
||||
}, nil
|
||||
}
|
||||
33
did/crypto_test.go
Normal file
33
did/crypto_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package did_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/crypto"
|
||||
"github.com/multiformats/go-multicodec"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/ucan-wg/go-ucan/v1/did"
|
||||
)
|
||||
|
||||
func TestFromPubKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const example = "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
|
||||
|
||||
id, err := did.Parse(example)
|
||||
require.NoError(t, err)
|
||||
|
||||
buf := bytes.NewBuffer(id.Bytes())
|
||||
|
||||
code, err := binary.ReadUvarint(buf)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint64(multicodec.Ed25519Pub), code)
|
||||
|
||||
pubKey, err := crypto.UnmarshalEd25519PublicKey(buf.Bytes())
|
||||
require.NoError(t, err)
|
||||
|
||||
id2, err := did.FromPubKey(pubKey)
|
||||
require.Equal(t, id, id2)
|
||||
}
|
||||
13
did/did.go
13
did/did.go
@@ -5,6 +5,7 @@ import (
|
||||
"strings"
|
||||
|
||||
mbase "github.com/multiformats/go-multibase"
|
||||
"github.com/multiformats/go-multicodec"
|
||||
varint "github.com/multiformats/go-varint"
|
||||
)
|
||||
|
||||
@@ -13,11 +14,15 @@ const KeyPrefix = "did:key:"
|
||||
|
||||
const DIDCore = 0x0d1d
|
||||
const Ed25519 = 0xed
|
||||
const RSA = uint64(multicodec.RsaPub)
|
||||
|
||||
var MethodOffset = varint.UvarintSize(uint64(DIDCore))
|
||||
|
||||
//
|
||||
// [did:key format]: https://w3c-ccg.github.io/did-method-key/
|
||||
type DID struct {
|
||||
key bool
|
||||
code uint64
|
||||
str string
|
||||
}
|
||||
|
||||
@@ -36,6 +41,10 @@ func (d DID) Bytes() []byte {
|
||||
return []byte(d.str)
|
||||
}
|
||||
|
||||
func (d DID) Code() uint64 {
|
||||
return d.code
|
||||
}
|
||||
|
||||
func (d DID) DID() DID {
|
||||
return d
|
||||
}
|
||||
@@ -54,8 +63,8 @@ func Decode(bytes []byte) (DID, error) {
|
||||
if err != nil {
|
||||
return Undef, err
|
||||
}
|
||||
if code == Ed25519 {
|
||||
return DID{str: string(bytes), key: true}, nil
|
||||
if code == Ed25519 || code == RSA {
|
||||
return DID{str: string(bytes), code: code, key: true}, nil
|
||||
} else if code == DIDCore {
|
||||
return DID{str: string(bytes)}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user