or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aead.mdauth.mdbox.mded25519.mdhash.mdindex.mdkdf.mdkx.mdmemory.mdpwhash.mdrandom.mdsecretbox.mdsecretstream.mdshorthash.mdsign.mdstream.md

stream.mddocs/

0

# Stream Ciphers

1

2

High-performance stream ciphers including ChaCha20, XChaCha20, and Salsa20 for fast symmetric encryption with XOR operations.

3

4

## Capabilities

5

6

### ChaCha20 Stream Cipher

7

8

High-speed stream cipher suitable for bulk encryption.

9

10

```javascript { .api }

11

/**

12

* Generate ChaCha20 keystream

13

* @param c - Output buffer for keystream

14

* @param n - Nonce buffer (must be NONCEBYTES long)

15

* @param k - Key buffer (must be KEYBYTES long)

16

* @throws Error if buffer sizes are incorrect or generation fails

17

*/

18

function crypto_stream_chacha20(c: Buffer, n: Buffer, k: Buffer): void;

19

20

/**

21

* Encrypt/decrypt data with ChaCha20 (XOR operation)

22

* @param c - Output buffer for ciphertext/plaintext (same length as message)

23

* @param m - Message buffer to encrypt/decrypt

24

* @param n - Nonce buffer (must be NONCEBYTES long)

25

* @param k - Key buffer (must be KEYBYTES long)

26

* @throws Error if buffer sizes are incorrect or operation fails

27

*/

28

function crypto_stream_chacha20_xor(c: Buffer, m: Buffer, n: Buffer, k: Buffer): void;

29

30

/**

31

* Encrypt/decrypt with ChaCha20 and initial counter

32

* @param c - Output buffer for ciphertext/plaintext (same length as message)

33

* @param m - Message buffer to encrypt/decrypt

34

* @param n - Nonce buffer (must be NONCEBYTES long)

35

* @param ic - Initial counter value

36

* @param k - Key buffer (must be KEYBYTES long)

37

* @throws Error if buffer sizes are incorrect or operation fails

38

*/

39

function crypto_stream_chacha20_xor_ic(c: Buffer, m: Buffer, n: Buffer, ic: number, k: Buffer): void;

40

```

41

42

**Usage Example:**

43

44

```javascript

45

const sodium = require('sodium-native');

46

47

// ChaCha20 encryption/decryption

48

const key = Buffer.alloc(sodium.crypto_stream_chacha20_KEYBYTES);

49

const nonce = Buffer.alloc(sodium.crypto_stream_chacha20_NONCEBYTES);

50

sodium.randombytes_buf(key);

51

sodium.randombytes_buf(nonce);

52

53

const message = Buffer.from('Hello, ChaCha20!');

54

const ciphertext = Buffer.alloc(message.length);

55

const plaintext = Buffer.alloc(message.length);

56

57

// Encrypt

58

sodium.crypto_stream_chacha20_xor(ciphertext, message, nonce, key);

59

60

// Decrypt (same operation)

61

sodium.crypto_stream_chacha20_xor(plaintext, ciphertext, nonce, key);

62

console.log(plaintext.toString()); // "Hello, ChaCha20!"

63

```

64

65

### ChaCha20-IETF Stream Cipher

66

67

IETF-standardized variant of ChaCha20 with different nonce size.

68

69

```javascript { .api }

70

/**

71

* Generate ChaCha20-IETF keystream

72

* @param c - Output buffer for keystream

73

* @param n - Nonce buffer (must be NONCEBYTES long)

74

* @param k - Key buffer (must be KEYBYTES long)

75

* @throws Error if buffer sizes are incorrect or generation fails

76

*/

77

function crypto_stream_chacha20_ietf(c: Buffer, n: Buffer, k: Buffer): void;

78

79

/**

80

* Encrypt/decrypt data with ChaCha20-IETF

81

* @param c - Output buffer for ciphertext/plaintext (same length as message)

82

* @param m - Message buffer to encrypt/decrypt

83

* @param n - Nonce buffer (must be NONCEBYTES long)

84

* @param k - Key buffer (must be KEYBYTES long)

85

* @throws Error if buffer sizes are incorrect or operation fails

86

*/

87

function crypto_stream_chacha20_ietf_xor(c: Buffer, m: Buffer, n: Buffer, k: Buffer): void;

88

89

/**

90

* Encrypt/decrypt with ChaCha20-IETF and initial counter

91

* @param c - Output buffer for ciphertext/plaintext (same length as message)

92

* @param m - Message buffer to encrypt/decrypt

93

* @param n - Nonce buffer (must be NONCEBYTES long)

94

* @param ic - Initial counter value

95

* @param k - Key buffer (must be KEYBYTES long)

96

* @throws Error if buffer sizes are incorrect or operation fails

97

*/

98

function crypto_stream_chacha20_ietf_xor_ic(c: Buffer, m: Buffer, n: Buffer, ic: number, k: Buffer): void;

99

```

