func (k *KeyPair) UnmarshalJSON(data []byte) error {
	type keyPair KeyPair
	if err := json.Unmarshal(data, (*keyPair)(k)); err != nil {
		return err
	}
	return k.validate()
}
UnmarshalJSON implements json.Unmarshaler.
package bakery
import (
	"crypto/rand"
	"encoding/base64"
	"encoding/json"
	"strings"
	"sync"
	"golang.org/x/crypto/nacl/box"
	"golang.org/x/net/context"
	"gopkg.in/errgo.v1"
	"gopkg.in/macaroon.v2"
)
const KeyLen = 32
const NonceLen = 24
type PublicKey struct {
	Key
}
type PrivateKey struct {
	Key
}
type Key [KeyLen]byte
func (k Key) String() string {
	return base64.StdEncoding.EncodeToString(k[:])
}
func (k Key) MarshalBinary() ([]byte, error) {
	return k[:], nil
}
func (k Key) isZero() bool {
	return k == Key{}
}
func (k *Key) UnmarshalBinary(data []byte) error {
	if len(data) != len(k) {
		return errgo.Newf("wrong length for key, got %d want %d", len(data), len(k))
	}
	copy(k[:], data)
	return nil
}
func (k Key) MarshalText() ([]byte, error) {
	data := make([]byte, base64.StdEncoding.EncodedLen(len(k)))
	base64.StdEncoding.Encode(data, k[:])
	return data, nil
}
func (k Key) boxKey() *[KeyLen]byte {
	return (*[KeyLen]byte)(&k)
}
func (k *Key) UnmarshalText(text []byte) error {
	data, err := macaroon.Base64Decode(text)
	if err != nil {
		return errgo.Notef(err, "cannot decode base64 key")
	}
	if len(data) != len(k) {
		return errgo.Newf("wrong length for key, got %d want %d", len(data), len(k))
	}
	copy(k[:], data)
	return nil
}
type ThirdPartyInfo struct {
	PublicKey PublicKey
	Version Version
}
type ThirdPartyLocator interface {
	ThirdPartyInfo(ctx context.Context, loc string) (ThirdPartyInfo, error)
}
type ThirdPartyStore struct {
	mu sync.RWMutex
	m  map[string]ThirdPartyInfo
}
func NewThirdPartyStore() *ThirdPartyStore {
	return &ThirdPartyStore{
		m: make(map[string]ThirdPartyInfo),
	}
}
func (s *ThirdPartyStore) AddInfo(loc string, info ThirdPartyInfo) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.m[canonicalLocation(loc)] = info
}
func canonicalLocation(loc string) string {
	return strings.TrimSuffix(loc, "/")
}
func (s *ThirdPartyStore) ThirdPartyInfo(ctx context.Context, loc string) (ThirdPartyInfo, error) {
	s.mu.RLock()
	defer s.mu.RUnlock()
	if info, ok := s.m[canonicalLocation(loc)]; ok {
		return info, nil
	}
	return ThirdPartyInfo{}, ErrNotFound
}
type KeyPair struct {
	Public  PublicKey  `json:"public"`
	Private PrivateKey `json:"private"`
}