or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aead.mdauth.mdbox.mded25519.mdhash.mdindex.mdkdf.mdkx.mdmemory.mdpwhash.mdrandom.mdsecretbox.mdsecretstream.mdshorthash.mdsign.mdstream.md

pwhash.mddocs/

0

# Password Hashing

1

2

Secure password hashing using Argon2 and scrypt algorithms for password verification, key derivation, and protection against brute-force attacks.

3

4

## Capabilities

5

6

### Argon2 Password Hashing

7

8

Modern password hashing using Argon2i or Argon2id algorithms.

9

10

```javascript { .api }

11

/**

12

* Hash password using Argon2

13

* @param out - Output buffer for derived key

14

* @param passwd - Password buffer to hash

15

* @param salt - Salt buffer (must be SALTBYTES long)

16

* @param opslimit - Operations limit (computational cost)

17

* @param memlimit - Memory limit in bytes

18

* @param alg - Algorithm ID (ALG_ARGON2I13 or ALG_ARGON2ID13)

19

* @throws Error if parameters are out of bounds or hashing fails

20

*/

21

function crypto_pwhash(

22

out: Buffer,

23

passwd: Buffer,

24

salt: Buffer,

25

opslimit: number,

26

memlimit: number,

27

alg: number

28

): void;

29

```

30

31

### Argon2 Async Password Hashing

32

33

Non-blocking password hashing for server applications.

34

35

```javascript { .api }

36

/**

37

* Hash password using Argon2 (async)

38

* @param out - Output buffer for derived key

39

* @param passwd - Password buffer to hash

40

* @param salt - Salt buffer (must be SALTBYTES long)

41

* @param opslimit - Operations limit (computational cost)

42

* @param memlimit - Memory limit in bytes

43

* @param alg - Algorithm ID (ALG_ARGON2I13 or ALG_ARGON2ID13)

44

* @param callback - Optional callback function

45

* @returns Promise<void> if no callback provided

46

* @throws Error if parameters are out of bounds

47

*/

48

function crypto_pwhash_async(

49

out: Buffer,

50

passwd: Buffer,

51

salt: Buffer,

52

opslimit: number,

53

memlimit: number,

54

alg: number,

55

callback?: (error: Error | null) => void

56

): Promise<void> | undefined;

57

```

58

59

**Usage Example:**

60

61

```javascript

62

const sodium = require('sodium-native');

63

64

async function hashPassword(password) {

65

const salt = Buffer.alloc(sodium.crypto_pwhash_SALTBYTES);

66

sodium.randombytes_buf(salt);

67

68

const derivedKey = Buffer.alloc(32);

69

70

// Using async version (recommended for servers)

71

await sodium.crypto_pwhash_async(

72

derivedKey,

73

Buffer.from(password),

74

salt,

75

sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,

76

sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE,

77

sodium.crypto_pwhash_ALG_ARGON2ID13

78

);

79

80

return { derivedKey, salt };

81

}

82

```

83

84

### Argon2 String Format

85

86

Password hashing with string encoding for easy storage.

87

88

```javascript { .api }

89

/**

90

* Hash password to string format

91

* @param out - Output buffer for password string (must be STRBYTES long)

92

* @param passwd - Password buffer to hash

93

* @param opslimit - Operations limit (computational cost)

94

* @param memlimit - Memory limit in bytes

95

* @throws Error if parameters are out of bounds or hashing fails

96

*/

97

function crypto_pwhash_str(

98

out: Buffer,

99

passwd: Buffer,

100

opslimit: number,

101

memlimit: number

102

): void;

103

104

/**

105

* Hash password to string format (async)

106

* @param out - Output buffer for password string (must be STRBYTES long)

107

* @param passwd - Password buffer to hash

108

* @param opslimit - Operations limit (computational cost)

109

* @param memlimit - Memory limit in bytes

110

* @param callback - Optional callback function

111

* @returns Promise<void> if no callback provided

112

*/

113

function crypto_pwhash_str_async(

114

out: Buffer,

115

passwd: Buffer,

116

opslimit: number,

117

memlimit: number,

118

callback?: (error: Error | null) => void

119

): Promise<void> | undefined;

120

```

121

122

### Argon2 String Verification

123

124

Verify passwords against stored string hashes.

125

126

```javascript { .api }

127

/**

128

* Verify password against string hash

129

* @param str - Password string hash to verify against (must be STRBYTES long)

130

* @param passwd - Password buffer to verify

131

* @returns true if password matches, false otherwise

132

*/

133

function crypto_pwhash_str_verify(str: Buffer, passwd: Buffer): boolean;

134

135

/**

136

* Verify password against string hash (async)

137

* @param str - Password string hash to verify against (must be STRBYTES long)

138

* @param passwd - Password buffer to verify

139

* @param callback - Optional callback function

140

* @returns Promise<boolean> if no callback provided

141

*/

142

function crypto_pwhash_str_verify_async(

143

str: Buffer,

144

passwd: Buffer,

145

callback?: (error: Error | null, result?: boolean) => void

146

): Promise<boolean> | undefined;

147

```

