func (k *Keyring) LookupBoxPublicKey(kid []byte) saltpack.BoxPublicKey {
	return kidToPublicKey(kid)
}
LookupBoxPublicKey returns the public key that corresponds to the
given key ID (or "kid")
package basic
import (
	"crypto/rand"
	"github.com/keybase/saltpack"
	"golang.org/x/crypto/ed25519"
	"golang.org/x/crypto/nacl/box"
)
type EphemeralKeyCreator struct{}
func (c EphemeralKeyCreator) CreateEphemeralKey() (saltpack.BoxSecretKey, error) {
	return generateBoxKey()
}
type PublicKey struct {
	EphemeralKeyCreator
	saltpack.RawBoxKey
}
type SecretKey struct {
	sec saltpack.RawBoxKey
	pub PublicKey
}
type PrecomputedSharedKey saltpack.RawBoxKey
func (k PublicKey) ToKID() []byte {
	return k.RawBoxKey[:]
}
func (k PublicKey) ToRawBoxKeyPointer() *saltpack.RawBoxKey {
	ret := k.RawBoxKey
	return &ret
}
func (k PublicKey) HideIdentity() bool { return false }
func generateBoxKey() (*SecretKey, error) {
	pub, priv, err := box.GenerateKey(rand.Reader)
	if err != nil {
		return nil, err
	}
	ret := NewSecretKey(pub, priv)
	return &ret, nil
}
var _ saltpack.BoxPublicKey = PublicKey{}
func (k SecretKey) Box(receiver saltpack.BoxPublicKey, nonce saltpack.Nonce, msg []byte) []byte {
	ret := box.Seal([]byte{}, msg, (*[24]byte)(&nonce), (*[32]byte)(receiver.ToRawBoxKeyPointer()), (*[32]byte)(&k.sec))
	return ret
}
func (k SecretKey) Unbox(sender saltpack.BoxPublicKey, nonce saltpack.Nonce, msg []byte) ([]byte, error) {
	ret, ok := box.Open([]byte{}, msg, (*[24]byte)(&nonce), (*[32]byte)(sender.ToRawBoxKeyPointer()), (*[32]byte)(&k.sec))
	if !ok {
		return nil, saltpack.ErrDecryptionFailed
	}
	return ret, nil
}
func (k SecretKey) GetPublicKey() saltpack.BoxPublicKey {
	return k.pub
}
func (k SecretKey) Precompute(peer saltpack.BoxPublicKey) saltpack.BoxPrecomputedSharedKey {
	var res PrecomputedSharedKey
	box.Precompute((*[32]byte)(&res), (*[32]byte)(peer.ToRawBoxKeyPointer()), (*[32]byte)(&k.sec))
	return res
}
func NewSecretKey(pub, sec *[32]byte) SecretKey {
	return SecretKey{
		sec: saltpack.RawBoxKey(*sec),
		pub: PublicKey{
			RawBoxKey: *pub,
		},
	}
}
var _ saltpack.BoxSecretKey = SecretKey{}
func (k PrecomputedSharedKey) Box(nonce saltpack.Nonce, msg []byte) []byte {
	ret := box.SealAfterPrecomputation([]byte{}, msg, (*[24]byte)(&nonce), (*[32]byte)(&k))
	return ret
}
func (k PrecomputedSharedKey) Unbox(nonce saltpack.Nonce, msg []byte) ([]byte, error) {
	ret, ok := box.OpenAfterPrecomputation([]byte{}, msg, (*[24]byte)(&nonce), (*[32]byte)(&k))
	if !ok {
		return nil, saltpack.ErrDecryptionFailed
	}
	return ret, nil
}
var _ saltpack.BoxPrecomputedSharedKey = PrecomputedSharedKey{}
type Keyring struct {
	EphemeralKeyCreator
	encKeys map[PublicKey]SecretKey
	sigKeys map[SigningPublicKey]SigningSecretKey
}
func NewKeyring() *Keyring {
	return &Keyring{
		encKeys: make(map[PublicKey]SecretKey),
		sigKeys: make(map[SigningPublicKey]SigningSecretKey),
	}
}
func (k *Keyring) ImportBoxKey(pub, sec *[32]byte) {
	nk := NewSecretKey(pub, sec)
	k.encKeys[nk.pub] = nk
}
func (k *Keyring) GenerateBoxKey() (*SecretKey, error) {
	ret, err := generateBoxKey()
	if err != nil {
		return nil, err
	}
	k.encKeys[ret.pub] = *ret
	return ret, nil
}
func (k *Keyring) GenerateSigningKey() (*SigningSecretKey, error) {
	pub, sec, err := ed25519.GenerateKey(rand.Reader)
	if err != nil {
		return nil, err
	}
	if len(pub) != ed25519.PublicKeySize {
		panic("unexpected public key size")
	}
	var pubArray [ed25519.PublicKeySize]byte
	copy(pubArray[:], pub)
	if len(sec) != ed25519.PrivateKeySize {
		panic("unexpected private key size")
	}
	var privArray [ed25519.PrivateKeySize]byte
	copy(privArray[:], sec)
	ret := NewSigningSecretKey(&pubArray, &privArray)
	return &ret, nil
}
func (k *Keyring) ImportSigningKey(pub *[ed25519.PublicKeySize]byte, sec *[ed25519.PrivateKeySize]byte) {
	nk := NewSigningSecretKey(pub, sec)
	k.sigKeys[nk.pub] = nk
}
func kidToPublicKey(kid []byte) PublicKey {
	var tmp PublicKey
	copy(tmp.RawBoxKey[:], kid)
	return tmp
}
func (k *Keyring) LookupBoxSecretKey(kids [][]byte) (int, saltpack.BoxSecretKey) {
	for i, kid := range kids {
		if sk, ok := k.encKeys[kidToPublicKey(kid)]; ok {
			return i, sk
		}
	}
	return -1, nil
}