100

101

### XChaCha20 Stream Cipher

102

103

Extended nonce variant of ChaCha20 for better nonce management.

104

105

```javascript { .api }

106

/**

107

* Generate XChaCha20 keystream

108

* @param c - Output buffer for keystream

109

* @param n - Nonce buffer (must be NONCEBYTES long)

110

* @param k - Key buffer (must be KEYBYTES long)

111

* @throws Error if buffer sizes are incorrect or generation fails

112

*/

113

function crypto_stream_xchacha20(c: Buffer, n: Buffer, k: Buffer): void;

114

115

/**

116

* Encrypt/decrypt data with XChaCha20

117

* @param c - Output buffer for ciphertext/plaintext (same length as message)

118

* @param m - Message buffer to encrypt/decrypt

119

* @param n - Nonce buffer (must be NONCEBYTES long)

120

* @param k - Key buffer (must be KEYBYTES long)

121

* @throws Error if buffer sizes are incorrect or operation fails

122

*/

123

function crypto_stream_xchacha20_xor(c: Buffer, m: Buffer, n: Buffer, k: Buffer): void;

124

125

/**

126

* Encrypt/decrypt with XChaCha20 and initial counter

127

* @param c - Output buffer for ciphertext/plaintext (same length as message)

128

* @param m - Message buffer to encrypt/decrypt

129

* @param n - Nonce buffer (must be NONCEBYTES long)

130

* @param ic - Initial counter value

131

* @param k - Key buffer (must be KEYBYTES long)

132

* @throws Error if buffer sizes are incorrect or operation fails

133

*/

134

function crypto_stream_xchacha20_xor_ic(c: Buffer, m: Buffer, n: Buffer, ic: number, k: Buffer): void;

135

```

136

137

### Salsa20 Stream Cipher

138

139

High-performance stream cipher, predecessor to ChaCha20.

140

141

```javascript { .api }

142

/**

143

* Generate Salsa20 keystream

144

* @param c - Output buffer for keystream

145

* @param n - Nonce buffer (must be NONCEBYTES long)

146

* @param k - Key buffer (must be KEYBYTES long)

147

* @throws Error if buffer sizes are incorrect or generation fails

148

*/

149

function crypto_stream_salsa20(c: Buffer, n: Buffer, k: Buffer): void;

150

151

/**

152

* Encrypt/decrypt data with Salsa20

153

* @param c - Output buffer for ciphertext/plaintext (same length as message)

154

* @param m - Message buffer to encrypt/decrypt

155

* @param n - Nonce buffer (must be NONCEBYTES long)

156

* @param k - Key buffer (must be KEYBYTES long)

157

* @throws Error if buffer sizes are incorrect or operation fails

158

*/

159

function crypto_stream_salsa20_xor(c: Buffer, m: Buffer, n: Buffer, k: Buffer): void;

160

161

/**

162

* Encrypt/decrypt with Salsa20 and initial counter

163

* @param c - Output buffer for ciphertext/plaintext (same length as message)

164

* @param m - Message buffer to encrypt/decrypt

165

* @param n - Nonce buffer (must be NONCEBYTES long)

166

* @param ic - Initial counter value

167

* @param k - Key buffer (must be KEYBYTES long)

168

* @throws Error if buffer sizes are incorrect or operation fails

169

*/

170

function crypto_stream_salsa20_xor_ic(c: Buffer, m: Buffer, n: Buffer, ic: number, k: Buffer): void;

171

```

172

173