148

149

### Argon2 Rehash Check

150

151

Check if a password hash needs to be updated due to changed parameters.

152

153

```javascript { .api }

154

/**

155

* Check if password hash needs rehashing with new parameters

156

* @param str - Password string hash to check (must be STRBYTES long)

157

* @param opslimit - New operations limit to compare against

158

* @param memlimit - New memory limit to compare against

159

* @returns true if rehashing needed, false otherwise

160

*/

161

function crypto_pwhash_str_needs_rehash(

162

str: Buffer,

163

opslimit: number,

164

memlimit: number

165

): boolean;

166

```

167

168

**Usage Example:**

169

170

```javascript

171

const sodium = require('sodium-native');

172

173

class PasswordManager {

174

async hashPassword(password) {

175

const hash = Buffer.alloc(sodium.crypto_pwhash_STRBYTES);

176

177

await sodium.crypto_pwhash_str_async(

178

hash,

179

Buffer.from(password),

180

sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,

181

sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE

182

);

183

184

return hash;

185

}

186

187

async verifyPassword(password, hash) {

188

return await sodium.crypto_pwhash_str_verify_async(

189

hash,

190

Buffer.from(password)

191

);

192

}

193

194

needsRehash(hash) {

195

return sodium.crypto_pwhash_str_needs_rehash(

196

hash,

197

sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,

198

sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE

199

);

200

}

201

}

202

```

203

204

### Scrypt Password Hashing

205

206

Legacy scrypt algorithm support for compatibility.

207

208

```javascript { .api }

209

/**

210

* Hash password using scrypt

211

* @param out - Output buffer for derived key

212

* @param passwd - Password buffer to hash

213

* @param salt - Salt buffer (must be SALTBYTES long)

214

* @param opslimit - Operations limit (computational cost)

215

* @param memlimit - Memory limit in bytes

216

* @throws Error if parameters are out of bounds or hashing fails

217

*/

218

function crypto_pwhash_scryptsalsa208sha256(

219

out: Buffer,

220

passwd: Buffer,

221

salt: Buffer,

222

opslimit: number,

223

memlimit: number

224

): void;

225

226

/**

227

* Hash password using scrypt (async)

228

* @param out - Output buffer for derived key

229

* @param passwd - Password buffer to hash

230

* @param salt - Salt buffer (must be SALTBYTES long)

231

* @param opslimit - Operations limit (computational cost)

232

* @param memlimit - Memory limit in bytes

233

* @param callback - Optional callback function

234

* @returns Promise<void> if no callback provided

235

*/

236

function crypto_pwhash_scryptsalsa208sha256_async(

237

out: Buffer,

238

passwd: Buffer,

239

salt: Buffer,

240

opslimit: number,

241

memlimit: number,

242

callback?: (error: Error | null) => void

243

): Promise<void> | undefined;

244

```

245

246

### Scrypt String Format

247

248

Scrypt password hashing with string encoding.

249

250

```javascript { .api }

251

/**

252

* Hash password to string format using scrypt

253

* @param out - Output buffer for password string (must be STRBYTES long)

254

* @param passwd - Password buffer to hash

255

* @param opslimit - Operations limit (computational cost)

256

* @param memlimit - Memory limit in bytes

257

* @throws Error if parameters are out of bounds or hashing fails

258

*/

259

function crypto_pwhash_scryptsalsa208sha256_str(

260

out: Buffer,

261

passwd: Buffer,

262

opslimit: number,

263

memlimit: number

264

): void;

265

266

/**

267

* Verify password against scrypt string hash

268

* @param str - Password string hash to verify against (must be STRBYTES long)

269

* @param passwd - Password buffer to verify

270

* @returns true if password matches, false otherwise

271

*/

272

function crypto_pwhash_scryptsalsa208sha256_str_verify(str: Buffer, passwd: Buffer): boolean;

273

274

/**

275

* Check if scrypt password hash needs rehashing

276

* @param str - Password string hash to check (must be STRBYTES long)

277

* @param opslimit - New operations limit to compare against

278

* @param memlimit - New memory limit to compare against

279

* @returns true if rehashing needed, false otherwise

280

*/

281

function crypto_pwhash_scryptsalsa208sha256_str_needs_rehash(

282

str: Buffer,

283

opslimit: number,

284

memlimit: number

285

): boolean;

286

```

287

288

## Constants

289

290

