or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-sha3.mdcore-hashing.mdhmac-operations.mdindex.mdvariant-classes.md
tile.json

advanced-sha3.mddocs/

0

# Advanced SHA3 Features

1

2

Advanced SHA-3 functionality including variable-length SHAKE algorithms, customizable cSHAKE variants, and KMAC (Keccak-based Message Authentication Code). These modern cryptographic functions provide enhanced security features and flexibility beyond traditional fixed-length hash functions.

3

4

## Capabilities

5

6

### SHAKE (Secure Hash Algorithm Keccak) - Variable Length

7

8

SHAKE algorithms provide variable-length output based on the Keccak sponge construction, offering configurable output sizes for specific security requirements.

9

10

```typescript { .api }

11

/**

12

* SHAKE constructor for TEXT input format

13

* @param variant - SHAKE variant: SHAKE128 or SHAKE256

14

* @param inputFormat - Must be "TEXT"

15

* @param options - Optional configuration including encoding and numRounds

16

*/

17

constructor(variant: "SHAKE128" | "SHAKE256", inputFormat: "TEXT", options?: SHAKEOptionsEncodingType);

18

19

/**

20

* SHAKE constructor for binary input formats

21

* @param variant - SHAKE variant: SHAKE128 or SHAKE256

22

* @param inputFormat - Binary format: HEX, B64, BYTES, ARRAYBUFFER, UINT8ARRAY

23

* @param options - Optional configuration including numRounds

24

*/

25

constructor(variant: "SHAKE128" | "SHAKE256", inputFormat: FormatNoTextType, options?: SHAKEOptionsNoEncodingType);

26

27

interface SHAKEOptionsEncodingType {

28

numRounds?: number;

29

encoding?: EncodingType;

30

}

31

32

interface SHAKEOptionsNoEncodingType {

33

numRounds?: number;

34

}

35

36

type EncodingType = "UTF8" | "UTF16BE" | "UTF16LE";

37

type FormatNoTextType = "HEX" | "B64" | "BYTES" | "ARRAYBUFFER" | "UINT8ARRAY";

38

```

39

40

**Usage Examples:**

41

42

```typescript

43

import jsSHA from "jssha";

44

45

// SHAKE128 with 256-bit output

46

const shake128 = new jsSHA("SHAKE128", "TEXT", { encoding: "UTF8" });

47

shake128.update("Hello, SHAKE128!");

48

const hash256 = shake128.getHash("HEX", { outputLen: 256 });

49

50

// SHAKE256 with 512-bit output

51

const shake256 = new jsSHA("SHAKE256", "TEXT");

52

shake256.update("Hello, SHAKE256!");

53

const hash512 = shake256.getHash("HEX", { outputLen: 512 });

54

55

// Variable output lengths

56

const shake = new jsSHA("SHAKE128", "TEXT");

57

shake.update("Same input");

58

const short = shake.getHash("HEX", { outputLen: 128 }); // 128-bit output

59

const medium = shake.getHash("HEX", { outputLen: 384 }); // 384-bit output

60

const long = shake.getHash("HEX", { outputLen: 1024 }); // 1024-bit output

61

62

// SHAKE with hex input

63

const shakeHex = new jsSHA("SHAKE256", "HEX");

64

shakeHex.update("48656c6c6f"); // "Hello" in hex

65

const result = shakeHex.getHash("B64", { outputLen: 256 });

66

```

67

68

### cSHAKE (Customizable SHAKE) - Domain Separation

69

70

cSHAKE extends SHAKE with domain separation through customization strings and function names, providing enhanced security in multi-purpose applications.

71

72

