func EdPrivateKeyToX25519(privateKey ed25519.PrivateKey) []byte {
	h := sha512.New()
	_, _ = h.Write(privateKey[:32])
	digest := h.Sum(nil)
	h.Reset()
	digest[0] &= 248
	digest[31] &= 127
	digest[31] |= 64
	dst := make([]byte, ScalarSize)
	copy(dst, digest)
	return dst
}
EdPrivateKeyToX25519 converts an Ed25519 private key into a corresponding
X25519 private key such that the resulting X25519 public key will equal
the result from EdPublicKeyToX25519.
package x25519
import (
	"crypto/sha512"
	"crypto/subtle"
	"fmt"
	xcurve "golang.org/x/crypto/curve25519"
	"github.com/oasisprotocol/ed25519"
	"github.com/oasisprotocol/ed25519/internal/curve25519"
	"github.com/oasisprotocol/ed25519/internal/ge25519"
	"github.com/oasisprotocol/ed25519/internal/modm"
)
const (
	ScalarSize = 32
	PointSize = 32
)
var Basepoint []byte
var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
func ScalarMult(dst, in, base *[32]byte) {
	xcurve.ScalarMult(dst, in, base)
}
func ScalarBaseMult(dst, in *[32]byte) {
	var (
		ec              [32]byte
		s               modm.Bignum256
		p               ge25519.Ge25519
		yplusz, zminusy curve25519.Bignum25519
	)
	copy(ec[:], in[:])
	ec[0] &= 248
	ec[31] &= 127
	ec[31] |= 64
	modm.ExpandRaw(&s, ec[:])
	ge25519.ScalarmultBaseNiels(&p, &ge25519.NielsBaseMultiples, &s)
	curve25519.Add(&yplusz, p.Y(), p.Z())
	curve25519.Sub(&zminusy, p.Z(), p.Y())
	curve25519.Recip(&zminusy, &zminusy)
	curve25519.Mul(&yplusz, &yplusz, &zminusy)
	curve25519.Contract(dst[:], &yplusz)
	s.Reset()
	for i := range ec {
		ec[i] = 0
	}
}
func X25519(scalar, point []byte) ([]byte, error) {
	var dst [32]byte
	return x25519(&dst, scalar, point)
}
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
	var in [32]byte
	if l := len(scalar); l != 32 {
		return nil, fmt.Errorf("bad scalar length: %d, expected %d", l, 32)
	}
	if l := len(point); l != 32 {
		return nil, fmt.Errorf("bad point length: %d, expected %d", l, 32)
	}
	copy(in[:], scalar)
	if &point[0] == &Basepoint[0] {
		checkBasepoint()
		ScalarBaseMult(dst, &in)
	} else {
		var base, zero [32]byte
		copy(base[:], point)
		ScalarMult(dst, &in, &base)
		if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
			return nil, fmt.Errorf("bad input point: low order point")
		}
	}
	return dst[:], nil
}
func checkBasepoint() {
	if subtle.ConstantTimeCompare(Basepoint, []byte{
		0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}) != 1 {
		panic("curve25519: global Basepoint value was modified")
	}
}