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

utilities.mddocs/

0

# Utilities and Helpers

1

2

Utility functions provide essential support for cryptographic operations including random number generation, data conversion, memory operations, and various helper functions for working with cryptographic data.

3

4

## Random Number Generation

5

6

Cryptographically secure random number generation for keys, nonces, and other security-critical values.

7

8

### Random Bytes

9

10

```javascript { .api }

11

/**

12

* Generate cryptographically secure random bytes

13

* @param length - Number of bytes to generate

14

* @returns Uint8Array - Random bytes

15

*/

16

function randombytes_buf(length: number): Uint8Array;

17

18

/**

19

* Fill existing buffer with random bytes

20

* @param buffer - Buffer to fill with random data

21

*/

22

function randombytes_buf_into(buffer: Uint8Array): void;

23

24

/**

25

* Generate deterministic random bytes from seed

26

* @param length - Number of bytes to generate

27

* @param seed - 32-byte seed for deterministic generation

28

* @returns Uint8Array - Deterministic random bytes

29

*/

30

function randombytes_buf_deterministic(

31

length: number,

32

seed: Uint8Array

33

): Uint8Array;

34

```

35

36

### Random Numbers

37

38

```javascript { .api }

39

/**

40

* Generate random 32-bit unsigned integer

41

* @returns number - Random 32-bit value

42

*/

43

function randombytes_random(): number;

44

45

/**

46

* Generate random integer in range [0, upper_bound)

47

* @param upper_bound - Exclusive upper bound (must be > 0)

48

* @returns number - Random integer in range

49

*/

50

function randombytes_uniform(upper_bound: number): number;

51

```

52

53

### Random Number System Control

54

55

```javascript { .api }

56

/**

57

* Stir the random number generator

58

*/

59

function randombytes_stir(): void;

60

61

/**

62

* Close the random number generator

63

*/

64

function randombytes_close(): void;

65

66

/**

67

* Set random number generator implementation

68

* @param implementation - Custom RNG implementation

69

*/

70

function randombytes_set_implementation(implementation: any): void;

71

```

72

73

## Data Conversion

74

75

Functions for converting between different data representations commonly used in cryptographic operations.

76

77

### String Conversion

78

79

```javascript { .api }

80

/**

81

* Convert UTF-8 string to Uint8Array

82

* @param string - UTF-8 string to convert

83

* @returns Uint8Array - String as bytes

84

*/

85

function from_string(string: string): Uint8Array;

86

87

/**

88

* Convert Uint8Array to UTF-8 string

89

* @param input - Bytes to convert to string

90

* @returns string - UTF-8 string

91

*/

92

function to_string(input: Uint8Array): string;

93

```

94

95

### Hexadecimal Conversion

96

97

```javascript { .api }

98

/**

99

* Convert hexadecimal string to Uint8Array

100

* @param hex_string - Hex string to convert (case insensitive)

101

* @returns Uint8Array - Decoded bytes

102

*/

103

function from_hex(hex_string: string): Uint8Array;

104

105

/**

106

* Convert Uint8Array to hexadecimal string

107

* @param input - Bytes to convert to hex

108

* @returns string - Lowercase hex string

109

*/

110

function to_hex(input: Uint8Array): string;

111

```

112

113

### Base64 Conversion

114

115

```javascript { .api }

116

/**

117

* Convert Base64 string to Uint8Array

118

* @param input - Base64 string to decode

119

* @param variant - Base64 variant (optional)

120

* @returns Uint8Array - Decoded bytes

121

*/

122

function from_base64(input: string, variant?: number): Uint8Array;

123

124

/**

125

* Convert Uint8Array to Base64 string

126

* @param input - Bytes to encode

127

* @param variant - Base64 variant (optional)

128

* @returns string - Base64 encoded string

129

*/

130

function to_base64(input: Uint8Array, variant?: number): string;

131

```

132

133

### Base64 Variants

134

135

```javascript { .api }

136

const base64_variants = {

137

ORIGINAL: 1, // Standard Base64 with padding

138

ORIGINAL_NO_PADDING: 3,// Standard Base64 without padding

139

URLSAFE: 5, // URL-safe Base64 with padding

140

URLSAFE_NO_PADDING: 7 // URL-safe Base64 without padding (default)

141

};

142

```

143

144

## Memory Operations

