0
$\begingroup$

I followed the description here:

Public-key authenticated encryption: crypto_box

and created an example that encrypts a message with Bob's public key and signs it with Alice's secret key :

cipher = crypto_box(secret_string, nonce, bob_pk, alice_sk); 

The cipher text can be decrypted and verified with Bob's secret key and Alice's public key:

message = crypto_box_open(cipher, nonce, alice_pk, bob_sk); 

However, the message can also be decrypted with Bob' public key and Alice's secret key:

message = crypto_box_open(cipher, nonce, bob_pk, alice_sk); 

This is somehow unexpected. I couldn't find much documentation for the crypto box. What is the math behind it?

My full code to reproduce:

#include <crypto_box.h> #include <string> #include <iostream> #include <fstream> #include <randombytes.h> #include <string> #include <iostream> int main() { std::string alice_pk; std::string alice_sk; std::string bob_pk; std::string bob_sk; std::string nonce; std::string cipher; std::string message; std::string secret_string = "my secret string"; unsigned char buffer[crypto_box_NONCEBYTES]; randombytes((unsigned char*)buffer, crypto_box_NONCEBYTES); nonce.assign((const char*)buffer, (size_t)crypto_box_NONCEBYTES); alice_pk = crypto_box_keypair(&alice_sk); bob_pk = crypto_box_keypair(&bob_sk); cipher = crypto_box(secret_string, nonce, bob_pk, alice_sk); message = crypto_box_open(cipher, nonce, bob_pk, alice_sk); std::cout << message << std::endl; message = crypto_box_open(cipher, nonce, alice_pk, bob_sk); std::cout << message << std::endl; } 
$\endgroup$
2
  • $\begingroup$ > Selected primitive > crypto_box is curve25519xsalsa20poly1305, a particular combination of Curve25519, Salsa20, and Poly1305 specified in "Cryptography in NaCl". This function is conjectured to meet the standard notions of privacy and third-party unforgeability. $\endgroup$ Commented Aug 17, 2019 at 14:50
  • $\begingroup$ That is where in the linked page it has a description of the crypto used. Mr. Denis' explanation is correct, since Curve25519 is an ECDH primitive in this context. $\endgroup$ Commented Aug 17, 2019 at 14:53

1 Answer 1

6
$\begingroup$

Alice and Bob's keys are used to compute a shared key.

Both parties compute the same key, which is used both encryption and decryption.

This is a traditional, hybrid encryption system.

Using only asymmetric cryptography for encryption would be painfully slow.

As a mitigation, the sender can create an ephemeral key pair, deleted right after the message has been encrypted. See ECIES or libsodium's crypto_box_seal() construction.

$\endgroup$
4
  • $\begingroup$ So why exactly can I decrypt the message with the same public key used for encryption? $\endgroup$ Commented Aug 15, 2019 at 13:57
  • 1
    $\begingroup$ The same key can be computed either from (Alice PK, Bob SK) or (Bob PK, Alice SK). This is the key actually used for encryption, and decryption. $\endgroup$ Commented Aug 15, 2019 at 14:02
  • $\begingroup$ So this is ECDH with some symmetric cipher then? On the website, they mention not a single bit about DH. $\endgroup$ Commented Aug 15, 2019 at 14:18
  • 3
    $\begingroup$ Yes, crypto_box() is ECDH using X25519, and encryption using salsa20poly1305. $\endgroup$ Commented Aug 15, 2019 at 16:25

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.