func WriteSignedObject(w io.Writer, obj interface{}, sk SecretKey) error {
	objBytes := encoding.Marshal(obj)
	sig := SignHash(HashBytes(objBytes), sk)
	return encoding.NewEncoder(w).EncodeAll(sig, objBytes)
}
WriteSignedObject writes a length-prefixed object prefixed by its signature.
package crypto
import (
	"bytes"
	"errors"
	"io"
	"github.com/NebulousLabs/Sia/encoding"
	"github.com/NebulousLabs/fastrand"
	"golang.org/x/crypto/ed25519"
)
const (
	EntropySize = 32
	PublicKeySize = ed25519.PublicKeySize
	SecretKeySize = ed25519.PrivateKeySize
	SignatureSize = ed25519.SignatureSize
)
var (
	ErrInvalidSignature = errors.New("invalid signature")
)
type (
	PublicKey [PublicKeySize]byte
	SecretKey [SecretKeySize]byte
	Signature [SignatureSize]byte
)
func (sk SecretKey) PublicKey() (pk PublicKey) {
	copy(pk[:], sk[SecretKeySize-PublicKeySize:])
	return
}
func GenerateKeyPair() (sk SecretKey, pk PublicKey) {
	epk, esk, _ := ed25519.GenerateKey(fastrand.Reader)
	copy(sk[:], esk)
	copy(pk[:], epk)
	return
}
func GenerateKeyPairDeterministic(entropy [EntropySize]byte) (sk SecretKey, pk PublicKey) {
	epk, esk, _ := ed25519.GenerateKey(bytes.NewReader(entropy[:]))
	copy(sk[:], esk)
	copy(pk[:], epk)
	return
}
func ReadSignedObject(r io.Reader, obj interface{}, maxLen uint64, pk PublicKey) error {
	var sig Signature
	err := encoding.NewDecoder(r).Decode(&sig)
	if err != nil {
		return err
	}
	encObj, err := encoding.ReadPrefixedBytes(r, maxLen)
	if err != nil {
		return err
	}
	if err := VerifyHash(HashBytes(encObj), pk, sig); err != nil {
		return err
	}
	return encoding.Unmarshal(encObj, obj)
}
func SignHash(data Hash, sk SecretKey) (sig Signature) {
	copy(sig[:], ed25519.Sign(sk[:], data[:]))
	return
}
func VerifyHash(data Hash, pk PublicKey, sig Signature) error {
	verifies := ed25519.Verify(pk[:], data[:], sig[:])
	if !verifies {
		return ErrInvalidSignature
	}
	return nil
}