145

146

Constant-time memory operations for secure comparison and manipulation.

147

148

### Memory Comparison

149

150

```javascript { .api }

151

/**

152

* Constant-time equality comparison

153

* @param a - First buffer

154

* @param b - Second buffer

155

* @returns boolean - True if buffers are equal

156

*/

157

function memcmp(a: Uint8Array, b: Uint8Array): boolean;

158

159

/**

160

* Constant-time comparison returning -1, 0, or 1

161

* @param a - First buffer

162

* @param b - Second buffer

163

* @returns number - Comparison result (-1, 0, or 1)

164

*/

165

function compare(a: Uint8Array, b: Uint8Array): number;

166

167

/**

168

* Check if buffer contains only zeros (constant-time)

169

* @param buffer - Buffer to check

170

* @returns boolean - True if buffer is all zeros

171

*/

172

function is_zero(buffer: Uint8Array): boolean;

173

```

174

175

### Memory Manipulation

176

177

```javascript { .api }

178

/**

179

* Securely zero out memory

180

* @param buffer - Buffer to zero out

181

*/

182

function memzero(buffer: Uint8Array): void;

183

184

/**

185

* Increment little-endian number in buffer

186

* @param buffer - Buffer containing little-endian number

187

*/

188

function increment(buffer: Uint8Array): void;

189

190

/**

191

* Add two little-endian numbers

192

* @param a - First operand (modified in place)

193

* @param b - Second operand

194

*/

195

function add(a: Uint8Array, b: Uint8Array): void;

196

```

197

198

### Data Padding

199

200

```javascript { .api }

201

/**

202

* Pad buffer to specified block size using PKCS#7

203

* @param buffer - Buffer to pad

204

* @param blocksize - Target block size

205

* @returns Uint8Array - Padded buffer

206

*/

207

function pad(buffer: Uint8Array, blocksize: number): Uint8Array;

208

209

/**

210

* Remove PKCS#7 padding from buffer

211

* @param buffer - Padded buffer

212

* @param blocksize - Block size used for padding

213

* @returns Uint8Array - Unpadded buffer

214

*/

215

function unpad(buffer: Uint8Array, blocksize: number): Uint8Array;

216

```

217

218

## Verification Functions

219

220

Constant-time verification functions for various data sizes.

221

222

```javascript { .api }

223

/**

224

* Verify 16-byte values (constant-time)

225

* @param a - First 16-byte value

226

* @param b - Second 16-byte value

227

* @returns boolean - True if values are equal

228

*/

229

// Uses crypto_verify_16_BYTES constant (16)

230

231

/**

232

* Verify 32-byte values (constant-time)

233

* @param a - First 32-byte value

234

* @param b - Second 32-byte value

235

* @returns boolean - True if values are equal

236

*/

237

// Uses crypto_verify_32_BYTES constant (32)

238

239

/**

240

* Verify 64-byte values (constant-time)

241

* @param a - First 64-byte value

242

* @param b - Second 64-byte value

243

* @returns boolean - True if values are equal

244

*/

245

// Uses crypto_verify_64_BYTES constant (64)

246

```

247

248

### Verification Constants

249

250

```javascript { .api }

251

const crypto_verify_16_BYTES: number; // 16

252

const crypto_verify_32_BYTES: number; // 32

253

const crypto_verify_64_BYTES: number; // 64

254

```

255

256

## One-Time Authentication

257

258

Fast polynomial authentication using Poly1305.

259

260

### Key Generation

261

262

```javascript { .api }

263

/**

264

* Generate key for one-time authentication

265

* @returns Uint8Array - 32-byte authentication key

266

*/

267

function crypto_onetimeauth_keygen(): Uint8Array;

268

```

269

270

### Authentication

271

272

```javascript { .api }

273

/**

274

* Compute one-time authentication tag

275

* @param message - Data to authenticate

276

* @param key - 32-byte authentication key (use only once!)

277

* @returns Uint8Array - 16-byte authentication tag

278

*/

279

function crypto_onetimeauth(

280

message: Uint8Array,

281

key: Uint8Array

282

): Uint8Array;

283

284

/**

285

* Verify one-time authentication tag

286

* @param hash - Authentication tag to verify

287

* @param message - Original message

288

* @param key - 32-byte authentication key

289

* @returns boolean - True if tag is valid

290

*/

291

function crypto_onetimeauth_verify(

292

hash: Uint8Array,

293

message: Uint8Array,

294

key: Uint8Array

295

): boolean;

296

```

