# Why NaCL does not provide anonymous public key cryptography?

At the same time Sodium provides API for anonymous encryption without using ephemeral keys. Is it a bad practice to just use other user public key to encrypt a message?

• I'm not really clear on the question. – Thomas M. DuBuisson Jun 5 '17 at 15:08
• @ThomasM.DuBuisson, from NaCL docs: "NaCl's goal is to provide all of the core operations needed to build higher-level cryptographic tools". Isn't non-authenticated asymmetric encryption, the core operation to build cryptographic tools? AFAIK, sodium server the same purpose and provides this. – Andrey Kuznetsov Jun 5 '17 at 15:37
• How is crypto_box with an ephemeral key not unauthenticated? Or do you mean not count hybrid operations, so you can't count most DH-only ECC schemes? – Thomas M. DuBuisson Jun 5 '17 at 15:40
• Crypto_box with an ephemeral key is authenticated. But sodium provides int crypto_box_seal(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *pk) which does not require secret key for encryption. – Andrey Kuznetsov Jun 5 '17 at 15:49
• You can't actually authenticate an ephemeral key sort of by definition, so I guess we aren't in agreement on some basic terminology. Notice crypto_box_seal is exactly an ephemeral key and crypto_box with a little extra trick to compute the nonce in a space-saving way. – Thomas M. DuBuisson Jun 5 '17 at 16:50

As I now understand the question: why doesn't NaCL provide a primitive for unauthenticated encryption, making ciphertext blobs that are only decrypt-able by a receiver identified by their public key? Note libsodium provides crypto_box_seal which does exactly this and NaCL claims to (try to) provide all necessary crypto primitives.

In answer, notice crypto_box_seal can be built using other primitives. Sodium says of crypto_box_seal:

ephemeral_pk ‖ box( m, recipient_pk, ephemeral_sk
, nonce=blake2b(ephemeral_pk ‖ recipient_pk))


So what we have in terms of NaCL prims are (pseudo-code):

sk = random();
ephemeral_pk = crypto_box_keypair(sk);
nonce = sha512(ephemeral_pk || recipient_pk); // NaCL uses SHA512 not Blake2b.
ct = ephemeral_pk || crypto_box(m, recipient_pk, sk, nonce);


This can be considered anonymous because the ephemeral key pairs used are not associated with any identity - the secret key should be destroyed immediately after computing the ciphertext message, ct.