or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aead.mdauth.mdbox.mdhash.mdindex.mdkey-derivation.mdsecretbox.mdsign.mdstreaming.mdutilities.md
tile.json

hash.mddocs/

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.