2

I use the nacl cryptographic library and need to recover the public key from the secret key. Is this possible?

This is my somewhat naive attempt:

#include <nacl/crypto_scalarmult_curve25519.h>
#include <nacl/crypto_sign.h>

//...

int main(int argc, char **argv)
{
    UCHAR pk[crypto_sign_PUBLICKEYBYTES];
    UCHAR sk[crypto_sign_SECRETKEYBYTES];
    char pkhexbuf[2*crypto_sign_PUBLICKEYBYTES+1];
    char skhexbuf[2*crypto_sign_SECRETKEYBYTES+1];

    if( crypto_sign_keypair( pk, sk ) != 0) {
        printf( "Failed to generate keys." );
        return 1;
    }

    printf( "public key: %s\n", bytes_to_hex( pkhexbuf, pk, sizeof(pk) ) );
    printf( "secret key: %s\n", bytes_to_hex( skhexbuf, sk, sizeof(sk) ) );

    //reset the public key
    memset(pk, '\0', sizeof(pk));

    //recover public key
    if( crypto_scalarmult_curve25519_base(pk, sk) != 0 ) {
        printf( "Failed to derive public key from secret key." );
        return 1;
    }

    printf( "public key: %s\n", bytes_to_hex( pkhexbuf, pk, sizeof(pk) ) );
    return 0;
}

The public keys don't match. Any ideas how this is supposed to be done?

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
mwarning
  • 721
  • 5
  • 22
  • `crypto_sign` uses Ed25519 (Edwards form curve), `crypto_scalarmult_base` is for key-exchange and uses montgomery form. // You probably shouldn't use the signature code in NaCl in the first place. It's only a prototype. – CodesInChaos Oct 28 '13 at 08:53
  • Ok. Thank you for your answer! Is there some library you can recommend instead? – mwarning Oct 28 '13 at 13:59
  • You could take a look at LibSodium, it uses the final Ed25519 variant. But I think they haven't added the key regeneration API you want yet. There is an [open issue](https://github.com/jedisct1/libsodium/issues/81) and I'd expect that'll be added soon. – CodesInChaos Oct 28 '13 at 14:02
  • I used libsodium and actually prefer it. But I had to give libnacl a try because there was no package available for my target system. – mwarning Oct 28 '13 at 14:08
  • A copy of the public key is stored in the second half of the secret key. So, unless you only stored the first 32 bytes returned by NaCl for the secret key, you can simply read the 32 last bytes to get the corresponding public key. – Frank Denis Dec 03 '19 at 10:34

0 Answers0