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