Ed25519 to Curve25519

Ed25519 keys can be converted to X25519 keys, so that the same key pair can be used both for authenticated encryption (crypto_box) and for signatures (crypto_sign).
Before considering this operation, please read these relevant paragraphs from the FAQ:


unsigned char ed25519_pk[crypto_sign_ed25519_PUBLICKEYBYTES];
unsigned char ed25519_skpk[crypto_sign_ed25519_SECRETKEYBYTES];
unsigned char x25519_pk[crypto_scalarmult_curve25519_BYTES];
unsigned char x25519_sk[crypto_scalarmult_curve25519_BYTES];
crypto_sign_ed25519_keypair(ed25519_pk, ed25519_skpk);
crypto_sign_ed25519_pk_to_curve25519(x25519_pk, ed25519_pk);
crypto_sign_ed25519_sk_to_curve25519(x25519_sk, ed25519_skpk);


int crypto_sign_ed25519_pk_to_curve25519(unsigned char *x25519_pk,
const unsigned char *ed25519_pk);
The crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk.
int crypto_sign_ed25519_sk_to_curve25519(unsigned char *x25519_sk,
const unsigned char *ed25519_sk);
The crypto_sign_ed25519_sk_to_curve25519() function converts an Ed25519 secret key ed25519_sk to an X25519 secret key and stores it into x25519_sk.
In order to save some CPU cycles, the crypto_sign_open() and crypto_sign_verify_detached() functions expect the secret key to be followed by the public key, as generated by crypto_sign_keypair() and crypto_sign_seed_keypair().
However, the crypto_sign_ed25519_sk_to_curve25519() function doesn't have this requirement, and it is perfectly fine to provide only the Ed25519 secret key to this function.


If you can afford it, using distinct keys for signing and for encryption is still highly recommended.