```typescript { .api }

73

/**

74

* cSHAKE constructor for TEXT input format

75

* @param variant - cSHAKE variant: CSHAKE128 or CSHAKE256

76

* @param inputFormat - Must be "TEXT"

77

* @param options - Customization options including funcName and customization

78

*/

79

constructor(variant: "CSHAKE128" | "CSHAKE256", inputFormat: "TEXT", options?: CSHAKEOptionsEncodingType);

80

81

/**

82

* cSHAKE constructor for binary input formats

83

* @param variant - cSHAKE variant: CSHAKE128 or CSHAKE256

84

* @param inputFormat - Binary format: HEX, B64, BYTES, ARRAYBUFFER, UINT8ARRAY

85

* @param options - Customization options including funcName and customization

86

*/

87

constructor(variant: "CSHAKE128" | "CSHAKE256", inputFormat: FormatNoTextType, options?: CSHAKEOptionsNoEncodingType);

88

89

interface CSHAKEOptionsEncodingType {

90

customization?: GenericInputType;

91

funcName?: GenericInputType;

92

encoding?: EncodingType;

93

}

94

95

interface CSHAKEOptionsNoEncodingType {

96

customization?: GenericInputType;

97

funcName?: GenericInputType;

98

}

99

100

interface GenericInputType {

101

value: string;

102

format: "TEXT";

103

encoding?: EncodingType;

104

} | {

105

value: string;

106

format: "B64" | "HEX" | "BYTES";

107

} | {

108

value: ArrayBuffer;

109

format: "ARRAYBUFFER";

110

} | {

111

value: Uint8Array;

112

format: "UINT8ARRAY";

113

}

114

```

115

116

**Usage Examples:**

117

118

```typescript

119

import jsSHA from "jssha";

120

121

// cSHAKE with customization string

122

const cshake1 = new jsSHA("CSHAKE128", "TEXT", {

123

customization: { value: "MyApp", format: "TEXT" },

124

encoding: "UTF8"

125

});

126

cshake1.update("Hello, cSHAKE!");

127

const result1 = cshake1.getHash("HEX", { outputLen: 256 });

128

129

// cSHAKE with function name and customization

130

const cshake2 = new jsSHA("CSHAKE256", "TEXT", {

131

funcName: { value: "KeyDerivation", format: "TEXT" },

132

customization: { value: "UserAuth-v1.0", format: "TEXT" }

133

});

134

cshake2.update("sensitive-data");

135

const result2 = cshake2.getHash("B64", { outputLen: 384 });

136

137

// cSHAKE with hex customization

138

const cshake3 = new jsSHA("CSHAKE128", "HEX", {

139

customization: { value: "deadbeef", format: "HEX" }

140

});

141

cshake3.update("48656c6c6f"); // "Hello" in hex

142

const result3 = cshake3.getHash("UINT8ARRAY", { outputLen: 512 });

143

144

// Domain separation example

145

const emailHash = new jsSHA("CSHAKE256", "TEXT", {

146

funcName: { value: "EmailHash", format: "TEXT" },

147

customization: { value: "MyCompany-2024", format: "TEXT" }

148

});

149

emailHash.update("user@example.com");

150

const emailDigest = emailHash.getHash("HEX", { outputLen: 256 });

151

152

const passwordHash = new jsSHA("CSHAKE256", "TEXT", {

153

funcName: { value: "PasswordHash", format: "TEXT" },

154

customization: { value: "MyCompany-2024", format: "TEXT" }

155

});

156

passwordHash.update("user-password");

157

const passwordDigest = passwordHash.getHash("HEX", { outputLen: 256 });

158

```

159

160

### KMAC (Keccak-based Message Authentication Code)

161

162

KMAC provides authenticated hashing based on cSHAKE, offering strong security guarantees for message authentication and integrity verification.

163

164

```typescript { .api }

165

/**

166

* KMAC constructor for TEXT input format

167

* @param variant - KMAC variant: KMAC128 or KMAC256

168

* @param inputFormat - Must be "TEXT"

169

* @param options - Required kmacKey and optional customization

170

*/

171

constructor(variant: "KMAC128" | "KMAC256", inputFormat: "TEXT", options: KMACOptionsEncodingType);

172

173

/**

174

* KMAC constructor for binary input formats

175

* @param variant - KMAC variant: KMAC128 or KMAC256

176

* @param inputFormat - Binary format: HEX, B64, BYTES, ARRAYBUFFER, UINT8ARRAY

177

* @param options - Required kmacKey and optional customization

178

*/

179

constructor(variant: "KMAC128" | "KMAC256", inputFormat: FormatNoTextType, options: KMACOptionsNoEncodingType);

180

181

interface KMACOptionsEncodingType {

182

kmacKey: GenericInputType;

183

customization?: GenericInputType;

184

encoding?: EncodingType;

185

}

186

187

interface KMACOptionsNoEncodingType {

188

kmacKey: GenericInputType;

189

customization?: GenericInputType;

190

}

191

```

