feat(did): add to/from public key

This commit is contained in:
Steve Moyer
2024-09-09 08:50:15 -04:00
parent 3a542ecc85
commit 2205d5d4ce
3 changed files with 85 additions and 4 deletions

39
did/crypto.go Normal file
View 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
View 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)
}

View File

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