or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

big-number-arithmetic.mdbit-array-utilities.mdcipher-modes.mddata-encoding.mdelliptic-curve-cryptography.mdhash-functions.mdhigh-level-encryption.mdindex.mdkey-derivation.mdkey-exchange.mdmessage-authentication.mdrandom-number-generation.mdsymmetric-encryption.md

cipher-modes.mddocs/

0

# Cipher Modes

1

2

SJCL provides various cipher modes for secure encryption including authenticated modes (CCM, GCM, OCB2) and traditional modes (CBC, CTR). Authenticated modes are recommended for most applications as they provide both encryption and authentication.

3

4

## Capabilities

5

6

### CCM Mode (Counter with CBC-MAC)

7

8

Authenticated encryption mode combining CTR encryption with CBC-MAC authentication, providing both confidentiality and integrity.

9

10

```javascript { .api }

11

/**

12

* CCM mode name constant

13

*/

14

sjcl.mode.ccm.name = "ccm";

15

16

/**

17

* CCM authenticated encryption

18

* @param {Cipher} prf - Block cipher instance (typically AES)

19

* @param {BitArray} plaintext - Data to encrypt

20

* @param {BitArray} iv - Initialization vector (7-15 bytes)

21

* @param {BitArray} [adata] - Additional authenticated data (not encrypted)

22

* @param {number} [tlen] - Authentication tag length in bits (default 64)

23

* @returns {BitArray} Concatenated ciphertext and authentication tag

24

* @throws {sjcl.exception.invalid} If IV length is invalid

25

*/

26

sjcl.mode.ccm.encrypt(prf, plaintext, iv, adata, tlen);

27

28

/**

29

* CCM authenticated decryption

30

* @param {Cipher} prf - Block cipher instance (same as used for encryption)

31

* @param {BitArray} ciphertext - Encrypted data with authentication tag

32

* @param {BitArray} iv - Initialization vector (must match encryption)

33

* @param {BitArray} [adata] - Additional authenticated data (must match encryption)

34

* @param {number} [tlen] - Authentication tag length in bits (default 64)

35

* @returns {BitArray} Decrypted plaintext

36

* @throws {sjcl.exception.corrupt} If authentication tag doesn't match

37

*/

38

sjcl.mode.ccm.decrypt(prf, ciphertext, iv, adata, tlen);

39

```

40

41

**Progress Monitoring:**

42

43

```javascript { .api }

44

/**

45

* Add progress callback for long operations

46

* @param {Function} cb - Callback function receiving progress value

47

*/

48

sjcl.mode.ccm.listenProgress(cb);

49

50

/**

51

* Remove progress callback

52

* @param {Function} cb - Callback function to remove

53

*/

54

sjcl.mode.ccm.unListenProgress(cb);

55

```

56

57

**Usage Examples:**

58

59

```javascript

60

const sjcl = require('sjcl');

61

62

// Basic CCM encryption

63

const key = sjcl.random.randomWords(8); // 256-bit key

64

const aes = new sjcl.cipher.aes(key);

65

const plaintext = sjcl.codec.utf8String.toBits("Hello, World!");

66

const iv = sjcl.random.randomWords(3); // 12-byte IV

67

const adata = sjcl.codec.utf8String.toBits("authenticated data");

68

69

const encrypted = sjcl.mode.ccm.encrypt(aes, plaintext, iv, adata, 128);

70

const decrypted = sjcl.mode.ccm.decrypt(aes, encrypted, iv, adata, 128);

71

72

console.log(sjcl.codec.utf8String.fromBits(decrypted)); // "Hello, World!"

73

74

// Progress monitoring for large operations

75

sjcl.mode.ccm.listenProgress(function(progress) {

76

console.log("CCM progress:", Math.round(progress * 100) + "%");

77

});

78

```

79

80

### GCM Mode (Galois/Counter Mode)

81

82

Authenticated encryption mode providing both encryption and authentication with excellent performance characteristics.

83

84