192

193

**Usage Examples:**

194

195

```typescript

196

import jsSHA from "jssha";

197

198

// Basic KMAC with text key

199

const kmac1 = new jsSHA("KMAC128", "TEXT", {

200

kmacKey: { value: "secret-key", format: "TEXT" },

201

encoding: "UTF8"

202

});

203

kmac1.update("Message to authenticate");

204

const mac1 = kmac1.getHash("HEX", { outputLen: 256 });

205

206

// KMAC with customization string

207

const kmac2 = new jsSHA("KMAC256", "TEXT", {

208

kmacKey: { value: "another-secret", format: "TEXT" },

209

customization: { value: "MyProtocol-v2", format: "TEXT" }

210

});

211

kmac2.update("Authenticated message");

212

const mac2 = kmac2.getHash("B64", { outputLen: 512 });

213

214

// KMAC with hex key

215

const kmac3 = new jsSHA("KMAC128", "HEX", {

216

kmacKey: { value: "deadbeefcafebabe", format: "HEX" }

217

});

218

kmac3.update("48656c6c6f"); // "Hello" in hex

219

const mac3 = kmac3.getHash("UINT8ARRAY", { outputLen: 256 });

220

221

// KMAC with ArrayBuffer key

222

const keyBuffer = new TextEncoder().encode("binary-key").buffer;

223

const kmac4 = new jsSHA("KMAC256", "ARRAYBUFFER", {

224

kmacKey: { value: keyBuffer, format: "ARRAYBUFFER" },

225

customization: { value: "FileIntegrity", format: "TEXT" }

226

});

227

const messageBuffer = new TextEncoder().encode("File content").buffer;

228

kmac4.update(messageBuffer);

229

const mac4 = kmac4.getHash("ARRAYBUFFER", { outputLen: 384 });

230

231

// API authentication with KMAC

232

function authenticateAPICall(endpoint: string, payload: string, apiKey: string): string {

233

const message = `${endpoint}:${payload}`;

234

const kmac = new jsSHA("KMAC256", "TEXT", {

235

kmacKey: { value: apiKey, format: "TEXT" },

236

customization: { value: "APIAuth-v1", format: "TEXT" }

237

});

238

kmac.update(message);

239

return kmac.getHash("B64", { outputLen: 256 });

240

}

241

```

242

243

## Output Length Requirements

244

245

All variable-length variants (SHAKE, cSHAKE, KMAC) require the `outputLen` parameter in the `getHash()` method. Note that `shakeLen` is a deprecated alias for `outputLen` and should not be used in new code:

246

247

```typescript

248

// outputLen is required and specifies output length in BITS

249

const shake = new jsSHA("SHAKE128", "TEXT");

250

shake.update("Hello");

251

252

// Valid output lengths (multiples of 8 bits)

253

const hash128 = shake.getHash("HEX", { outputLen: 128 }); // 16 bytes

254

const hash256 = shake.getHash("HEX", { outputLen: 256 }); // 32 bytes

255

const hash512 = shake.getHash("HEX", { outputLen: 512 }); // 64 bytes

256

const hash1024 = shake.getHash("HEX", { outputLen: 1024 }); // 128 bytes

257

258

// Invalid - outputLen must be specified

259

try {

260

const invalid = shake.getHash("HEX"); // Error: outputLen required

261

} catch (error) {

262

console.error("outputLen parameter is required for variable-length variants");

263

}

264

265

// Invalid - outputLen must be multiple of 8

266

try {

267

const invalid = shake.getHash("HEX", { outputLen: 129 }); // Error: not multiple of 8

268

} catch (error) {

269

console.error("outputLen must be multiple of 8 bits");

270

}

271

```

272

273

## Security Levels and Recommendations

274

275

### SHAKE Security Levels

276

277

- **SHAKE128**: 128-bit security level, suitable for most applications

278

- **SHAKE256**: 256-bit security level, recommended for high-security applications

279

280

### Output Length Guidelines

281

282

- **Minimum Output**: Use at least the security level length (128 bits for SHAKE128, 256 bits for SHAKE256)

283

- **Authentication**: For KMAC, use output lengths of 256 bits or more for strong authentication