297

298

### Streaming One-Time Auth

299

300

```javascript { .api }

301

/**

302

* Initialize one-time auth streaming

303

* @param key - Authentication key

304

* @returns Uint8Array - State for streaming

305

*/

306

function crypto_onetimeauth_init(key: Uint8Array): Uint8Array;

307

308

/**

309

* Update streaming one-time auth

310

* @param state_address - State from init

311

* @param message_chunk - Data chunk to authenticate

312

*/

313

function crypto_onetimeauth_update(

314

state_address: any,

315

message_chunk: Uint8Array

316

): void;

317

318

/**

319

* Finalize streaming one-time auth

320

* @param state_address - State from init/update

321

* @returns Uint8Array - Authentication tag

322

*/

323

function crypto_onetimeauth_final(state_address: any): Uint8Array;

324

```

325

326

### One-Time Auth Constants

327

328

```javascript { .api }

329

const crypto_onetimeauth_BYTES: number; // 16 (tag length)

330

const crypto_onetimeauth_KEYBYTES: number; // 32 (key length)

331

332

// Poly1305 specific constants

333

const crypto_onetimeauth_poly1305_BYTES: number; // 16

334

const crypto_onetimeauth_poly1305_KEYBYTES: number; // 32

335

```

336

337

## Short Hash

338

339

Fast non-cryptographic hashing for hash tables and checksums.

340

341

### Key Generation

342

343

```javascript { .api }

344

/**

345

* Generate key for short hash function

346

* @returns Uint8Array - 16-byte hash key

347

*/

348

function crypto_shorthash_keygen(): Uint8Array;

349

```

350

351

### Hashing

352

353

```javascript { .api }

354

/**

355

* Compute short hash (SipHash-2-4)

356

* @param message - Data to hash

357

* @param key - 16-byte hash key

358

* @returns Uint8Array - 8-byte hash value

359

*/

360

function crypto_shorthash(

361

message: Uint8Array,

362

key: Uint8Array

363

): Uint8Array;

364

365

/**

366

* Compute SipHashX-2-4 (16-byte output)

367

* @param message - Data to hash

368

* @param key - 16-byte hash key

369

* @returns Uint8Array - 16-byte hash value

370

*/

371

function crypto_shorthash_siphashx24(

372

message: Uint8Array,

373

key: Uint8Array

374

): Uint8Array;

375

```

376

377

### Short Hash Constants

378

379

```javascript { .api }

380

const crypto_shorthash_BYTES: number; // 8 (SipHash-2-4 output)

381

const crypto_shorthash_KEYBYTES: number; // 16 (key length)

382

383

// SipHash-2-4 constants

384

const crypto_shorthash_siphash24_BYTES: number; // 8

385

const crypto_shorthash_siphash24_KEYBYTES: number; // 16

386

387

// SipHashX-2-4 constants

388

const crypto_shorthash_siphashx24_BYTES: number; // 16

389

const crypto_shorthash_siphashx24_KEYBYTES: number; // 16

390

```

391

392

## Library Information

393

394

Functions to get library version and information.

395

396

```javascript { .api }

397

/**

398

* Get sodium library version string

399

* @returns string - Version information

400

*/

401

function sodium_version_string(): string;

402

```

403

404

## Usage Examples

405

406

### Random Number Generation

407

408

```javascript

409

import _sodium from 'libsodium-wrappers-sumo';

410

await _sodium.ready;

411

const sodium = _sodium;

412

413

// Generate random bytes

414

const randomBytes = sodium.randombytes_buf(32);

415

console.log('Random bytes:', sodium.to_hex(randomBytes));

416

417

// Generate random numbers

418

const randomInt = sodium.randombytes_random();

419

const randomRange = sodium.randombytes_uniform(100); // 0-99

420

421

console.log('Random 32-bit int:', randomInt);

422

console.log('Random 0-99:', randomRange);

423

424

// Deterministic random generation

425

const seed = sodium.randombytes_buf(32);

426

const deterministicBytes1 = sodium.randombytes_buf_deterministic(16, seed);

427

const deterministicBytes2 = sodium.randombytes_buf_deterministic(16, seed);

428

429

console.log('Deterministic bytes match:',

430

sodium.memcmp(deterministicBytes1, deterministicBytes2)); // true

431

432

// Fill existing buffer

433

const buffer = new Uint8Array(10);

434

sodium.randombytes_buf_into(buffer);

435

console.log('Filled buffer:', sodium.to_hex(buffer));

436

```

