134 lines
2.6 KiB
Go
134 lines
2.6 KiB
Go
package crypto
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/agl/ed25519"
|
|
extra "github.com/agl/ed25519/extra25519"
|
|
proto "github.com/gogo/protobuf/proto"
|
|
pb "github.com/libp2p/go-libp2p-crypto/pb"
|
|
)
|
|
|
|
type Ed25519PrivateKey struct {
|
|
sk *[64]byte
|
|
pk *[32]byte
|
|
}
|
|
|
|
type Ed25519PublicKey struct {
|
|
k *[32]byte
|
|
}
|
|
|
|
func GenerateEd25519Key(src io.Reader) (PrivKey, PubKey, error) {
|
|
pub, priv, err := ed25519.GenerateKey(src)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
return &Ed25519PrivateKey{
|
|
sk: priv,
|
|
pk: pub,
|
|
},
|
|
&Ed25519PublicKey{
|
|
k: pub,
|
|
},
|
|
nil
|
|
}
|
|
|
|
func (k *Ed25519PrivateKey) Bytes() ([]byte, error) {
|
|
pbmes := new(pb.PrivateKey)
|
|
typ := pb.KeyType_Ed25519
|
|
pbmes.Type = &typ
|
|
|
|
buf := make([]byte, 96)
|
|
copy(buf, k.sk[:])
|
|
copy(buf[64:], k.pk[:])
|
|
pbmes.Data = buf
|
|
return proto.Marshal(pbmes)
|
|
}
|
|
|
|
func (k *Ed25519PrivateKey) Equals(o Key) bool {
|
|
edk, ok := o.(*Ed25519PrivateKey)
|
|
if !ok {
|
|
return false
|
|
}
|
|
|
|
return bytes.Equal((*k.sk)[:], (*edk.sk)[:]) && bytes.Equal((*k.pk)[:], (*edk.pk)[:])
|
|
}
|
|
|
|
func (k *Ed25519PrivateKey) GetPublic() PubKey {
|
|
return &Ed25519PublicKey{k.pk}
|
|
}
|
|
|
|
func (k *Ed25519PrivateKey) Sign(msg []byte) ([]byte, error) {
|
|
out := ed25519.Sign(k.sk, msg)
|
|
return (*out)[:], nil
|
|
}
|
|
|
|
func (k *Ed25519PrivateKey) ToCurve25519() *[32]byte {
|
|
var sk [32]byte
|
|
extra.PrivateKeyToCurve25519(&sk, k.sk)
|
|
return &sk
|
|
}
|
|
|
|
func (k *Ed25519PublicKey) Bytes() ([]byte, error) {
|
|
pbmes := new(pb.PublicKey)
|
|
typ := pb.KeyType_Ed25519
|
|
pbmes.Type = &typ
|
|
pbmes.Data = (*k.k)[:]
|
|
return proto.Marshal(pbmes)
|
|
}
|
|
|
|
func (k *Ed25519PublicKey) Equals(o Key) bool {
|
|
edk, ok := o.(*Ed25519PublicKey)
|
|
if !ok {
|
|
return false
|
|
}
|
|
|
|
return bytes.Equal((*k.k)[:], (*edk.k)[:])
|
|
}
|
|
|
|
func (k *Ed25519PublicKey) Verify(data []byte, sig []byte) (bool, error) {
|
|
var asig [64]byte
|
|
copy(asig[:], sig)
|
|
return ed25519.Verify(k.k, data, &asig), nil
|
|
}
|
|
|
|
func (k *Ed25519PublicKey) ToCurve25519() (*[32]byte, error) {
|
|
var pk [32]byte
|
|
success := extra.PublicKeyToCurve25519(&pk, k.k)
|
|
if !success {
|
|
return nil, fmt.Errorf("Error converting ed25519 pubkey to curve25519 pubkey")
|
|
}
|
|
return &pk, nil
|
|
}
|
|
|
|
func UnmarshalEd25519PublicKey(data []byte) (PubKey, error) {
|
|
if len(data) != 32 {
|
|
return nil, fmt.Errorf("expect ed25519 public key data size to be 32")
|
|
}
|
|
|
|
var pub [32]byte
|
|
copy(pub[:], data)
|
|
|
|
return &Ed25519PublicKey{
|
|
k: &pub,
|
|
}, nil
|
|
}
|
|
|
|
func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) {
|
|
if len(data) != 96 {
|
|
return nil, fmt.Errorf("expected ed25519 data size to be 96")
|
|
}
|
|
var priv [64]byte
|
|
var pub [32]byte
|
|
copy(priv[:], data)
|
|
copy(pub[:], data[64:])
|
|
|
|
return &Ed25519PrivateKey{
|
|
sk: &priv,
|
|
pk: &pub,
|
|
}, nil
|
|
}
|