func (e *KeyPair) Clone() bc.KeyPair {
	return new(KeyPair)
}
Clone : Returns a new node of the same type as this one
package ecc
import (
	"bytes"
	"crypto/hmac"
	"crypto/rand"
	"crypto/sha256"
	"encoding/base64"
	"errors"
	"io"
	"log"
	"github.com/awgh/bencrypt"
	"github.com/awgh/bencrypt/bc"
	"golang.org/x/crypto/curve25519"
)
var (
	NAME = "Curve25519,AES-CBC-256,HMAC-SHA-256"
	aesKeyLabel = []byte{
		0x1e, 0xf1, 0x77, 0x14, 0xdb, 0xbf, 0x4d, 0x1c,
		0x88, 0x69, 0xe8, 0x27, 0x3e, 0x2c, 0x32, 0x7a}
	macKeyLabel = []byte{
		0x1f, 0x8f, 0xac, 0x50, 0x35, 0x7a, 0x4c, 0xfd,
		0xb6, 0x7b, 0x08, 0x53, 0x11, 0x53, 0x4d, 0xf8}
	luggageKeyLabel = []byte{
		0xc0, 0x53, 0x3b, 0x6e, 0x1a, 0x94, 0x44, 0xb7,
		0xb3, 0xbe, 0x24, 0xf9, 0x84, 0x30, 0xfd, 0x69}
)
type PubKey struct {
	Pubkey []byte  
}
func init() {
	bencrypt.KeypairTypes[NAME] = func() bc.KeyPair { return new(KeyPair) }
}
func (e *PubKey) ToB64() string {
	return base64.StdEncoding.EncodeToString(e.Pubkey)
}
func (e *PubKey) FromB64(s string) error {
	pk, err := base64.StdEncoding.DecodeString(s)
	if err != nil {
		return err
	}
	if len(pk) != 32 {
		return errors.New("Key array wrong size in PubKey.FromB64")
	}
	e.Pubkey = pk
	return nil
}
func (e *PubKey) ToBytes() []byte {
	return e.Pubkey
}
func (e *PubKey) FromBytes(b []byte) error {
	if len(b) != 32 {
		return errors.New("Key array wrong size in PubKey.FromBytes")
	}
	e.Pubkey = b
	return nil
}
func (e *PubKey) Clone() bc.PubKey {
	return new(PubKey)
}
func (e *PubKey) Nil() interface{} {
	return (*PubKey)(nil)
}
type KeyPair struct {
	privkey [32]byte  
	pubkey  *PubKey
}
func (e *KeyPair) GetName() string {
	return NAME
}
func (e *KeyPair) GetPubKey() bc.PubKey {
	return e.pubkey
}
func (e *KeyPair) Precompute() {
}
func (e *KeyPair) GenerateKey() {
	var private [32]byte
	if _, err := io.ReadFull(rand.Reader, private[:]); err != nil {
		log.Fatal(err.Error())
	}
	var pk [32]byte
	curve25519.ScalarBaseMult(&pk, &private)
	pko := new(PubKey)
	if err := pko.FromBytes(pk[:]); err != nil {
		log.Fatal(err.Error())
	}
	e.pubkey = pko
	copy(e.privkey[:], private[:])
	e.Precompute()
}
func (e *KeyPair) ToB64() string {
	data := append(e.pubkey.ToBytes(), e.privkey[:]...)
	s := base64.StdEncoding.EncodeToString(data)
	return s
}
func (e *KeyPair) FromB64(s string) error {
	dec, err := base64.StdEncoding.DecodeString(s)
	if err != nil {
		return err
	}
	if len(dec) != 64 {
		return errors.New("Key array wrong size in B64toPrivateKey")
	}
	pk := new(PubKey)
	err = pk.FromBytes(dec[0:32])
	if err != nil {
		return err
	}
	e.pubkey = pk
	copy(e.privkey[:], dec[32:64])
	e.Precompute()
	return nil
}
func (e *KeyPair) EncryptMessage(clear []byte, pubkey bc.PubKey) ([]byte, error) {
	if pubkey == nil {
		return nil, errors.New("Nil PubKey in EncryptMessage")
	}
	pk := pubkey.ToBytes()
	if len(pk) != 32 {
		return nil, errors.New("Key array wrong size in EncryptMessage")
	}
	var private, R, public, sharedKey [32]byte
	if _, err := io.ReadFull(rand.Reader, private[:]); err != nil {
		log.Fatal(err.Error())
	}
	curve25519.ScalarBaseMult(&R, &private)
	copy(public[:], pk[:])
	curve25519.ScalarMult(&sharedKey, &private, &public)
	aesKey, err := bc.Kdf(sharedKey[:], aesKeyLabel, nil)
	if err != nil {
		return nil, err
	}
	macKey, err := bc.Kdf(sharedKey[:], macKeyLabel, nil)
	if err != nil {
		return nil, err
	}
	ciphertext, err := bc.AesEncrypt(clear, aesKey)
	if err != nil {
		return nil, err
	}
	luggageTag, err := bc.Kdf(sharedKey[:], luggageKeyLabel, nil)
	if err != nil {
		return nil, err
	}
	mac := hmac.New(sha256.New, macKey)
	_, err = mac.Write(R[:])
	if err != nil {
		return nil, err
	}
	_, err = mac.Write(luggageTag[:])
	if err != nil {
		return nil, err
	}
	_, err = mac.Write(ciphertext)
	if err != nil {
		return nil, err
	}
	msgmac := mac.Sum(nil)
	out := make([]byte, 32+len(luggageTag)+len(ciphertext)+32)
	copy(out[:], R[:])
	copy(out[32:], luggageTag[:])
	copy(out[32+len(luggageTag):], ciphertext[:])
	copy(out[32+len(luggageTag)+len(ciphertext):], msgmac[:])
	return out, nil
}
func (e *KeyPair) DecryptMessage(data []byte) (bool, []byte, error) {
	var sharedKey, r [32]byte
	copy(r[:], data[:32])
	curve25519.ScalarMult(&sharedKey, &e.privkey, &r)
	luggageTag, err := bc.Kdf(sharedKey[:], luggageKeyLabel, nil)
	if err != nil {
		return false, nil, err
	}
	if !bytes.Equal(luggageTag, data[32:64]) {
		return false, nil, nil
	}
	aesKey, err := bc.Kdf(sharedKey[:], aesKeyLabel, nil)
	if err != nil {
		return true, nil, err
	}
	macKey, err := bc.Kdf(sharedKey[:], macKeyLabel, nil)
	if err != nil {
		return true, nil, err
	}
	expectedMac := data[len(data)-32:]
	mac := hmac.New(sha256.New, macKey)
	_, err = mac.Write(data[:len(data)-32])
	if err != nil {
		return true, nil, err
	}
	realMac := mac.Sum(nil)
	if !hmac.Equal(realMac, expectedMac) {
		return true, nil, errors.New("HMAC check failed")
	}
	clear, err := bc.AesDecrypt(data[64:len(data)-32], aesKey)
	if err != nil {
		return true, nil, err
	}
	return true, clear, nil
}
func (e *KeyPair) ValidatePubKey(s string) bool {
	pk := new(PubKey)
	if err := pk.FromB64(s); err != nil || pk.Pubkey == nil || len(pk.Pubkey) != 32 {
		return false
	}
	return true
}