### Stateful Stream Cipher Wrappers

174

175

Sodium-native specific wrappers for streaming encryption with state management.

176

177

```javascript { .api }

178

/**

179

* Initialize ChaCha20 streaming encryption state

180

* @param state - State buffer (must be STATEBYTES long)

181

* @param n - Nonce buffer (must be NONCEBYTES long)

182

* @param k - Key buffer (must be KEYBYTES long)

183

*/

184

function crypto_stream_chacha20_xor_wrap_init(state: Buffer, n: Buffer, k: Buffer): void;

185

186

/**

187

* Update ChaCha20 streaming encryption with more data

188

* @param state - State buffer from init

189

* @param c - Output buffer for ciphertext/plaintext (same length as message)

190

* @param m - Message buffer to encrypt/decrypt

191

*/

192

function crypto_stream_chacha20_xor_wrap_update(state: Buffer, c: Buffer, m: Buffer): void;

193

194

/**

195

* Finalize ChaCha20 streaming encryption

196

* @param state - State buffer from init/update

197

*/

198

function crypto_stream_chacha20_xor_wrap_final(state: Buffer): void;

199

```

200

201

**Usage Example:**

202

203

```javascript

204

const sodium = require('sodium-native');

205

206

// Streaming encryption for large data

207

const key = Buffer.alloc(sodium.crypto_stream_chacha20_KEYBYTES);

208

const nonce = Buffer.alloc(sodium.crypto_stream_chacha20_NONCEBYTES);

209

sodium.randombytes_buf(key);

210

sodium.randombytes_buf(nonce);

211

212

const state = Buffer.alloc(sodium.crypto_stream_chacha20_xor_STATEBYTES);

213

sodium.crypto_stream_chacha20_xor_wrap_init(state, nonce, key);

214

215

// Process data in chunks

216

const chunk1 = Buffer.from('First chunk of data');

217

const chunk2 = Buffer.from('Second chunk of data');

218

const encrypted1 = Buffer.alloc(chunk1.length);

219

const encrypted2 = Buffer.alloc(chunk2.length);

220

221

sodium.crypto_stream_chacha20_xor_wrap_update(state, encrypted1, chunk1);

222

sodium.crypto_stream_chacha20_xor_wrap_update(state, encrypted2, chunk2);

223

224

sodium.crypto_stream_chacha20_xor_wrap_final(state);

225

```

226

227

## Constants

228

229

```javascript { .api }

230

// Generic stream cipher constants

231

const crypto_stream_KEYBYTES: number;

232

const crypto_stream_NONCEBYTES: number;

233

234

// ChaCha20 constants

235

const crypto_stream_chacha20_KEYBYTES: number;

236

const crypto_stream_chacha20_NONCEBYTES: number;

237

const crypto_stream_chacha20_MESSAGEBYTES_MAX: number;

238

const crypto_stream_chacha20_xor_STATEBYTES: number;

239

240

// ChaCha20-IETF constants

241

const crypto_stream_chacha20_ietf_KEYBYTES: number;

242

const crypto_stream_chacha20_ietf_NONCEBYTES: number;

243

const crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX: number;

244

const crypto_stream_chacha20_ietf_xor_STATEBYTES: number;

245

246

// XChaCha20 constants

247

const crypto_stream_xchacha20_KEYBYTES: number;

248

const crypto_stream_xchacha20_NONCEBYTES: number;

249

const crypto_stream_xchacha20_MESSAGEBYTES_MAX: number;

250

const crypto_stream_xchacha20_xor_STATEBYTES: number;

251

252

// Salsa20 constants

253

const crypto_stream_salsa20_KEYBYTES: number;

254

const crypto_stream_salsa20_NONCEBYTES: number;

255

const crypto_stream_salsa20_MESSAGEBYTES_MAX: number;

256

const crypto_stream_salsa20_xor_STATEBYTES: number;

257

258

// Sodium-native specific

259

const sn_crypto_stream_xor_STATEBYTES: number;

260

```

261

262

## Security Considerations

263

264

- **Nonce Reuse**: Never reuse nonces with the same key. Each encryption must use a unique nonce.

265

- **Key Management**: Use secure key generation and storage practices.

266

