diff --git a/resources/go-did concepts.png b/resources/go-did concepts.png index ea6b0e1..77addda 100644 Binary files a/resources/go-did concepts.png and b/resources/go-did concepts.png differ diff --git a/verifications/ed25519/VerificationKey2020.go b/verifications/ed25519/VerificationKey2020.go index 0328694..39815a4 100644 --- a/verifications/ed25519/VerificationKey2020.go +++ b/verifications/ed25519/VerificationKey2020.go @@ -2,14 +2,10 @@ package ed25519 import ( "crypto/ed25519" - "crypto/rand" "encoding/json" "errors" "fmt" - mbase "github.com/multiformats/go-multibase" - "github.com/multiformats/go-varint" - "github.com/INFURA/go-did" ) @@ -102,45 +98,3 @@ func (v VerificationKey2020) JsonLdContext() string { func (v VerificationKey2020) Verify(data []byte, sig []byte) bool { return ed25519.Verify(v.pubkey, data, sig) } - -// PublicKeyToMultibase encodes the public key in a suitable way for publicKeyMultibase -func PublicKeyToMultibase(pub PublicKey) string { - // can only fail with an invalid encoding, but it's hardcoded - bytes, _ := mbase.Encode(mbase.Base58BTC, append(varint.ToUvarint(MultibaseCode), pub...)) - return bytes -} - -// MultibaseToPublicKey decodes the public key from its publicKeyMultibase form -func MultibaseToPublicKey(multibase string) (PublicKey, error) { - baseCodec, bytes, err := mbase.Decode(multibase) - if err != nil { - return nil, err - } - // the specification enforces that encoding - if baseCodec != mbase.Base58BTC { - return nil, fmt.Errorf("not Base58BTC encoded") - } - code, read, err := varint.FromUvarint(bytes) - if err != nil { - return nil, err - } - if code != MultibaseCode { - return nil, fmt.Errorf("invalid code") - } - if read != 2 { - return nil, fmt.Errorf("unexpected multibase") - } - if len(bytes)-read != ed25519.PublicKeySize { - return nil, fmt.Errorf("invalid ed25519 public key size") - } - return bytes[read:], nil -} - -// ------------ - -type PublicKey = ed25519.PublicKey -type PrivateKey = ed25519.PrivateKey - -func GenerateKeyPair() (PublicKey, PrivateKey, error) { - return ed25519.GenerateKey(rand.Reader) -} diff --git a/verifications/ed25519/key.go b/verifications/ed25519/key.go new file mode 100644 index 0000000..e02ecd8 --- /dev/null +++ b/verifications/ed25519/key.go @@ -0,0 +1,50 @@ +package ed25519 + +import ( + "crypto/ed25519" + "crypto/rand" + "fmt" + + mbase "github.com/multiformats/go-multibase" + "github.com/multiformats/go-varint" +) + +type PublicKey = ed25519.PublicKey +type PrivateKey = ed25519.PrivateKey + +func GenerateKeyPair() (PublicKey, PrivateKey, error) { + return ed25519.GenerateKey(rand.Reader) +} + +// PublicKeyToMultibase encodes the public key in a suitable way for publicKeyMultibase +func PublicKeyToMultibase(pub PublicKey) string { + // can only fail with an invalid encoding, but it's hardcoded + bytes, _ := mbase.Encode(mbase.Base58BTC, append(varint.ToUvarint(MultibaseCode), pub...)) + return bytes +} + +// MultibaseToPublicKey decodes the public key from its publicKeyMultibase form +func MultibaseToPublicKey(multibase string) (PublicKey, error) { + baseCodec, bytes, err := mbase.Decode(multibase) + if err != nil { + return nil, err + } + // the specification enforces that encoding + if baseCodec != mbase.Base58BTC { + return nil, fmt.Errorf("not Base58BTC encoded") + } + code, read, err := varint.FromUvarint(bytes) + if err != nil { + return nil, err + } + if code != MultibaseCode { + return nil, fmt.Errorf("invalid code") + } + if read != 2 { + return nil, fmt.Errorf("unexpected multibase") + } + if len(bytes)-read != ed25519.PublicKeySize { + return nil, fmt.Errorf("invalid ed25519 public key size") + } + return bytes[read:], nil +} diff --git a/verifications/x25519/key.go b/verifications/x25519/key.go index e13c1ca..cb34c3d 100644 --- a/verifications/x25519/key.go +++ b/verifications/x25519/key.go @@ -12,8 +12,8 @@ import ( "github.com/INFURA/go-did/verifications/ed25519" ) -// This mirrors ed25519's structure for private/public "keys". jwx -// requires dedicated types for these as they drive +// This mirrors ed25519's structure for private/public "keys". We +// require dedicated types for these as they drive // serialization/deserialization logic, as well as encryption types. // // Note that with the x25519 scheme, the private key is a sequence of @@ -37,37 +37,6 @@ const ( // PublicKey is the type of X25519 public keys type PublicKey []byte -// Any methods implemented on PublicKey might need to also be implemented on -// PrivateKey, as the latter embeds the former and will expose its methods. - -// Equal reports whether pub and x have the same value. -func (pub PublicKey) Equal(x crypto.PublicKey) bool { - xx, ok := x.(PublicKey) - if !ok { - return false - } - return bytes.Equal(pub, xx) -} - -// PrivateKey is the type of X25519 private key -type PrivateKey []byte - -// Public returns the PublicKey corresponding to priv. -func (priv PrivateKey) Public() crypto.PublicKey { - publicKey := make([]byte, PublicKeySize) - copy(publicKey, priv[SeedSize:]) - return PublicKey(publicKey) -} - -// Equal reports whether priv and x have the same value. -func (priv PrivateKey) Equal(x crypto.PrivateKey) bool { - xx, ok := x.(PrivateKey) - if !ok { - return false - } - return bytes.Equal(priv, xx) -} - // NewKeyFromSeed calculates a private key from a seed. It will return // an error if len(seed) is not SeedSize. This function is provided // for interoperability with RFC 7748. RFC 7748's private keys @@ -105,6 +74,37 @@ func GenerateKey() (PublicKey, PrivateKey, error) { return publicKey, privateKey, nil } +// Any methods implemented on PublicKey might need to also be implemented on +// PrivateKey, as the latter embeds the former and will expose its methods. + +// Equal reports whether pub and x have the same value. +func (pub PublicKey) Equal(x crypto.PublicKey) bool { + xx, ok := x.(PublicKey) + if !ok { + return false + } + return bytes.Equal(pub, xx) +} + +// PrivateKey is the type of X25519 private key +type PrivateKey []byte + +// Public returns the PublicKey corresponding to priv. +func (priv PrivateKey) Public() crypto.PublicKey { + publicKey := make([]byte, PublicKeySize) + copy(publicKey, priv[SeedSize:]) + return PublicKey(publicKey) +} + +// Equal reports whether priv and x have the same value. +func (priv PrivateKey) Equal(x crypto.PrivateKey) bool { + xx, ok := x.(PrivateKey) + if !ok { + return false + } + return bytes.Equal(priv, xx) +} + func PublicKeyFromEd25519(pub ed25519.PublicKey) (PublicKey, error) { // x, _ := curve25519.X25519(pub, curve25519.Basepoint) publicKey := make([]byte, PublicKeySize)