0
# Public-Key Encryption
1
2
Public-key encryption enables secure communication between parties without prior key exchange. libsodium-wrappers provides Curve25519-based key exchange with ChaCha20-Poly1305 encryption and anonymous encryption (sealing) capabilities.
3
4
## Capabilities
5
6
### Standard Box Encryption
7
8
Curve25519-XSalsa20-Poly1305 encryption between two parties with known keys.
9
10
```javascript { .api }
11
/**
12
* Generates a new key pair for public-key encryption
13
* @returns Object with publicKey, privateKey, and keyType properties
14
*/
15
function crypto_box_keypair();
16
17
/**
18
* Encrypts a message for a recipient
19
* @param message - The plaintext message to encrypt
20
* @param nonce - 24-byte nonce (must be unique for each message with the same key pair)
21
* @param publicKey - Recipient's 32-byte public key
22
* @param privateKey - Sender's 32-byte private key
23
* @returns Encrypted ciphertext with authentication tag
24
*/
25
function crypto_box_easy(message, nonce, publicKey, privateKey);
26
27
/**
28
* Decrypts a message
29
* @param ciphertext - The encrypted message to decrypt
30
* @param nonce - 24-byte nonce used during encryption
31
* @param publicKey - Sender's 32-byte public key
32
* @param privateKey - Recipient's 32-byte private key
33
* @returns Decrypted plaintext message
34
* @throws Error if decryption fails or authentication is invalid
35
*/
36
function crypto_box_open_easy(ciphertext, nonce, publicKey, privateKey);
37
38
/**
39
* Generates a deterministic key pair from a seed
40
* @param seed - 32-byte seed for key generation
41
* @returns Object with publicKey, privateKey, and keyType properties
42
*/
43
function crypto_box_seed_keypair(seed);
44
45
/**
46
* Encrypts a message with detached authentication tag
47
* @param message - The plaintext message to encrypt
48
* @param nonce - 24-byte nonce
49
* @param publicKey - Recipient's 32-byte public key
50
* @param privateKey - Sender's 32-byte private key
51
* @returns Object with ciphertext and mac properties
52
*/
53
function crypto_box_detached(message, nonce, publicKey, privateKey);
54
55
/**
56
* Decrypts a message with detached authentication tag
57
* @param ciphertext - The encrypted message
58
* @param mac - The detached authentication tag
59
* @param nonce - 24-byte nonce used during encryption
60
* @param publicKey - Sender's 32-byte public key
61
* @param privateKey - Recipient's 32-byte private key
62
* @returns Decrypted plaintext message
63
*/
64
function crypto_box_open_detached(ciphertext, mac, nonce, publicKey, privateKey);
65
```
66
67
**Usage Example:**
68
69
```javascript
70
// Generate key pairs for Alice and Bob
71
const alice = sodium.crypto_box_keypair();
72
const bob = sodium.crypto_box_keypair();
73
74
// Alice encrypts a message for Bob
75
const message = sodium.from_string("Hello Bob!");
76
const nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES);
77
const ciphertext = sodium.crypto_box_easy(message, nonce, bob.publicKey, alice.privateKey);
78
79
// Bob decrypts the message from Alice
80
const decrypted = sodium.crypto_box_open_easy(ciphertext, nonce, alice.publicKey, bob.privateKey);
81
console.log(sodium.to_string(decrypted)); // "Hello Bob!"
82
```
83
84
### Optimized Operations with Shared Secret
85
86
For multiple messages between the same parties, compute the shared secret once for better performance.
87
88
```javascript { .api }
89
/**
90
* Computes a shared secret between two parties
91
* @param publicKey - Other party's 32-byte public key
92
* @param privateKey - Own 32-byte private key
93
* @returns 32-byte shared secret for use with afternm functions
94
*/
95
function crypto_box_beforenm(publicKey, privateKey);
96
97
/**
98
* Encrypts a message using a precomputed shared secret
99
* @param message - The plaintext message to encrypt
100
* @param nonce - 24-byte nonce
101
* @param sharedKey - 32-byte shared secret from crypto_box_beforenm
102
* @returns Encrypted ciphertext with authentication tag
103
*/
104
function crypto_box_easy_afternm(message, nonce, sharedKey);
105
106
/**
107
* Decrypts a message using a precomputed shared secret
108
* @param ciphertext - The encrypted message to decrypt
109
* @param nonce - 24-byte nonce used during encryption
110
* @param sharedKey - 32-byte shared secret from crypto_box_beforenm
111
* @returns Decrypted plaintext message
112
*/
113
function crypto_box_open_easy_afternm(ciphertext, nonce, sharedKey);
114
```
115
116
### Anonymous Encryption (Sealing)
117
118
Encrypt messages for a recipient without revealing the sender's identity.
119
120
```javascript { .api }
121
/**
122
* Encrypts a message anonymously for a recipient
123
* @param message - The plaintext message to encrypt
124
* @param publicKey - Recipient's 32-byte public key
125
* @returns Encrypted ciphertext (larger than regular box due to ephemeral key)
126
*/
127
function crypto_box_seal(message, publicKey);
128
129
/**
130
* Decrypts an anonymously encrypted message
131
* @param ciphertext - The sealed ciphertext to decrypt
132
* @param publicKey - Recipient's 32-byte public key
133
* @param secretKey - Recipient's 32-byte secret key
134
* @returns Decrypted plaintext message
135
* @throws Error if decryption fails
136
*/
137
function crypto_box_seal_open(ciphertext, publicKey, secretKey);
138
```
139
140
**Usage Example:**
141
142
```javascript
143
// Bob's key pair
144
const bob = sodium.crypto_box_keypair();
145
146
// Anonymous sender encrypts a message for Bob
147
const message = sodium.from_string("Anonymous message");
148
const sealedBox = sodium.crypto_box_seal(message, bob.publicKey);
149
150
// Bob decrypts the anonymous message
151
const decrypted = sodium.crypto_box_seal_open(sealedBox, bob.publicKey, bob.privateKey);
152
console.log(sodium.to_string(decrypted)); // "Anonymous message"
153
```
154
155
### Curve25519-XChaCha20-Poly1305 (Modern Variant)
156
157
Modern variant with extended nonces for better security properties.
158
159
```javascript { .api }
160
function crypto_box_curve25519xchacha20poly1305_keypair();
161
function crypto_box_curve25519xchacha20poly1305_easy(message, nonce, publicKey, privateKey);
162
function crypto_box_curve25519xchacha20poly1305_open_easy(ciphertext, nonce, publicKey, privateKey);
163
function crypto_box_curve25519xchacha20poly1305_seal(message, publicKey);
164
function crypto_box_curve25519xchacha20poly1305_seal_open(ciphertext, publicKey, secretKey);
165
function crypto_box_curve25519xchacha20poly1305_beforenm(publicKey, privateKey);
166
function crypto_box_curve25519xchacha20poly1305_easy_afternm(message, nonce, sharedKey);
167
function crypto_box_curve25519xchacha20poly1305_open_easy_afternm(ciphertext, nonce, sharedKey);
168
function crypto_box_curve25519xchacha20poly1305_detached(message, nonce, publicKey, privateKey);
169
function crypto_box_curve25519xchacha20poly1305_open_detached(ciphertext, mac, nonce, publicKey, privateKey);
170
function crypto_box_curve25519xchacha20poly1305_seed_keypair(seed);
171
```
172
173
## Key Pair Structure
174
175
```javascript { .api }
176
interface KeyPair {
177
publicKey: Uint8Array; // 32 bytes - share with others
178
privateKey: Uint8Array; // 32 bytes - keep secret
179
keyType: string; // "x25519" or "curve25519"
180
}
181
```
182
183
## Constants
184
185
```javascript { .api }
186
// Standard Box
187
const crypto_box_PUBLICKEYBYTES = 32;
188
const crypto_box_SECRETKEYBYTES = 32;
189
const crypto_box_NONCEBYTES = 24;
190
const crypto_box_MACBYTES = 16;
191
const crypto_box_SEEDBYTES = 32;
192
const crypto_box_BEFORENMBYTES = 32;
193
const crypto_box_SEALBYTES = 48; // Additional bytes for sealed boxes
194
195
// Modern Variant
196
const crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES = 32;
197
const crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES = 32;
198
const crypto_box_curve25519xchacha20poly1305_NONCEBYTES = 24;
199
const crypto_box_curve25519xchacha20poly1305_MACBYTES = 16;
200
const crypto_box_curve25519xchacha20poly1305_SEEDBYTES = 32;
201
const crypto_box_curve25519xchacha20poly1305_SEALBYTES = 48;
202
```
203
204
## Security Considerations
205
206
- **Nonce Management**: Never reuse nonces with the same key pair. Use random nonces or counters.
207
- **Key Generation**: Always use `crypto_box_keypair()` or `crypto_box_seed_keypair()` for key generation.
208
- **Private Key Security**: Private keys must be kept secret and securely stored.
209
- **Public Key Verification**: Verify public keys are received from trusted sources to prevent man-in-the-middle attacks.
210
- **Sealed Boxes**: Anonymous encryption provides no sender authentication - use regular boxes when sender identity matters.