- **Message Size**: Be aware of maximum message size limits for each cipher variant.

267

- **Authentication**: Stream ciphers provide no authentication - consider using AEAD modes or separate MAC.

268

269

## Common Patterns

270

271

### File Encryption with Stream Cipher

272

273

```javascript

274

const sodium = require('sodium-native');

275

const fs = require('fs');

276

277

class StreamFileEncryption {

278

constructor(cipher = 'xchacha20') {

279

this.cipher = cipher;

280

this.keyBytes = sodium[`crypto_stream_${cipher}_KEYBYTES`];

281

this.nonceBytes = sodium[`crypto_stream_${cipher}_NONCEBYTES`];

282

}

283

284

encryptFile(inputFile, outputFile, key) {

285

const nonce = Buffer.alloc(this.nonceBytes);

286

sodium.randombytes_buf(nonce);

287

288

const input = fs.readFileSync(inputFile);

289

const output = Buffer.alloc(input.length);

290

291

sodium[`crypto_stream_${this.cipher}_xor`](output, input, nonce, key);

292

293

// Prepend nonce to encrypted data

294

const encrypted = Buffer.concat([nonce, output]);

295

fs.writeFileSync(outputFile, encrypted);

296

}

297

298

decryptFile(inputFile, outputFile, key) {

299

const encrypted = fs.readFileSync(inputFile);

300

const nonce = encrypted.subarray(0, this.nonceBytes);

301

const ciphertext = encrypted.subarray(this.nonceBytes);

302

303

const output = Buffer.alloc(ciphertext.length);

304

sodium[`crypto_stream_${this.cipher}_xor`](output, ciphertext, nonce, key);

305

306

fs.writeFileSync(outputFile, output);

307

}

308

}

309

```

310

311

### Streaming Data Encryption

312

313

```javascript

314

const sodium = require('sodium-native');

315

316

class StreamCipher {

317

constructor(key, nonce, cipher = 'chacha20') {

318

this.cipher = cipher;

319

this.state = Buffer.alloc(sodium[`crypto_stream_${cipher}_xor_STATEBYTES`]);

320

sodium[`crypto_stream_${cipher}_xor_wrap_init`](this.state, nonce, key);

321

}

322

323

process(data) {

324

const output = Buffer.alloc(data.length);

325

sodium[`crypto_stream_${this.cipher}_xor_wrap_update`](this.state, output, data);

326

return output;

327

}

328

329

finalize() {

330

sodium[`crypto_stream_${this.cipher}_xor_wrap_final`](this.state);

331

}

332

}

333

334

// Usage

335

const key = Buffer.alloc(sodium.crypto_stream_chacha20_KEYBYTES);

336

const nonce = Buffer.alloc(sodium.crypto_stream_chacha20_NONCEBYTES);

337

sodium.randombytes_buf(key);

338

sodium.randombytes_buf(nonce);

339

340

const cipher = new StreamCipher(key, nonce);

341

342

// Process data in chunks

343

const encrypted1 = cipher.process(Buffer.from('First chunk'));

344

const encrypted2 = cipher.process(Buffer.from('Second chunk'));

345

346

cipher.finalize();

347

```

348

349

### Counter Mode with Custom Position

350

351

```javascript

352

const sodium = require('sodium-native');

353

354

function encryptAtPosition(data, key, nonce, position) {

355

// Calculate initial counter based on position

356

const blockSize = 64; // ChaCha20 block size

357

const initialCounter = Math.floor(position / blockSize);

358

359

const output = Buffer.alloc(data.length);

360

sodium.crypto_stream_chacha20_xor_ic(output, data, nonce, initialCounter, key);

361

362

return output;

363

}

364

365

// Useful for random access in encrypted files

366

const key = Buffer.alloc(sodium.crypto_stream_chacha20_KEYBYTES);

367

const nonce = Buffer.alloc(sodium.crypto_stream_chacha20_NONCEBYTES);

368

sodium.randombytes_buf(key);

369

sodium.randombytes_buf(nonce);

370

371

// Encrypt data at specific file position

372

const position = 1024; // Start encryption at byte 1024

373

const data = Buffer.from('Data to encrypt at position');

374

const encrypted = encryptAtPosition(data, key, nonce, position);

375

```