or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

box.mdindex.mdlowlevel.mdscalarmult.mdsecretbox.mdsign.mdutilities.md

box.mddocs/

0

# Public-Key Authenticated Encryption

1

2

Public-key authenticated encryption using x25519-xsalsa20-poly1305. This system provides confidentiality and authenticity between two parties using their respective public and secret key pairs, without requiring a shared secret.

3

4

## Capabilities

5

6

### Basic Encryption and Decryption

7

8

Encrypt and decrypt messages using public-key cryptography.

9

10

```javascript { .api }

11

/**

12

* Encrypts and authenticates a message using peer's public key and our secret key

13

* @param {Uint8Array} message - The plaintext message to encrypt

14

* @param {Uint8Array} nonce - Unique nonce for this encryption (24 bytes)

15

* @param {Uint8Array} theirPublicKey - Recipient's public key (32 bytes)

16

* @param {Uint8Array} mySecretKey - Sender's secret key (32 bytes)

17

* @returns {Uint8Array} Encrypted and authenticated message (16 bytes longer than original)

18

*/

19

nacl.box(message, nonce, theirPublicKey, mySecretKey): Uint8Array

20

21

/**

22

* Authenticates and decrypts a box using peer's public key and our secret key

23

* @param {Uint8Array} box - The encrypted message to decrypt

24

* @param {Uint8Array} nonce - The nonce used for encryption (24 bytes)

25

* @param {Uint8Array} theirPublicKey - Sender's public key (32 bytes)

26

* @param {Uint8Array} mySecretKey - Recipient's secret key (32 bytes)

27

* @returns {Uint8Array | null} Decrypted message or null if authentication fails

28

*/

29

nacl.box.open(box, nonce, theirPublicKey, mySecretKey): Uint8Array | null

30

```

31

32

**Usage Example:**

33

34

```javascript

35

const nacl = require('tweetnacl');

36

37

// Generate key pairs for Alice and Bob

38

const alice = nacl.box.keyPair();

39

const bob = nacl.box.keyPair();

40

41

// Alice encrypts a message for Bob

42

const message = new TextEncoder().encode("Hello Bob!");

43

const nonce = nacl.randomBytes(nacl.box.nonceLength);

44

const encrypted = nacl.box(message, nonce, bob.publicKey, alice.secretKey);

45

46

// Bob decrypts Alice's message

47

const decrypted = nacl.box.open(encrypted, nonce, alice.publicKey, bob.secretKey);

48

if (decrypted) {

49

console.log(new TextDecoder().decode(decrypted)); // "Hello Bob!"

50

}

51

```

52

53

### Optimized Operations with Precomputed Keys

54

55

For multiple operations between the same key pairs, precompute shared keys for better performance.

56

57

```javascript { .api }

58

/**

59

* Precomputes a shared key for multiple box operations between the same key pairs

60

* @param {Uint8Array} theirPublicKey - Peer's public key (32 bytes)

61

* @param {Uint8Array} mySecretKey - Our secret key (32 bytes)

62

* @returns {Uint8Array} Precomputed shared key (32 bytes)

63

*/

64

nacl.box.before(theirPublicKey, mySecretKey): Uint8Array

65

66

/**

67

* Encrypts using a precomputed shared key

68

* @param {Uint8Array} message - The plaintext message to encrypt

69

* @param {Uint8Array} nonce - Unique nonce for this encryption (24 bytes)

70

* @param {Uint8Array} sharedKey - Precomputed shared key from nacl.box.before

71

* @returns {Uint8Array} Encrypted and authenticated message

72

*/

73

nacl.box.after(message, nonce, sharedKey): Uint8Array

74

75

/**

76

* Decrypts using a precomputed shared key

77

* @param {Uint8Array} box - The encrypted message to decrypt

78

* @param {Uint8Array} nonce - The nonce used for encryption (24 bytes)

79

* @param {Uint8Array} sharedKey - Precomputed shared key from nacl.box.before

80

* @returns {Uint8Array | null} Decrypted message or null if authentication fails

81

*/

82

nacl.box.open.after(box, nonce, sharedKey): Uint8Array | null

83

```

84

85

**Usage Example:**

86

87