```javascript { .api }

291

// Argon2 algorithm constants

292

const crypto_pwhash_ALG_ARGON2I13: number;

293

const crypto_pwhash_ALG_ARGON2ID13: number;

294

const crypto_pwhash_ALG_DEFAULT: number;

295

296

// Argon2 size constants

297

const crypto_pwhash_BYTES_MIN: number;

298

const crypto_pwhash_BYTES_MAX: number;

299

const crypto_pwhash_PASSWD_MIN: number;

300

const crypto_pwhash_PASSWD_MAX: number;

301

const crypto_pwhash_SALTBYTES: number;

302

const crypto_pwhash_STRBYTES: number;

303

304

// Argon2 cost constants

305

const crypto_pwhash_OPSLIMIT_MIN: number;

306

const crypto_pwhash_OPSLIMIT_MAX: number;

307

const crypto_pwhash_OPSLIMIT_INTERACTIVE: number;

308

const crypto_pwhash_OPSLIMIT_MODERATE: number;

309

const crypto_pwhash_OPSLIMIT_SENSITIVE: number;

310

const crypto_pwhash_MEMLIMIT_MIN: number;

311

const crypto_pwhash_MEMLIMIT_MAX: number;

312

const crypto_pwhash_MEMLIMIT_INTERACTIVE: number;

313

const crypto_pwhash_MEMLIMIT_MODERATE: number;

314

const crypto_pwhash_MEMLIMIT_SENSITIVE: number;

315

316

// Scrypt size constants

317

const crypto_pwhash_scryptsalsa208sha256_BYTES_MIN: number;

318

const crypto_pwhash_scryptsalsa208sha256_BYTES_MAX: number;

319

const crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN: number;

320

const crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX: number;

321

const crypto_pwhash_scryptsalsa208sha256_SALTBYTES: number;

322

const crypto_pwhash_scryptsalsa208sha256_STRBYTES: number;

323

324

// Scrypt cost constants

325

const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN: number;

326

const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX: number;

327

const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE: number;

328

const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE: number;

329

const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN: number;

330

const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX: number;

331

const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE: number;

332

const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE: number;

333

```

334

335

## Security Considerations

336

337

- **Algorithm Choice**: Use Argon2id (ALG_ARGON2ID13) for new applications; it's more resistant to GPU attacks.

338

- **Cost Parameters**: Choose appropriate opslimit/memlimit based on your security requirements and hardware.

339

- **Salt Uniqueness**: Always use unique, random salts for each password.

340

- **Timing**: Use async versions in server applications to prevent blocking.

341

342

## Common Patterns

343

344

### User Authentication System

345

346

```javascript

347

const sodium = require('sodium-native');

348

349

class UserAuth {

350

constructor() {

351

this.users = new Map();

352

}

353

354

async registerUser(username, password) {

355

const hash = Buffer.alloc(sodium.crypto_pwhash_STRBYTES);

356

357

await sodium.crypto_pwhash_str_async(

358

hash,

359

Buffer.from(password),

360

sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,

361

sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE

362

);

363

364

this.users.set(username, hash);

365

return true;

366

}

367

368

async loginUser(username, password) {

369

const storedHash = this.users.get(username);

370

if (!storedHash) return false;

371

372

// Check if hash needs updating

373

if (sodium.crypto_pwhash_str_needs_rehash(

374

storedHash,

375

sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,

376

sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE

377

)) {

378

// Rehash password with new parameters after successful verification

379

const isValid = await sodium.crypto_pwhash_str_verify_async(

380

storedHash,

381

Buffer.from(password)

382

);

383

384

if (isValid) {

385

await this.registerUser(username, password); // Update hash

386

}

387

388

return isValid;

389

}

390

391

return await sodium.crypto_pwhash_str_verify_async(

392

storedHash,

393

Buffer.from(password)

394

);

395

}

396

}

397

```

398

399

### Key Derivation from Password

400

401

```javascript

402

const sodium = require('sodium-native');

403

404

async function deriveEncryptionKey(password, salt) {

405

const key = Buffer.alloc(32); // 256-bit key

406

407

await sodium.crypto_pwhash_async(

408

key,

409

Buffer.from(password),

410

salt,

411

sodium.crypto_pwhash_OPSLIMIT_SENSITIVE,

412

sodium.crypto_pwhash_MEMLIMIT_SENSITIVE,

413

sodium.crypto_pwhash_ALG_ARGON2ID13

414

);

415

416

return key;

417

}

418

419

// Usage for file encryption

420

async function encryptFileWithPassword(filename, password) {

421

const salt = Buffer.alloc(sodium.crypto_pwhash_SALTBYTES);

422

sodium.randombytes_buf(salt);

423

424

const key = await deriveEncryptionKey(password, salt);

425

426

// Use key with crypto_secretbox_easy

427

// Store salt alongside encrypted file for decryption

428

}

429

```