437

438

### Data Conversion

439

440

```javascript

441

// String conversion

442

const message = 'Hello, 世界! 🌍';

443

const messageBytes = sodium.from_string(message);

444

const backToString = sodium.to_string(messageBytes);

445

446

console.log('Original:', message);

447

console.log('Bytes:', sodium.to_hex(messageBytes));

448

console.log('Back to string:', backToString);

449

console.log('Strings match:', message === backToString); // true

450

451

// Hex conversion

452

const hexString = 'deadbeef';

453

const hexBytes = sodium.from_hex(hexString);

454

const backToHex = sodium.to_hex(hexBytes);

455

456

console.log('Hex string:', hexString);

457

console.log('Hex bytes:', hexBytes);

458

console.log('Back to hex:', backToHex);

459

460

// Base64 conversion with variants

461

const data = sodium.randombytes_buf(20);

462

const base64Original = sodium.to_base64(data, sodium.base64_variants.ORIGINAL);

463

const base64UrlSafe = sodium.to_base64(data, sodium.base64_variants.URLSAFE_NO_PADDING);

464

465

console.log('Original Base64:', base64Original);

466

console.log('URL-safe Base64:', base64UrlSafe);

467

468

// Decode back

469

const decodedOriginal = sodium.from_base64(base64Original, sodium.base64_variants.ORIGINAL);

470

const decodedUrlSafe = sodium.from_base64(base64UrlSafe, sodium.base64_variants.URLSAFE_NO_PADDING);

471

472

console.log('Decoded match:', sodium.memcmp(data, decodedOriginal)); // true

473

console.log('URL-safe decoded match:', sodium.memcmp(data, decodedUrlSafe)); // true

474

```

475

476

### Memory Operations

477

478

```javascript

479

// Constant-time comparison

480

const secret1 = sodium.randombytes_buf(16);

481

const secret2 = sodium.randombytes_buf(16);

482

const secret1Copy = new Uint8Array(secret1);

483

484

console.log('Secrets equal:', sodium.memcmp(secret1, secret2)); // false

485

console.log('Secret equals copy:', sodium.memcmp(secret1, secret1Copy)); // true

486

487

// Comparison with ordering

488

const a = sodium.from_hex('0102');

489

const b = sodium.from_hex('0201');

490

const comparison = sodium.compare(a, b);

491

492

console.log('Comparison result:', comparison); // -1 (a < b)

493

494

// Zero checking

495

const zeros = new Uint8Array(16); // All zeros

496

const nonZeros = sodium.randombytes_buf(16);

497

498

console.log('Zeros detected:', sodium.is_zero(zeros)); // true

499

console.log('Non-zeros detected:', !sodium.is_zero(nonZeros)); // true

500

501

// Memory zeroing

502

const sensitive = sodium.from_string('sensitive data');

503

console.log('Before zeroing:', sodium.to_string(sensitive));

504

sodium.memzero(sensitive);

505

console.log('After zeroing is all zeros:', sodium.is_zero(sensitive)); // true

506

507

// Increment operation (little-endian)

508

const counter = new Uint8Array([0, 0, 0, 1]); // 16777216 in little-endian

509

console.log('Counter before:', Array.from(counter));

510

sodium.increment(counter);

511

console.log('Counter after:', Array.from(counter)); // [1, 0, 0, 1]

512

513

// Addition (little-endian)

514

const num1 = new Uint8Array([5, 0, 0, 0]); // 5

515

const num2 = new Uint8Array([3, 0, 0, 0]); // 3

516

sodium.add(num1, num2); // num1 = num1 + num2

517

console.log('Addition result:', Array.from(num1)); // [8, 0, 0, 0] = 8

518

```

519

520

### Padding Operations

521

522

