0
# Hashing
1
2
Cryptographic hash functions provide secure message digests for data integrity, fingerprinting, and key derivation. The library includes BLAKE2b (generic hash), SHA-256, and SHA-512 implementations with both one-shot and streaming operations.
3
4
## Generic Hash (BLAKE2b)
5
6
BLAKE2b is a high-performance cryptographic hash function that's faster than SHA-3 and more secure than SHA-2. It supports keyed hashing and variable output lengths.
7
8
### Key Generation
9
10
```javascript { .api }
11
/**
12
* Generate a random key for BLAKE2b keyed hashing
13
* @returns Uint8Array - Random key (up to 64 bytes)
14
*/
15
function crypto_generichash_keygen(): Uint8Array;
16
```
17
18
### One-Shot Hashing
19
20
```javascript { .api }
21
/**
22
* Compute BLAKE2b hash with optional key and custom length
23
* @param hash_length - Desired output length (1-64 bytes, default 32)
24
* @param message - Data to hash
25
* @param key - Optional key for keyed hashing (null for unkeyed)
26
* @returns Uint8Array - Hash digest
27
*/
28
function crypto_generichash(
29
hash_length: number,
30
message: Uint8Array,
31
key?: Uint8Array | null
32
): Uint8Array;
33
```
34
35
### Streaming Operations
36
37
```javascript { .api }
38
/**
39
* Initialize BLAKE2b streaming state
40
* @param key - Optional key for keyed hashing
41
* @param hash_length - Output length (1-64 bytes)
42
* @returns Uint8Array - State object for streaming
43
*/
44
function crypto_generichash_init(
45
key: Uint8Array | null,
46
hash_length: number
47
): Uint8Array;
48
49
/**
50
* Update BLAKE2b state with data chunk
51
* @param state_address - State from init function
52
* @param message_chunk - Data chunk to hash
53
*/
54
function crypto_generichash_update(
55
state_address: any,
56
message_chunk: Uint8Array
57
): void;
58
59
/**
60
* Finalize BLAKE2b and return hash digest
61
* @param state_address - State from init/update functions
62
* @param hash_length - Output length (must match init)
63
* @returns Uint8Array - Final hash digest
64
*/
65
function crypto_generichash_final(
66
state_address: any,
67
hash_length: number
68
): Uint8Array;
69
```
70
71
### BLAKE2b Constants
72
73
```javascript { .api }
74
const crypto_generichash_BYTES: number; // 32 (default output size)
75
const crypto_generichash_BYTES_MIN: number; // 16 (minimum output size)
76
const crypto_generichash_BYTES_MAX: number; // 64 (maximum output size)
77
const crypto_generichash_KEYBYTES: number; // 32 (default key size)
78
const crypto_generichash_KEYBYTES_MIN: number; // 16 (minimum key size)
79
const crypto_generichash_KEYBYTES_MAX: number; // 64 (maximum key size)
80
81
// BLAKE2b specific constants
82
const crypto_generichash_blake2b_BYTES: number; // 32
83
const crypto_generichash_blake2b_BYTES_MIN: number; // 16
84
const crypto_generichash_blake2b_BYTES_MAX: number; // 64
85
const crypto_generichash_blake2b_KEYBYTES: number; // 32
86
const crypto_generichash_blake2b_KEYBYTES_MIN: number; // 16
87
const crypto_generichash_blake2b_KEYBYTES_MAX: number; // 64
88
const crypto_generichash_blake2b_SALTBYTES: number; // 16
89
const crypto_generichash_blake2b_PERSONALBYTES: number; // 16
90
```
91
92
### BLAKE2b with Salt and Personal Parameters
93
94
```javascript { .api }
95
/**
96
* BLAKE2b with salt and personalization parameters
97
* @param subkey_len - Output length
98
* @param key - Optional key
99
* @param id - Salt parameter (16 bytes or null)
100
* @param ctx - Personalization parameter (16 bytes or null)
101
* @returns Uint8Array - Hash digest
102
*/
103
function crypto_generichash_blake2b_salt_personal(
104
subkey_len: number,
105
key: Uint8Array | null,
106
id: Uint8Array | null,
107
ctx: Uint8Array | null
108
): Uint8Array;
109
```
110
111
## SHA-256
112
113
Secure Hash Algorithm 256-bit, widely used and standardized hash function.
114
115
### One-Shot Hashing
116
117
```javascript { .api }
118
/**
119
* Compute SHA-256 hash
120
* @param message - Data to hash
121
* @returns Uint8Array - 32-byte hash digest
122
*/
123
function crypto_hash_sha256(message: Uint8Array): Uint8Array;
124
```
125
126
### Streaming Operations
127
128
```javascript { .api }
129
/**
130
* Initialize SHA-256 streaming state
131
* @returns Uint8Array - State object for streaming
132
*/
133
function crypto_hash_sha256_init(): Uint8Array;
134
135
/**
136
* Update SHA-256 state with data chunk
137
* @param state_address - State from init function
138
* @param message_chunk - Data chunk to hash
139
*/
140
function crypto_hash_sha256_update(
141
state_address: any,
142
message_chunk: Uint8Array
143
): void;
144
145
/**
146
* Finalize SHA-256 and return hash digest
147
* @param state_address - State from init/update functions
148
* @returns Uint8Array - 32-byte hash digest
149
*/
150
function crypto_hash_sha256_final(state_address: any): Uint8Array;
151
```
152
153
### SHA-256 Constants
154
155
```javascript { .api }
156
const crypto_hash_sha256_BYTES: number; // 32 (output size)
157
```
158
159
## SHA-512
160
161
Secure Hash Algorithm 512-bit, provides higher security margin than SHA-256.
162
163
### One-Shot Hashing
164
165
```javascript { .api }
166
/**
167
* Compute SHA-512 hash
168
* @param message - Data to hash
169
* @returns Uint8Array - 64-byte hash digest
170
*/
171
function crypto_hash_sha512(message: Uint8Array): Uint8Array;
172
```
173
174
### Streaming Operations
175
176
```javascript { .api }
177
/**
178
* Initialize SHA-512 streaming state
179
* @returns Uint8Array - State object for streaming
180
*/
181
function crypto_hash_sha512_init(): Uint8Array;
182
183
/**
184
* Update SHA-512 state with data chunk
185
* @param state_address - State from init function
186
* @param message_chunk - Data chunk to hash
187
*/
188
function crypto_hash_sha512_update(
189
state_address: any,
190
message_chunk: Uint8Array
191
): void;
192
193
/**
194
* Finalize SHA-512 and return hash digest
195
* @param state_address - State from init/update functions
196
* @returns Uint8Array - 64-byte hash digest
197
*/
198
function crypto_hash_sha512_final(state_address: any): Uint8Array;
199
```
200
201
### SHA-512 Constants
202
203
```javascript { .api }
204
const crypto_hash_sha512_BYTES: number; // 64 (output size)
205
```
206
207
## Generic Hash (Default)
208
209
The generic hash function defaults to SHA-512.
210
211
```javascript { .api }
212
/**
213
* Compute generic hash (SHA-512)
214
* @param message - Data to hash
215
* @returns Uint8Array - 64-byte hash digest
216
*/
217
function crypto_hash(message: Uint8Array): Uint8Array;
218
219
const crypto_hash_BYTES: number; // 64 (output size)
220
```
221
222
## Usage Examples
223
224
### Basic Hashing
225
226
```javascript
227
import _sodium from 'libsodium-wrappers-sumo';
228
await _sodium.ready;
229
const sodium = _sodium;
230
231
// Basic BLAKE2b hashing
232
const message = sodium.from_string('Hello, World!');
233
234
// Default 32-byte BLAKE2b hash
235
const hash = sodium.crypto_generichash(32, message);
236
console.log('BLAKE2b hash:', sodium.to_hex(hash));
237
238
// SHA-256 hash
239
const sha256 = sodium.crypto_hash_sha256(message);
240
console.log('SHA-256 hash:', sodium.to_hex(sha256));
241
242
// SHA-512 hash
243
const sha512 = sodium.crypto_hash_sha512(message);
244
console.log('SHA-512 hash:', sodium.to_hex(sha512));
245
246
// Generic hash (SHA-512)
247
const genericHash = sodium.crypto_hash(message);
248
console.log('Generic hash equals SHA-512:',
249
sodium.memcmp(sha512, genericHash)); // true
250
```
251
252
### Keyed Hashing with BLAKE2b
253
254
```javascript
255
// Generate key for keyed hashing
256
const key = sodium.crypto_generichash_keygen();
257
const message = sodium.from_string('Keyed message');
258
259
// Keyed BLAKE2b hash
260
const keyedHash = sodium.crypto_generichash(32, message, key);
261
console.log('Keyed hash:', sodium.to_hex(keyedHash));
262
263
// Same message with different key produces different hash
264
const differentKey = sodium.crypto_generichash_keygen();
265
const differentHash = sodium.crypto_generichash(32, message, differentKey);
266
267
console.log('Same message, different key produces different hash:',
268
!sodium.memcmp(keyedHash, differentHash)); // true
269
```
270
271
### Variable Length BLAKE2b
272
273
```javascript
274
const message = sodium.from_string('Variable length hashing');
275
276
// Different output lengths
277
const hash16 = sodium.crypto_generichash(16, message); // 16 bytes
278
const hash32 = sodium.crypto_generichash(32, message); // 32 bytes
279
const hash64 = sodium.crypto_generichash(64, message); // 64 bytes
280
281
console.log('16-byte hash:', sodium.to_hex(hash16));
282
console.log('32-byte hash:', sodium.to_hex(hash32));
283
console.log('64-byte hash:', sodium.to_hex(hash64));
284
```
285
286
### Streaming Hash for Large Data
287
288
```javascript
289
function hashLargeData(chunks, algorithm = 'blake2b') {
290
let state;
291
292
// Initialize based on algorithm
293
switch (algorithm) {
294
case 'blake2b':
295
state = sodium.crypto_generichash_init(null, 32);
296
break;
297
case 'sha256':
298
state = sodium.crypto_hash_sha256_init();
299
break;
300
case 'sha512':
301
state = sodium.crypto_hash_sha512_init();
302
break;
303
default:
304
throw new Error('Unsupported algorithm');
305
}
306
307
// Process chunks
308
for (const chunk of chunks) {
309
switch (algorithm) {
310
case 'blake2b':
311
sodium.crypto_generichash_update(state, chunk);
312
break;
313
case 'sha256':
314
sodium.crypto_hash_sha256_update(state, chunk);
315
break;
316
case 'sha512':
317
sodium.crypto_hash_sha512_update(state, chunk);
318
break;
319
}
320
}
321
322
// Finalize
323
switch (algorithm) {
324
case 'blake2b':
325
return sodium.crypto_generichash_final(state, 32);
326
case 'sha256':
327
return sodium.crypto_hash_sha256_final(state);
328
case 'sha512':
329
return sodium.crypto_hash_sha512_final(state);
330
}
331
}
332
333
// Create large data set
334
const largeData = new Uint8Array(10 * 1024 * 1024); // 10MB
335
sodium.randombytes_buf_into(largeData);
336
337
// Split into chunks
338
const chunkSize = 64 * 1024; // 64KB chunks
339
const chunks = [];
340
for (let i = 0; i < largeData.length; i += chunkSize) {
341
chunks.push(largeData.subarray(i, i + chunkSize));
342
}
343
344
// Hash with different algorithms
345
console.time('BLAKE2b streaming');
346
const blake2bHash = hashLargeData(chunks, 'blake2b');
347
console.timeEnd('BLAKE2b streaming');
348
349
console.time('SHA-256 streaming');
350
const sha256Hash = hashLargeData(chunks, 'sha256');
351
console.timeEnd('SHA-256 streaming');
352
353
console.time('SHA-512 streaming');
354
const sha512Hash = hashLargeData(chunks, 'sha512');
355
console.timeEnd('SHA-512 streaming');
356
357
console.log('BLAKE2b result:', sodium.to_hex(blake2bHash));
358
console.log('SHA-256 result:', sodium.to_hex(sha256Hash));
359
```
360
361
### File Integrity Verification
362
363
```javascript
364
class FileIntegrity {
365
constructor() {
366
this.checksums = new Map();
367
}
368
369
// Store file hash
370
addFile(filename, data) {
371
const hash = sodium.crypto_generichash(32, data);
372
this.checksums.set(filename, {
373
hash: sodium.to_hex(hash),
374
size: data.length,
375
timestamp: new Date().toISOString()
376
});
377
return sodium.to_hex(hash);
378
}
379
380
// Verify file integrity
381
verifyFile(filename, data) {
382
const stored = this.checksums.get(filename);
383
if (!stored) {
384
return { valid: false, error: 'File not in registry' };
385
}
386
387
if (data.length !== stored.size) {
388
return { valid: false, error: 'Size mismatch' };
389
}
390
391
const currentHash = sodium.crypto_generichash(32, data);
392
const currentHashHex = sodium.to_hex(currentHash);
393
394
return {
395
valid: currentHashHex === stored.hash,
396
storedHash: stored.hash,
397
currentHash: currentHashHex,
398
timestamp: stored.timestamp
399
};
400
}
401
402
// Export registry
403
exportRegistry() {
404
return JSON.stringify(Object.fromEntries(this.checksums));
405
}
406
407
// Import registry
408
importRegistry(json) {
409
const data = JSON.parse(json);
410
this.checksums = new Map(Object.entries(data));
411
}
412
}
413
414
// Usage
415
const integrity = new FileIntegrity();
416
const fileData = sodium.from_string('Important file content');
417
418
// Add file to registry
419
const hash = integrity.addFile('document.txt', fileData);
420
console.log('File hash:', hash);
421
422
// Verify file later
423
const verification = integrity.verifyFile('document.txt', fileData);
424
console.log('File is valid:', verification.valid); // true
425
426
// Test with modified file
427
const modifiedData = sodium.from_string('Modified file content');
428
const modifiedVerification = integrity.verifyFile('document.txt', modifiedData);
429
console.log('Modified file is valid:', modifiedVerification.valid); // false
430
```
431
432
## Password Hashing (Argon2)
433
434
Secure password hashing using Argon2i and Argon2id algorithms for storing user passwords and deriving keys from passwords. **Never use regular hash functions for passwords.**
435
436
### Password-Based Key Derivation
437
438
```javascript { .api }
439
/**
440
* Derive a key from a password using Argon2
441
* @param keyLength - Length of derived key (16-4294967295)
442
* @param password - Password to derive from
443
* @param salt - Random salt (crypto_pwhash_SALTBYTES)
444
* @param opsLimit - CPU/time cost parameter
445
* @param memLimit - Memory cost parameter (bytes)
446
* @param algorithm - Algorithm (ALG_ARGON2I13 or ALG_ARGON2ID13)
447
* @returns Uint8Array - Derived key
448
*/
449
function crypto_pwhash(
450
keyLength: number,
451
password: Uint8Array,
452
salt: Uint8Array,
453
opsLimit: number,
454
memLimit: number,
455
algorithm: number
456
): Uint8Array;
457
```
458
459
### Password String Hashing
460
461
```javascript { .api }
462
/**
463
* Hash password to string format for storage
464
* @param password - Password to hash
465
* @param opsLimit - CPU/time cost parameter
466
* @param memLimit - Memory cost parameter (bytes)
467
* @returns string - Formatted hash string for storage
468
*/
469
function crypto_pwhash_str(
470
password: Uint8Array,
471
opsLimit: number,
472
memLimit: number
473
): string;
474
475
/**
476
* Verify password against stored hash string
477
* @param hashedPassword - Previously computed hash string
478
* @param password - Password to verify
479
* @returns boolean - True if password matches
480
*/
481
function crypto_pwhash_str_verify(
482
hashedPassword: string,
483
password: Uint8Array
484
): boolean;
485
486
/**
487
* Check if stored hash needs rehashing (parameters changed)
488
* @param hashedPassword - Previously computed hash string
489
* @param opsLimit - Current CPU cost parameter
490
* @param memLimit - Current memory cost parameter
491
* @returns boolean - True if rehashing recommended
492
*/
493
function crypto_pwhash_str_needs_rehash(
494
hashedPassword: string,
495
opsLimit: number,
496
memLimit: number
497
): boolean;
498
```
499
500
### Scrypt Legacy Support
501
502
```javascript { .api }
503
/**
504
* Legacy scrypt-based password hashing
505
* @param keyLength - Length of derived key
506
* @param password - Password to derive from
507
* @param salt - Random salt (32 bytes)
508
* @param opsLimit - CPU/time cost parameter
509
* @param memLimit - Memory cost parameter
510
* @returns Uint8Array - Derived key
511
*/
512
function crypto_pwhash_scryptsalsa208sha256(
513
keyLength: number,
514
password: Uint8Array,
515
salt: Uint8Array,
516
opsLimit: number,
517
memLimit: number
518
): Uint8Array;
519
520
/**
521
* Legacy scrypt string hashing
522
* @param password - Password to hash
523
* @param opsLimit - CPU cost parameter
524
* @param memLimit - Memory cost parameter
525
* @returns string - Formatted hash string
526
*/
527
function crypto_pwhash_scryptsalsa208sha256_str(
528
password: Uint8Array,
529
opsLimit: number,
530
memLimit: number
531
): string;
532
533
/**
534
* Verify password against scrypt hash string
535
* @param hashedPassword - Previously computed scrypt hash
536
* @param password - Password to verify
537
* @returns boolean - True if password matches
538
*/
539
function crypto_pwhash_scryptsalsa208sha256_str_verify(
540
hashedPassword: string,
541
password: Uint8Array
542
): boolean;
543
```
544
545
### Password Hashing Constants
546
547
```javascript { .api }
548
// Argon2 algorithm identifiers
549
const crypto_pwhash_ALG_ARGON2I13: number; // 1 (Argon2i)
550
const crypto_pwhash_ALG_ARGON2ID13: number; // 2 (Argon2id - recommended)
551
const crypto_pwhash_ALG_DEFAULT: number; // Same as ALG_ARGON2ID13
552
553
// Salt and output size limits
554
const crypto_pwhash_SALTBYTES: number; // 32 (salt size)
555
const crypto_pwhash_STRBYTES: number; // 102 (string hash length)
556
const crypto_pwhash_STRPREFIX: string; // "$argon2id$" (string prefix)
557
const crypto_pwhash_BYTES_MIN: number; // 16 (min key length)
558
const crypto_pwhash_BYTES_MAX: number; // 4294967295 (max key length)
559
const crypto_pwhash_PASSWD_MIN: number; // 0 (min password length)
560
const crypto_pwhash_PASSWD_MAX: number; // 4294967295 (max password length)
561
562
// Computational limits - Argon2
563
const crypto_pwhash_OPSLIMIT_INTERACTIVE: number; // 4 (fast login)
564
const crypto_pwhash_OPSLIMIT_MODERATE: number; // 6 (moderate security)
565
const crypto_pwhash_OPSLIMIT_SENSITIVE: number; // 8 (high security)
566
const crypto_pwhash_MEMLIMIT_INTERACTIVE: number; // 67108864 (64MB)
567
const crypto_pwhash_MEMLIMIT_MODERATE: number; // 268435456 (256MB)
568
const crypto_pwhash_MEMLIMIT_SENSITIVE: number; // 1073741824 (1GB)
569
570
// Computational limits - Scrypt legacy
571
const crypto_pwhash_scryptsalsa208sha256_SALTBYTES: number; // 32
572
const crypto_pwhash_scryptsalsa208sha256_STRBYTES: number; // 102
573
const crypto_pwhash_scryptsalsa208sha256_STRPREFIX: string; // "$7$"
574
const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE: number; // 32768
575
const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE: number; // 33554432
576
const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE: number; // 16777216
577
const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE: number; // 1073741824
578
```
579
580
### Usage Examples
581
582
```javascript
583
// User registration - hash password for storage
584
const password = sodium.from_string('user_password123');
585
586
// String-based hashing (recommended for most use cases)
587
const hashedPassword = sodium.crypto_pwhash_str(
588
password,
589
sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
590
sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
591
);
592
593
// Store hashedPassword in database
594
console.log('Store this hash:', hashedPassword);
595
596
// User login - verify password
597
const loginPassword = sodium.from_string('user_password123');
598
const isValid = sodium.crypto_pwhash_str_verify(hashedPassword, loginPassword);
599
console.log('Password is valid:', isValid); // true
600
601
// Key derivation from password (for encryption keys)
602
const salt = sodium.randombytes_buf(sodium.crypto_pwhash_SALTBYTES);
603
const encryptionKey = sodium.crypto_pwhash(
604
32, // 32-byte key for ChaCha20
605
password,
606
salt,
607
sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
608
sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE,
609
sodium.crypto_pwhash_ALG_ARGON2ID13
610
);
611
612
// Use encryptionKey for symmetric encryption
613
// Store salt alongside encrypted data for key recovery
614
```
615
616
### BLAKE2b with Personalization
617
618
```javascript
619
// BLAKE2b with salt and personalization for domain separation
620
const message = sodium.from_string('Domain-specific message');
621
const salt = sodium.from_string('app_salt_v1.0'); // 16 bytes max
622
const personal = sodium.from_string('user_profile_'); // 16 bytes max
623
624
// Pad to required lengths
625
const saltPadded = new Uint8Array(16);
626
const personalPadded = new Uint8Array(16);
627
saltPadded.set(salt.subarray(0, Math.min(salt.length, 16)));
628
personalPadded.set(personal.subarray(0, Math.min(personal.length, 16)));
629
630
const domainHash = sodium.crypto_generichash_blake2b_salt_personal(
631
32, null, saltPadded, personalPadded
632
);
633
634
console.log('Domain-separated hash:', sodium.to_hex(domainHash));
635
```
636
637
### Performance Comparison
638
639
```javascript
640
function benchmarkHashing() {
641
const message = new Uint8Array(1024 * 1024); // 1MB
642
sodium.randombytes_buf_into(message);
643
644
const iterations = 10;
645
646
// BLAKE2b
647
console.time(`BLAKE2b ${iterations}x1MB`);
648
for (let i = 0; i < iterations; i++) {
649
sodium.crypto_generichash(32, message);
650
}
651
console.timeEnd(`BLAKE2b ${iterations}x1MB`);
652
653
// SHA-256
654
console.time(`SHA-256 ${iterations}x1MB`);
655
for (let i = 0; i < iterations; i++) {
656
sodium.crypto_hash_sha256(message);
657
}
658
console.timeEnd(`SHA-256 ${iterations}x1MB`);
659
660
// SHA-512
661
console.time(`SHA-512 ${iterations}x1MB`);
662
for (let i = 0; i < iterations; i++) {
663
sodium.crypto_hash_sha512(message);
664
}
665
console.timeEnd(`SHA-512 ${iterations}x1MB`);
666
}
667
668
benchmarkHashing();
669
```
670
671
## Short Hash (SipHash)
672
673
Fast non-cryptographic hash functions for hash tables, checksums, and other applications where speed is more important than cryptographic security.
674
675
### Key Generation
676
677
```javascript { .api }
678
/**
679
* Generate random key for short hash functions
680
* @returns Uint8Array - 16-byte key for SipHash
681
*/
682
function crypto_shorthash_keygen(): Uint8Array;
683
```
684
685
### Short Hash Functions
686
687
```javascript { .api }
688
/**
689
* Compute SipHash-2-4 (default short hash)
690
* @param message - Data to hash
691
* @param key - 16-byte secret key
692
* @returns Uint8Array - 8-byte hash output
693
*/
694
function crypto_shorthash(
695
message: Uint8Array,
696
key: Uint8Array
697
): Uint8Array;
698
699
/**
700
* Compute SipHash-X-2-4 (128-bit output variant)
701
* @param message - Data to hash
702
* @param key - 16-byte secret key
703
* @returns Uint8Array - 16-byte hash output
704
*/
705
function crypto_shorthash_siphashx24(
706
message: Uint8Array,
707
key: Uint8Array
708
): Uint8Array;
709
```
710
711
### Short Hash Constants
712
713
```javascript { .api }
714
const crypto_shorthash_BYTES: number; // 8 (SipHash-2-4 output)
715
const crypto_shorthash_KEYBYTES: number; // 16 (key size)
716
const crypto_shorthash_siphashx24_BYTES: number; // 16 (SipHashX-2-4 output)
717
const crypto_shorthash_siphashx24_KEYBYTES: number; // 16 (key size)
718
```
719
720
### Usage Examples
721
722
```javascript
723
// Generate key for short hash operations
724
const shortHashKey = sodium.crypto_shorthash_keygen();
725
726
// Hash table usage example
727
class FastHashMap {
728
constructor() {
729
this.buckets = new Array(1024).fill(null).map(() => []);
730
this.key = sodium.crypto_shorthash_keygen();
731
}
732
733
getBucket(key) {
734
const keyBytes = sodium.from_string(key);
735
const hash = sodium.crypto_shorthash(keyBytes, this.key);
736
// Convert first 4 bytes to bucket index
737
const bucket = new DataView(hash.buffer).getUint32(0, true) % this.buckets.length;
738
return this.buckets[bucket];
739
}
740
741
set(key, value) {
742
const bucket = this.getBucket(key);
743
const existing = bucket.find(item => item.key === key);
744
if (existing) {
745
existing.value = value;
746
} else {
747
bucket.push({ key, value });
748
}
749
}
750
751
get(key) {
752
const bucket = this.getBucket(key);
753
const item = bucket.find(item => item.key === key);
754
return item ? item.value : undefined;
755
}
756
}
757
758
// Usage
759
const hashMap = new FastHashMap();
760
hashMap.set('user:123', { name: 'Alice', email: 'alice@example.com' });
761
hashMap.set('user:456', { name: 'Bob', email: 'bob@example.com' });
762
763
console.log(hashMap.get('user:123')); // { name: 'Alice', email: 'alice@example.com' }
764
765
// Checksums for data integrity (non-cryptographic)
766
const data1 = sodium.from_string('Version 1.0 data');
767
const data2 = sodium.from_string('Version 1.1 data');
768
769
const checksum1 = sodium.crypto_shorthash(data1, shortHashKey);
770
const checksum2 = sodium.crypto_shorthash(data2, shortHashKey);
771
772
console.log('Data1 checksum:', sodium.to_hex(checksum1));
773
console.log('Data2 checksum:', sodium.to_hex(checksum2));
774
console.log('Checksums match:', sodium.memcmp(checksum1, checksum2)); // false
775
```
776
777
## Security Considerations
778
779
- **Collision Resistance**: All provided hash functions are cryptographically secure
780
- **Preimage Resistance**: Computationally infeasible to reverse hash functions
781
- **Avalanche Effect**: Small input changes produce drastically different outputs
782
- **Algorithm Selection**: BLAKE2b is fastest, SHA-256/512 for standards compliance
783
- **Keyed Hashing**: Use BLAKE2b with keys for MAC-like properties (though HMAC is preferred for MACs)
784
- **Salt Usage**: Use random salts for password-related hashing (prefer crypto_pwhash)
785
786
## Algorithm Selection Guide
787
788
- **BLAKE2b**: Best performance, variable output length, optional keying
789
- **SHA-256**: Standards compliance, widely supported
790
- **SHA-512**: Higher security margin, good performance on 64-bit systems
791
- **Keyed BLAKE2b**: Fast alternative to HMAC for some use cases
792
- **Streaming**: Use for large files or memory-constrained environments
793
794
BLAKE2b is generally recommended for new applications due to its superior performance and security properties.