284

- **Key Derivation**: For key derivation, match the output length to the required key size

285

- **Digital Signatures**: Use output lengths appropriate for the signature scheme

286

287

### Customization Best Practices

288

289

```typescript

290

// Good: Descriptive customization strings

291

const cshake = new jsSHA("CSHAKE256", "TEXT", {

292

funcName: { value: "KeyDerivation", format: "TEXT" },

293

customization: { value: "MyApp-UserAuth-v1.2", format: "TEXT" }

294

});

295

296

// Good: Domain-specific KMAC customization

297

const kmac = new jsSHA("KMAC256", "TEXT", {

298

kmacKey: { value: "secret", format: "TEXT" },

299

customization: { value: "FileIntegrity-SHA3", format: "TEXT" }

300

});

301

302

// Avoid: Empty or generic customization strings reduce security benefits

303

```

304

305

## Advanced Use Cases

306

307

### Key Derivation Function (KDF)

308

309

```typescript

310

import jsSHA from "jssha";

311

312

function deriveKey(masterKey: string, salt: string, info: string, keyLength: number): Uint8Array {

313

const cshake = new jsSHA("CSHAKE256", "TEXT", {

314

funcName: { value: "KeyDerivation", format: "TEXT" },

315

customization: { value: `${salt}:${info}`, format: "TEXT" }

316

});

317

cshake.update(masterKey);

318

return cshake.getHash("UINT8ARRAY", { outputLen: keyLength * 8 });

319

}

320

321

const derivedKey = deriveKey("master-secret", "random-salt", "encryption-key", 32);

322

```

323

324

### Stream Cipher Keystream Generation

325

326

```typescript

327

import jsSHA from "jssha";

328

329

function generateKeystream(seed: string, nonce: string, length: number): Uint8Array {

330

const shake = new jsSHA("SHAKE256", "TEXT");

331

shake.update(`${seed}:${nonce}`);

332

return shake.getHash("UINT8ARRAY", { outputLen: length * 8 });

333

}

334

335

const keystream = generateKeystream("cipher-seed", "unique-nonce", 1024);

336

```

337

338

### Merkle Tree Construction

339

340

```typescript

341

import jsSHA from "jssha";

342

343

function hashNode(left: string, right: string): string {

344

const cshake = new jsSHA("CSHAKE256", "TEXT", {

345

funcName: { value: "MerkleNode", format: "TEXT" },

346

customization: { value: "MerkleTree-v1", format: "TEXT" }

347

});

348

cshake.update(`${left}${right}`);

349

return cshake.getHash("HEX", { outputLen: 256 });

350

}

351

352

const rootHash = hashNode(hashNode("leaf1", "leaf2"), hashNode("leaf3", "leaf4"));

353

```

354

355

## Error Handling

356

357

Advanced SHA-3 variants have specific requirements that can cause errors:

358

359

```typescript

360

// KMAC requires kmacKey

361

try {

362

const invalid = new jsSHA("KMAC128", "TEXT", {}); // Error: kmacKey required

363

} catch (error) {

364

console.error("KMAC variants require kmacKey parameter");

365

}

366

367

// Variable-length variants require outputLen

368

try {

369

const shake = new jsSHA("SHAKE128", "TEXT");

370

shake.update("Hello");

371

const invalid = shake.getHash("HEX"); // Error: outputLen required

372

} catch (error) {

373

console.error("Variable-length variants require outputLen parameter");

374

}

375

376

// numRounds not supported with some variants

377

try {

378

const invalid = new jsSHA("CSHAKE256", "TEXT", {

379

numRounds: 2, // Error: numRounds not valid with cSHAKE

380

customization: { value: "test", format: "TEXT" }

381

});

382

} catch (error) {

383

console.error("numRounds parameter not supported with MAC or cSHAKE variants");

384

}

385

```

386

387

## Compatibility Notes

388

389

- **NIST Standards**: cSHAKE and KMAC implementations follow NIST SP 800-185 specifications

390

- **Test Vectors**: Implementation passes official NIST test vectors for all variants

391

- **Interoperability**: Compatible with other standard-compliant SHA-3 implementations

392

- **Performance**: Variable-length variants may have different performance characteristics than fixed-length variants