Not all crypto currencies are using secp256k1 technology for keypair generation and digital signatures. Curve25519 technology (frequently used to support ECDH key exchanges) is being used by a few other cryptocurrencies. Ed25519 cryptography (meant to support EdDSA functionality) and Curve25519 cryptography are closely related through transformations and the trend is to start with Ed25519 keys and transform them to Curve25519 key pairs.

Been using this reference as a source of eight ED25519_SECRET_KEYS and corresponding ED25519_PUBLIC_KEYS to use as test vectors for applying Ed25519 package implementations.

Got floodyberry/ed25519-donna to function as expected. However, I could not compute the ED25519_CURVE25519_PUBLIC_KEYS from the reference using ed25519-donna using its curved25519_scalarmult_basepoint() function to match. This pushed me towards trying jedisct1/libsodium. Got crypto_scalarmult_base() function results from libsodium to match those from ed25519-donna:-)

However, it is unclear how jedisct1/libsodium can be applied to generate public Ed25519 keys only from secret Ed25519 keys that are natively in an ASCII hexadecimal format:-( It seems that jedisct1/libsodium requires keys to always be generated from it native keypair generation process, opposed to an externally supplied private key.

Used the sodium_hex2bin() to stuff an ASCII hex encoded private key from the reference into the 64 unsigned char ed25519_skpk variable:

sodium_hex2bin( ed25519_skpk, 32, ED25519_SECRET_KEYS[ii], 64, NULL, NULL, NULL );

Results from the following libsodium function were as expected:

crypto_scalarmult_base( curve25519_pk, ed25519_skpk )

Was a bit frustrated when I discovered that crypto_sign_ed25519_sk_to_pk() was coded to extract the public key from ed25519_skpk that was never initialized.

crypto_sign_ed25519_sk_to_pk( ed25519_pk, ed25519_skpk );

Becoming a bit disappointed not locating a libsodium function to compute the ed25519_pk key when ed25519_skpk is loaded with a working private key from an external source. Any assistance will be greatly appreciated.


2 Answers 2


It's not possible to directly compute the ed25519 public key from the private key. Instead, use the deterministic private key to create a seed, then use the seed to re-create the private key with its corresponding public key. The following code snippet assumes ed25519_skpk is already initialized:

char           hex_ed_pk[65];                                      
unsigned char  seed[crypto_sign_SEEDBYTES];                       
unsigned char  ed25519_skpk[crypto_sign_ed25519_SECRETKEYBYTES];        
unsigned char  ed25519_pk[crypto_sign_ed25519_PUBLICKEYBYTES];

(void)crypto_sign_ed25519_sk_to_seed( seed,ed25519_skpk);                
(void)crypto_sign_seed_keypair( ed25519_pk, ed25519_skpk, seed );      
(void)sodium_bin2hex( hex_ed_pk, 65, ed25519_pk, 32 );

On libsodium > 1.0.15, the crypto_scalarmult_ed25519_base() can do this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.