```javascript

523

// PKCS#7 padding

524

const data = sodium.from_string('Hello World!');

525

const padded = sodium.pad(data, 16);

526

527

console.log('Original length:', data.length); // 12

528

console.log('Padded length:', padded.length); // 16

529

console.log('Padded data:', sodium.to_hex(padded));

530

531

// Unpadding

532

const unpadded = sodium.unpad(padded, 16);

533

console.log('Unpadded matches original:',

534

sodium.memcmp(data, unpadded)); // true

535

536

// Different block sizes

537

const padded8 = sodium.pad(data, 8);

538

const padded32 = sodium.pad(data, 32);

539

540

console.log('8-byte padded length:', padded8.length); // 16

541

console.log('32-byte padded length:', padded32.length); // 32

542

```

543

544

### One-Time Authentication

545

546

```javascript

547

// One-time authentication (use key only once!)

548

const onetimeKey = sodium.crypto_onetimeauth_keygen();

549

const message = sodium.from_string('One-time authenticated message');

550

551

const tag = sodium.crypto_onetimeauth(message, onetimeKey);

552

const isValid = sodium.crypto_onetimeauth_verify(tag, message, onetimeKey);

553

554

console.log('One-time auth tag:', sodium.to_hex(tag));

555

console.log('Tag is valid:', isValid); // true

556

557

// CRITICAL: Never reuse the key!

558

// Using the same key again breaks security

559

sodium.memzero(onetimeKey); // Clear the key

560

561

// Streaming one-time authentication

562

const streamKey = sodium.crypto_onetimeauth_keygen();

563

const state = sodium.crypto_onetimeauth_init(streamKey);

564

565

const chunk1 = sodium.from_string('First chunk ');

566

const chunk2 = sodium.from_string('Second chunk');

567

568

sodium.crypto_onetimeauth_update(state, chunk1);

569

sodium.crypto_onetimeauth_update(state, chunk2);

570

571

const streamTag = sodium.crypto_onetimeauth_final(state);

572

573

// Verify against complete message

574

const completeMessage = sodium.from_string('First chunk Second chunk');

575

const streamValid = sodium.crypto_onetimeauth_verify(streamTag, completeMessage, streamKey);

576

577

console.log('Streaming auth valid:', streamValid); // true

578

sodium.memzero(streamKey); // Clear the key

579

```

580

581

### Short Hash for Hash Tables

582

583

```javascript

584

// Fast non-cryptographic hashing

585

const hashKey = sodium.crypto_shorthash_keygen();

586

587

// Hash table simulation

588

const hashTable = new Map();

589

590

function addToHashTable(key, value) {

591

const keyBytes = sodium.from_string(key);

592

const hash = sodium.crypto_shorthash(keyBytes, hashKey);

593

const hashHex = sodium.to_hex(hash);

594

595

if (!hashTable.has(hashHex)) {

596

hashTable.set(hashHex, []);

597

}

598

hashTable.get(hashHex).push({ key, value });

599

}

600

601

function getFromHashTable(key) {

602

const keyBytes = sodium.from_string(key);

603

const hash = sodium.crypto_shorthash(keyBytes, hashKey);

604

const hashHex = sodium.to_hex(hash);

605

606

const bucket = hashTable.get(hashHex);

607

if (!bucket) return undefined;

608

609

const entry = bucket.find(item => item.key === key);

610

return entry ? entry.value : undefined;

611

}

612

613

// Add some entries

614

addToHashTable('alice', { id: 1, name: 'Alice' });

615

addToHashTable('bob', { id: 2, name: 'Bob' });

616

addToHashTable('charlie', { id: 3, name: 'Charlie' });

617

618

// Retrieve entries

619

console.log('Alice:', getFromHashTable('alice'));

620

console.log('Bob:', getFromHashTable('bob'));

621

console.log('David:', getFromHashTable('david')); // undefined

622

623

// Show hash distribution

624

console.log('Hash table size:', hashTable.size);

625

console.log('Hash table contents:');

626

for (const [hash, bucket] of hashTable) {

627

console.log(` ${hash}: ${bucket.length} entries`);

628

}

629

630

// Extended hash for better distribution

631

const extendedHash = sodium.crypto_shorthash_siphashx24(

632

sodium.from_string('test key'), hashKey

633

);

634

console.log('Extended hash:', sodium.to_hex(extendedHash)); // 16 bytes

635

```

636

637

### Utility Helper Class

638

639