```javascript

88

const nacl = require('tweetnacl');

89

90

const alice = nacl.box.keyPair();

91

const bob = nacl.box.keyPair();

92

93

// Precompute shared keys (do this once)

94

const aliceSharedKey = nacl.box.before(bob.publicKey, alice.secretKey);

95

const bobSharedKey = nacl.box.before(alice.publicKey, bob.secretKey);

96

97

// Now encrypt/decrypt multiple messages efficiently

98

const message1 = new TextEncoder().encode("First message");

99

const message2 = new TextEncoder().encode("Second message");

100

101

const nonce1 = nacl.randomBytes(nacl.box.nonceLength);

102

const nonce2 = nacl.randomBytes(nacl.box.nonceLength);

103

104

const encrypted1 = nacl.box.after(message1, nonce1, aliceSharedKey);

105

const encrypted2 = nacl.box.after(message2, nonce2, aliceSharedKey);

106

107

const decrypted1 = nacl.box.open.after(encrypted1, nonce1, bobSharedKey);

108

const decrypted2 = nacl.box.open.after(encrypted2, nonce2, bobSharedKey);

109

```

110

111

### Key Generation

112

113

Generate key pairs for box operations.

114

115

```javascript { .api }

116

/**

117

* Generates a new random key pair for box operations

118

* @returns {{publicKey: Uint8Array, secretKey: Uint8Array}} Key pair object

119

*/

120

nacl.box.keyPair(): {publicKey: Uint8Array, secretKey: Uint8Array}

121

122

/**

123

* Derives a key pair from an existing secret key

124

* @param {Uint8Array} secretKey - The secret key (32 bytes)

125

* @returns {{publicKey: Uint8Array, secretKey: Uint8Array}} Key pair with corresponding public key

126

*/

127

nacl.box.keyPair.fromSecretKey(secretKey): {publicKey: Uint8Array, secretKey: Uint8Array}

128

```

129

130

**Usage Example:**

131

132

```javascript

133

const nacl = require('tweetnacl');

134

135

// Generate a new random key pair

136

const keyPair = nacl.box.keyPair();

137

console.log(keyPair.publicKey.length); // 32

138

console.log(keyPair.secretKey.length); // 32

139

140

// Derive key pair from existing secret key

141

const newKeyPair = nacl.box.keyPair.fromSecretKey(keyPair.secretKey);

142

// newKeyPair.publicKey will be identical to keyPair.publicKey

143

```

144

145

## Constants

146

147

```javascript { .api }

148

nacl.box.publicKeyLength: number // 32 - Length of public key in bytes

149

nacl.box.secretKeyLength: number // 32 - Length of secret key in bytes

150

nacl.box.sharedKeyLength: number // 32 - Length of precomputed shared key in bytes

151

nacl.box.nonceLength: number // 24 - Length of nonce in bytes

152

nacl.box.overheadLength: number // 16 - Length of overhead added to encrypted messages

153

```

154

155

## Error Handling

156

157

Common error patterns and proper handling:

158

159

```javascript

160

const nacl = require('tweetnacl');

161

162

function safeEncrypt(message, theirPublicKey, mySecretKey) {

163

try {

164

// Validate inputs

165

if (!message || !theirPublicKey || !mySecretKey) {

166

throw new Error('Missing required parameters');

167

}

168

169

if (theirPublicKey.length !== nacl.box.publicKeyLength) {

170

throw new Error(`Invalid public key length: expected ${nacl.box.publicKeyLength}, got ${theirPublicKey.length}`);

171

}

172

173

if (mySecretKey.length !== nacl.box.secretKeyLength) {

174

throw new Error(`Invalid secret key length: expected ${nacl.box.secretKeyLength}, got ${mySecretKey.length}`);

175

}

176

177

const nonce = nacl.randomBytes(nacl.box.nonceLength);

178

const encrypted = nacl.box(message, nonce, theirPublicKey, mySecretKey);

179

180

return { encrypted, nonce };

181

} catch (error) {

182

console.error('Encryption failed:', error.message);

183

return null;

184

}

185

}

186

187

function safeDecrypt(encrypted, nonce, theirPublicKey, mySecretKey) {

188

try {

189

const decrypted = nacl.box.open(encrypted, nonce, theirPublicKey, mySecretKey);

190

191

if (decrypted === null) {

192

throw new Error('Decryption failed: message was tampered with or keys are incorrect');

193

}

194

195

return decrypted;

196

} catch (error) {

197

console.error('Decryption failed:', error.message);

198

return null;

199

}

200

}

201

```

202

203

## Security Considerations

204

205

- **Nonce Uniqueness**: Each message encrypted with the same key pair must use a unique nonce. Reusing nonces breaks security.

206

- **Key Management**: Keep secret keys secure and never transmit them. Only share public keys.

207

- **Message Integrity**: If `nacl.box.open` returns `null`, the message was tampered with or authentication failed.

208

- **Overhead**: Encrypted messages are 16 bytes longer than the original due to authentication data.