```javascript { .api }

85

/**

86

* GCM mode name constant

87

*/

88

sjcl.mode.gcm.name = "gcm";

89

90

/**

91

* GCM authenticated encryption

92

* @param {Cipher} prf - Block cipher instance (typically AES)

93

* @param {BitArray} plaintext - Data to encrypt

94

* @param {BitArray} iv - Initialization vector (recommended 12 bytes)

95

* @param {BitArray} [adata] - Additional authenticated data

96

* @param {number} [tlen] - Authentication tag length in bits (default 128)

97

* @returns {BitArray} Concatenated ciphertext and authentication tag

98

*/

99

sjcl.mode.gcm.encrypt(prf, plaintext, iv, adata, tlen);

100

101

/**

102

* GCM authenticated decryption

103

* @param {Cipher} prf - Block cipher instance (same as used for encryption)

104

* @param {BitArray} ciphertext - Encrypted data with authentication tag

105

* @param {BitArray} iv - Initialization vector (must match encryption)

106

* @param {BitArray} [adata] - Additional authenticated data (must match encryption)

107

* @param {number} [tlen] - Authentication tag length in bits (default 128)

108

* @returns {BitArray} Decrypted plaintext

109

* @throws {sjcl.exception.corrupt} If authentication tag doesn't match

110

*/

111

sjcl.mode.gcm.decrypt(prf, ciphertext, iv, adata, tlen);

112

```

113

114

**Usage Examples:**

115

116

```javascript

117

const sjcl = require('sjcl');

118

119

// GCM encryption with 12-byte IV (recommended)

120

const key = sjcl.random.randomWords(8);

121

const aes = new sjcl.cipher.aes(key);

122

const plaintext = sjcl.codec.utf8String.toBits("Sensitive data");

123

const iv = sjcl.random.randomWords(3); // 12 bytes

124

const adata = sjcl.codec.utf8String.toBits("public metadata");

125

126

const encrypted = sjcl.mode.gcm.encrypt(aes, plaintext, iv, adata);

127

const decrypted = sjcl.mode.gcm.decrypt(aes, encrypted, iv, adata);

128

129

console.log(sjcl.codec.utf8String.fromBits(decrypted)); // "Sensitive data"

130

131

// GCM with custom tag length

132

const encryptedShortTag = sjcl.mode.gcm.encrypt(aes, plaintext, iv, adata, 96);

133

const decryptedShortTag = sjcl.mode.gcm.decrypt(aes, encryptedShortTag, iv, adata, 96);

134

```

135

136

### OCB2 Mode (Offset Codebook Mode)

137

138

Authenticated encryption mode providing both encryption and authentication in a single pass.

139

140

```javascript { .api }

141

/**

142

* OCB2 mode name constant

143

*/

144

sjcl.mode.ocb2.name = "ocb2";

145

146

/**

147

* OCB2 authenticated encryption

148

* @param {Cipher} prp - Block cipher instance (typically AES)

149

* @param {BitArray} plaintext - Data to encrypt

150

* @param {BitArray} iv - 128-bit initialization vector

151

* @param {BitArray} [adata] - Additional authenticated data

152

* @param {number} [tlen] - Authentication tag length in bits (default 64)

153

* @param {boolean} [premac] - Whether adata is already processed

154

* @returns {BitArray} Concatenated ciphertext and authentication tag

155

* @throws {sjcl.exception.invalid} If IV is not 128 bits

156

*/

157

sjcl.mode.ocb2.encrypt(prp, plaintext, iv, adata, tlen, premac);

158

159

/**

160

* OCB2 authenticated decryption

161

* @param {Cipher} prp - Block cipher instance (same as used for encryption)

162

* @param {BitArray} ciphertext - Encrypted data with authentication tag

163

* @param {BitArray} iv - 128-bit initialization vector (must match encryption)

164

* @param {BitArray} [adata] - Additional authenticated data (must match encryption)

165

* @param {number} [tlen] - Authentication tag length in bits (default 64)

166

* @param {boolean} [premac] - Whether adata is already processed

167

* @returns {BitArray} Decrypted plaintext

168

* @throws {sjcl.exception.corrupt} If authentication tag doesn't match

169

*/

170

sjcl.mode.ocb2.decrypt(prp, ciphertext, iv, adata, tlen, premac);

171

172

/**

173

* Compute PMAC authentication for additional data

174

* @param {Cipher} prp - Block cipher instance

175

* @param {BitArray} adata - Additional data to authenticate

176

* @returns {BitArray} PMAC authentication tag

177

*/

178

sjcl.mode.ocb2.pmac(prp, adata);

179

```

180

181

**Usage Examples:**

182

183