```javascript

640

class CryptoUtils {

641

static generateId(length = 16) {

642

const bytes = sodium.randombytes_buf(length);

643

return sodium.to_hex(bytes);

644

}

645

646

static constantTimeEquals(a, b) {

647

if (a.length !== b.length) return false;

648

return sodium.memcmp(a, b);

649

}

650

651

static secureRandom(min, max) {

652

const range = max - min;

653

if (range <= 0) throw new Error('Invalid range');

654

return min + sodium.randombytes_uniform(range);

655

}

656

657

static encodeData(data, format = 'base64') {

658

switch (format) {

659

case 'hex': return sodium.to_hex(data);

660

case 'base64': return sodium.to_base64(data);

661

case 'base64url': return sodium.to_base64(data, sodium.base64_variants.URLSAFE_NO_PADDING);

662

default: throw new Error('Unsupported format');

663

}

664

}

665

666

static decodeData(encoded, format = 'base64') {

667

switch (format) {

668

case 'hex': return sodium.from_hex(encoded);

669

case 'base64': return sodium.from_base64(encoded);

670

case 'base64url': return sodium.from_base64(encoded, sodium.base64_variants.URLSAFE_NO_PADDING);

671

default: throw new Error('Unsupported format');

672

}

673

}

674

675

static clearSensitiveData(...buffers) {

676

for (const buffer of buffers) {

677

if (buffer instanceof Uint8Array) {

678

sodium.memzero(buffer);

679

}

680

}

681

}

682

683

static createChecksum(data) {

684

// Fast non-cryptographic checksum

685

const key = sodium.crypto_shorthash_keygen();

686

const checksum = sodium.crypto_shorthash(data, key);

687

return {

688

checksum: sodium.to_hex(checksum),

689

key: sodium.to_hex(key)

690

};

691

}

692

693

static verifyChecksum(data, checksumHex, keyHex) {

694

const key = sodium.from_hex(keyHex);

695

const expectedChecksum = sodium.crypto_shorthash(data, key);

696

const actualChecksum = sodium.from_hex(checksumHex);

697

return sodium.memcmp(expectedChecksum, actualChecksum);

698

}

699

}

700

701

// Usage examples

702

console.log('Random ID:', CryptoUtils.generateId());

703

console.log('Random number 1-100:', CryptoUtils.secureRandom(1, 101));

704

705

const testData = sodium.from_string('Test data');

706

const hex = CryptoUtils.encodeData(testData, 'hex');

707

const base64 = CryptoUtils.encodeData(testData, 'base64');

708

const base64url = CryptoUtils.encodeData(testData, 'base64url');

709

710

console.log('Hex:', hex);

711

console.log('Base64:', base64);

712

console.log('Base64URL:', base64url);

713

714

// Checksum example

715

const fileData = sodium.from_string('Important file content');

716

const { checksum, key } = CryptoUtils.createChecksum(fileData);

717

const isValid = CryptoUtils.verifyChecksum(fileData, checksum, key);

718

719

console.log('Checksum valid:', isValid); // true

720

```

721

722

### Library Information

723

724

```javascript

725

// Get library version

726

console.log('Sodium version:', sodium.sodium_version_string());

727

console.log('Library version major:', sodium.SODIUM_LIBRARY_VERSION_MAJOR);

728

console.log('Library version minor:', sodium.SODIUM_LIBRARY_VERSION_MINOR);

729

console.log('Version string constant:', sodium.SODIUM_VERSION_STRING);

730

```

731

732

## Security Considerations

733

734

- **Random Number Quality**: All random functions use cryptographically secure generators

735

- **Constant-Time Operations**: Memory comparison functions prevent timing attacks

736

- **Memory Security**: Use memzero() to clear sensitive data from memory

737

- **One-Time Keys**: Never reuse keys for one-time authentication

738

- **Deterministic Generation**: Use only for testing, not production secrets

739

- **Data Validation**: Always validate decoded data before use

740

741

## Performance Notes

742

743

- **Short Hash**: Fast for hash tables but not cryptographically secure

744

- **Memory Operations**: Constant-time operations may be slower than naive implementations

745

- **Base64 Variants**: Choose appropriate variant for your use case

746

- **Random Generation**: Generating large amounts of random data may be slow

747

748

Utility functions form the foundation for secure cryptographic implementations and should be used consistently throughout applications.