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?
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
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,
crypto_boxwith an ephemeral key not unauthenticated? Or do you mean not count hybrid operations, so you can't count most DH-only ECC schemes? $\endgroup$
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. $\endgroup$
crypto_box_sealis exactly an ephemeral key and
crypto_boxwith a little extra trick to compute the nonce in a space-saving way. $\endgroup$