```javascript

184

const sjcl = require('sjcl');

185

186

// OCB2 encryption (requires 128-bit IV)

187

const key = sjcl.random.randomWords(8);

188

const aes = new sjcl.cipher.aes(key);

189

const plaintext = sjcl.codec.utf8String.toBits("OCB2 test data");

190

const iv = sjcl.random.randomWords(4); // Must be exactly 128 bits

191

const adata = sjcl.codec.utf8String.toBits("additional data");

192

193

const encrypted = sjcl.mode.ocb2.encrypt(aes, plaintext, iv, adata);

194

const decrypted = sjcl.mode.ocb2.decrypt(aes, encrypted, iv, adata);

195

196

console.log(sjcl.codec.utf8String.fromBits(decrypted)); // "OCB2 test data"

197

198

// Using PMAC for separate authentication

199

const pmacTag = sjcl.mode.ocb2.pmac(aes, adata);

200

```

201

202

### CBC Mode (Cipher Block Chaining)

203

204

Traditional encryption mode that requires separate authentication. **Security Warning**: CBC mode without authentication is vulnerable to padding oracle attacks.

205

206

```javascript { .api }

207

/**

208

* CBC mode name constant

209

*/

210

sjcl.mode.cbc.name = "cbc";

211

212

/**

213

* CBC encryption - REQUIRES sjcl.beware acknowledgment

214

* @param {Cipher} prp - Block cipher instance

215

* @param {BitArray} plaintext - Data to encrypt (must be multiple of block size)

216

* @param {BitArray} iv - Initialization vector (128 bits)

217

* @param {BitArray} [adata] - Ignored parameter for compatibility

218

* @returns {BitArray} Encrypted ciphertext

219

*/

220

sjcl.mode.cbc.encrypt(prp, plaintext, iv, adata);

221

222

/**

223

* CBC decryption - REQUIRES sjcl.beware acknowledgment

224

* @param {Cipher} prp - Block cipher instance

225

* @param {BitArray} ciphertext - Data to decrypt

226

* @param {BitArray} iv - Initialization vector (must match encryption)

227

* @param {BitArray} [adata] - Ignored parameter for compatibility

228

* @returns {BitArray} Decrypted plaintext

229

*/

230

sjcl.mode.cbc.decrypt(prp, ciphertext, iv, adata);

231

```

232

233

**Usage Examples:**

234

235

```javascript

236

const sjcl = require('sjcl');

237

238

// CBC mode requires acknowledging security risks

239

sjcl.beware["CBC mode is dangerous because it doesn't protect message integrity."]();

240

241

const key = sjcl.random.randomWords(8);

242

const aes = new sjcl.cipher.aes(key);

243

const plaintext = sjcl.codec.utf8String.toBits("This must be padded to block boundary");

244

// Pad to multiple of 128 bits (4 words)

245

const paddedPlaintext = sjcl.bitArray.clamp(plaintext, Math.ceil(sjcl.bitArray.bitLength(plaintext) / 128) * 128);

246

const iv = sjcl.random.randomWords(4);

247

248

const encrypted = sjcl.mode.cbc.encrypt(aes, paddedPlaintext, iv);

249

const decrypted = sjcl.mode.cbc.decrypt(aes, encrypted, iv);

250

251

// Must also implement authentication separately (HMAC recommended)

252

const hmacKey = sjcl.random.randomWords(8);

253

const hmac = new sjcl.misc.hmac(hmacKey);

254

const authTag = hmac.encrypt(encrypted);

255

```

256

257

### CTR Mode (Counter Mode)

258

259

Stream cipher mode that converts block ciphers into stream ciphers. **Security Warning**: Requires separate authentication.

260

261

```javascript { .api }

262

/**

263

* CTR mode name constant

264

*/

265

sjcl.mode.ctr.name = "ctr";

266

267

/**

268

* CTR encryption - REQUIRES sjcl.beware acknowledgment

269

* @param {Cipher} prf - Block cipher instance

270

* @param {BitArray} plaintext - Data to encrypt

271

* @param {BitArray} iv - Initialization vector/counter

272

* @param {BitArray} [adata] - Ignored parameter for compatibility

273

* @returns {BitArray} Encrypted ciphertext

274

*/

275

sjcl.mode.ctr.encrypt(prf, plaintext, iv, adata);

276

277

/**

278

* CTR decryption - REQUIRES sjcl.beware acknowledgment

279

* @param {Cipher} prf - Block cipher instance

280

* @param {BitArray} ciphertext - Data to decrypt

281

* @param {BitArray} iv - Initialization vector/counter (must match encryption)

282

* @param {BitArray} [adata] - Ignored parameter for compatibility

283

* @returns {BitArray} Decrypted plaintext

284

*/

285

sjcl.mode.ctr.decrypt(prf, ciphertext, iv, adata);

286

```

287

288

**Usage Examples:**

289

290

```javascript

291

const sjcl = require('sjcl');

292

293

// CTR mode requires acknowledging security risks

294

sjcl.beware["CTR mode is dangerous because it doesn't protect message integrity."]();

295

296

const key = sjcl.random.randomWords(8);

297

const aes = new sjcl.cipher.aes(key);

298

const plaintext = sjcl.codec.utf8String.toBits("CTR mode can encrypt any length");

299

const iv = sjcl.random.randomWords(4); // Counter/IV

300

301

const encrypted = sjcl.mode.ctr.encrypt(aes, plaintext, iv);

302

const decrypted = sjcl.mode.ctr.decrypt(aes, encrypted, iv);

303

304

console.log(sjcl.codec.utf8String.fromBits(decrypted));

305

306

// Must implement authentication separately

307

const authKey = sjcl.random.randomWords(8);

308

const hmac = new sjcl.misc.hmac(authKey);

309

const authTag = hmac.encrypt(sjcl.bitArray.concat(iv, encrypted));

310

```

311

312

## ArrayBuffer Support

313

314

### CCM ArrayBuffer

315

316

CCM mode with ArrayBuffer support for working with binary data directly.

317

318

```javascript { .api }

319

/**

320

* CCM encryption for ArrayBuffers

321

* @param {Cipher} prf - Block cipher instance

322

* @param {ArrayBuffer} plaintext - Data to encrypt

323

* @param {ArrayBuffer} iv - Initialization vector

324

* @param {ArrayBuffer} [adata] - Additional authenticated data

325

* @param {number} [tlen] - Authentication tag length in bits

326

* @returns {ArrayBuffer} Encrypted data with authentication tag

327

*/

328

sjcl.mode.ccmArrayBuffer.encrypt(prf, plaintext, iv, adata, tlen);

329

330

/**

331

* CCM decryption for ArrayBuffers

332

* @param {Cipher} prf - Block cipher instance

333

* @param {ArrayBuffer} ciphertext - Encrypted data with tag

334

* @param {ArrayBuffer} iv - Initialization vector

335

* @param {ArrayBuffer} [adata] - Additional authenticated data

336

* @param {number} [tlen] - Authentication tag length in bits

337

* @returns {ArrayBuffer} Decrypted plaintext

338

*/

339

sjcl.mode.ccmArrayBuffer.decrypt(prf, ciphertext, iv, adata, tlen);

340

```

341

342

## Progressive OCB2

343

344

OCB2 mode with progressive/streaming capabilities for large data processing.

345

346

```javascript { .api }

347

/**

348

* Create progressive OCB2 encryptor

349

* @param {Cipher} prf - Block cipher instance

350

* @param {BitArray} iv - 128-bit initialization vector

351

* @param {BitArray} [adata] - Additional authenticated data

352

* @returns {Object} Progressive encryptor object

353

*/

354

sjcl.mode.ocb2progressive.createEncryptor(prf, iv, adata);

355

356

/**

357

* Create progressive OCB2 decryptor

358

* @param {Cipher} prf - Block cipher instance

359

* @param {BitArray} iv - 128-bit initialization vector

360

* @param {BitArray} [adata] - Additional authenticated data

361

* @returns {Object} Progressive decryptor object

362

*/

363

sjcl.mode.ocb2progressive.createDecryptor(prf, iv, adata);

364

```

365

366

## Security Recommendations

367

368

1. **Use authenticated modes** (CCM, GCM, OCB2) for all new applications

369

2. **Avoid CBC and CTR** unless you implement separate authentication

370

3. **Never reuse IV/nonce** with the same key

371

4. **Use proper IV lengths**: 12 bytes for GCM, 7-15 bytes for CCM, 16 bytes for OCB2

372

5. **Validate authentication tags** before processing decrypted data

373

6. **Use unique IVs** for each encryption operation

374

375

## Mode Comparison

376

377

| Mode | Authentication | Performance | IV Requirements | Security Level |

378

|------|---------------|-------------|-----------------|----------------|

379

| GCM | Yes | Excellent | 12 bytes (rec.) | High |

380

| CCM | Yes | Good | 7-15 bytes | High |

381

| OCB2 | Yes | Excellent | 16 bytes | High |

382

| CBC | No | Good | 16 bytes | Low (vulnerable) |

383

| CTR | No | Excellent | 16 bytes | Low (vulnerable) |