or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aead-ciphers.mdasymmetric-cryptography.mdhash-functions.mdindex.mdkey-derivation.mdkey-serialization.mdmessage-authentication.mdsymmetric-ciphers.mdsymmetric-encryption.mdtwo-factor-auth.mdutilities.mdx509-certificates.md

hash-functions.mddocs/

0

# Hash Functions

1

2

Cryptographic hash functions providing both one-shot hashing and incremental hash contexts. Includes SHA family, SHA-3, BLAKE2, MD5, SM3, and extendable output functions (XOFs).

3

4

## Core Imports

5

6

```python

7

from cryptography.hazmat.primitives import hashes

8

```

9

10

## Capabilities

11

12

### Hash Context Interface

13

14

All hash functions provide a consistent context-based interface for incremental hashing.

15

16

```python { .api }

17

class Hash:

18

def __init__(self, algorithm, backend=None):

19

"""

20

Create hash context.

21

22

Args:

23

algorithm: Hash algorithm instance (SHA256(), BLAKE2b(), etc.)

24

backend: Cryptographic backend (usually None for default)

25

"""

26

27

def update(self, data: bytes) -> None:

28

"""

29

Update hash with additional data.

30

31

Args:

32

data (bytes): Data to add to hash

33

"""

34

35

def finalize(self) -> bytes:

36

"""

37

Finalize hash and return digest.

38

39

Returns:

40

bytes: Hash digest

41

42

Note:

43

Cannot call update() after finalize()

44

"""

45

46

def copy(self) -> 'Hash':

47

"""

48

Create copy of current hash state.

49

50

Returns:

51

Hash: Independent copy of hash context

52

"""

53

54

class HashAlgorithm:

55

"""Abstract base class for hash algorithms"""

56

57

@property

58

def name(self) -> str:

59

"""Algorithm name"""

60

61

@property

62

def digest_size(self) -> int:

63

"""Digest size in bytes"""

64

```

65

66

### Extendable Output Functions (XOFs)

67

68

XOFs can produce variable-length output.

69

70

```python { .api }

71

class XOFHash:

72

def __init__(self, algorithm, backend=None):

73

"""

74

Create XOF hash context.

75

76

Args:

77

algorithm: XOF algorithm (SHAKE128(), SHAKE256())

78

backend: Cryptographic backend

79

"""

80

81

def update(self, data: bytes) -> None:

82

"""Update XOF with data"""

83

84

def finalize(self, length: int) -> bytes:

85

"""

86

Finalize XOF and return digest of specified length.

87

88

Args:

89

length (int): Desired output length in bytes

90

91

Returns:

92

bytes: XOF digest of requested length

93

"""

94

95

def copy(self) -> 'XOFHash':

96

"""Create copy of XOF state"""

97

98

class ExtendableOutputFunction:

99

"""Abstract base for XOF algorithms"""

100

101

@property

102

def name(self) -> str:

103

"""Algorithm name"""

104

```

105

106

### SHA-2 Family

107

108

Standard SHA-2 hash functions with fixed output sizes.

109

110

```python { .api }

111

class SHA1:

112

"""

113

SHA-1 hash algorithm (160-bit digest).

114

115

Note: SHA-1 is cryptographically broken, use SHA-256 or higher.

116

"""

117

name = "sha1"

118

digest_size = 20

119

120

class SHA224:

121

"""SHA-224 hash algorithm (224-bit digest)"""

122

name = "sha224"

123

digest_size = 28

124

125

class SHA256:

126

"""SHA-256 hash algorithm (256-bit digest)"""

127

name = "sha256"

128

digest_size = 32

129

130

class SHA384:

131

"""SHA-384 hash algorithm (384-bit digest)"""

132

name = "sha384"

133

digest_size = 48

134

135

class SHA512:

136

"""SHA-512 hash algorithm (512-bit digest)"""

137

name = "sha512"

138

digest_size = 64

139

140

class SHA512_224:

141

"""SHA-512/224 hash algorithm (224-bit digest from SHA-512)"""

142

name = "sha512-224"

143

digest_size = 28

144

145

class SHA512_256:

146

"""SHA-512/256 hash algorithm (256-bit digest from SHA-512)"""

147

name = "sha512-256"

148

digest_size = 32

149

```

150

151

### SHA-3 Family

152

153

NIST SHA-3 standard hash functions.

154

155

```python { .api }

156

class SHA3_224:

157

"""SHA3-224 hash algorithm (224-bit digest)"""

158

name = "sha3-224"

159

digest_size = 28

160

161

class SHA3_256:

162

"""SHA3-256 hash algorithm (256-bit digest)"""

163

name = "sha3-256"

164

digest_size = 32

165

166

class SHA3_384:

167

"""SHA3-384 hash algorithm (384-bit digest)"""

168

name = "sha3-384"

169

digest_size = 48

170

171

class SHA3_512:

172

"""SHA3-512 hash algorithm (512-bit digest)"""

173

name = "sha3-512"

174

digest_size = 64

175

176

class SHAKE128:

177

"""SHAKE128 extendable output function"""

178

name = "shake128"

179

180

class SHAKE256:

181

"""SHAKE256 extendable output function"""

182

name = "shake256"

183

```

184

185

### BLAKE2 Family

186

187

High-performance cryptographic hash functions.

188

189

```python { .api }

190

class BLAKE2b:

191

def __init__(self, digest_size: int):

192

"""

193

BLAKE2b hash algorithm with configurable output size.

194

195

Args:

196

digest_size (int): Output size in bytes (1-64)

197

"""

198

199

@property

200

def name(self) -> str:

201

return "blake2b"

202

203

@property

204

def digest_size(self) -> int:

205

"""Configured digest size"""

206

207

class BLAKE2s:

208

def __init__(self, digest_size: int):

209

"""

210

BLAKE2s hash algorithm with configurable output size.

211

212

Args:

213

digest_size (int): Output size in bytes (1-32)

214

"""

215

216

@property

217

def name(self) -> str:

218

return "blake2s"

219

220

@property

221

def digest_size(self) -> int:

222

"""Configured digest size"""

223

```

224

225

### Other Hash Functions

226

227

```python { .api }

228

class MD5:

229

"""

230

MD5 hash algorithm (128-bit digest).

231

232

Note: MD5 is cryptographically broken, use SHA-256 or higher.

233

"""

234

name = "md5"

235

digest_size = 16

236

237

class SM3:

238

"""SM3 hash algorithm (256-bit digest) - Chinese national standard"""

239

name = "sm3"

240

digest_size = 32

241

```

242

243

## Usage Examples

244

245

### Basic Hashing

246

247

```python

248

from cryptography.hazmat.primitives import hashes

249

250

# One-shot hashing

251

data = b"Hello, World!"

252

253

# SHA-256

254

digest = hashes.Hash(hashes.SHA256())

255

digest.update(data)

256

hash_value = digest.finalize()

257

print(f"SHA-256: {hash_value.hex()}")

258

259

# SHA-3

260

digest = hashes.Hash(hashes.SHA3_256())

261

digest.update(data)

262

hash_value = digest.finalize()

263

print(f"SHA3-256: {hash_value.hex()}")

264

```

265

266

### Incremental Hashing

267

268

```python

269

from cryptography.hazmat.primitives import hashes

270

271

# Hash large data incrementally

272

hasher = hashes.Hash(hashes.SHA256())

273

274

# Process data in chunks

275

with open('large_file.bin', 'rb') as f:

276

while chunk := f.read(8192):

277

hasher.update(chunk)

278

279

final_hash = hasher.finalize()

280

print(f"File hash: {final_hash.hex()}")

281

```

282

283

### Hash State Copying

284

285

```python

286

from cryptography.hazmat.primitives import hashes

287

288

# Create base hash state

289

base_hasher = hashes.Hash(hashes.SHA256())

290

base_hasher.update(b"Common prefix")

291

292

# Create multiple branches from same state

293

hasher1 = base_hasher.copy()

294

hasher1.update(b"Branch 1 data")

295

hash1 = hasher1.finalize()

296

297

hasher2 = base_hasher.copy()

298

hasher2.update(b"Branch 2 data")

299

hash2 = hasher2.finalize()

300

301

print(f"Hash 1: {hash1.hex()}")

302

print(f"Hash 2: {hash2.hex()}")

303

```

304

305

### Extendable Output Functions (XOFs)

306

307

```python

308

from cryptography.hazmat.primitives import hashes

309

310

# SHAKE128 - variable length output

311

data = b"Input data for XOF"

312

xof = hashes.XOFHash(hashes.SHAKE128())

313

xof.update(data)

314

315

# Generate different length outputs

316

short_output = xof.copy().finalize(16) # 16 bytes

317

long_output = xof.copy().finalize(64) # 64 bytes

318

319

print(f"Short SHAKE128: {short_output.hex()}")

320

print(f"Long SHAKE128: {long_output.hex()}")

321

322

# SHAKE256

323

xof256 = hashes.XOFHash(hashes.SHAKE256())

324

xof256.update(data)

325

output256 = xof256.finalize(32)

326

print(f"SHAKE256: {output256.hex()}")

327

```

328

329

### BLAKE2 with Custom Output Size

330

331

```python

332

from cryptography.hazmat.primitives import hashes

333

334

data = b"Data to hash with BLAKE2"

335

336

# BLAKE2b with 32-byte output

337

blake2b_32 = hashes.Hash(hashes.BLAKE2b(32))

338

blake2b_32.update(data)

339

hash_32 = blake2b_32.finalize()

340

341

# BLAKE2b with 64-byte output (maximum)

342

blake2b_64 = hashes.Hash(hashes.BLAKE2b(64))

343

blake2b_64.update(data)

344

hash_64 = blake2b_64.finalize()

345

346

print(f"BLAKE2b-32: {hash_32.hex()}")

347

print(f"BLAKE2b-64: {hash_64.hex()}")

348

349

# BLAKE2s with 16-byte output

350

blake2s_16 = hashes.Hash(hashes.BLAKE2s(16))

351

blake2s_16.update(data)

352

hash_16 = blake2s_16.finalize()

353

print(f"BLAKE2s-16: {hash_16.hex()}")

354

```

355

356

### File Integrity Verification

357

358

```python

359

from cryptography.hazmat.primitives import hashes

360

import os

361

362

class FileHasher:

363

def __init__(self, algorithm=hashes.SHA256()):

364

self.algorithm = algorithm

365

366

def hash_file(self, filepath):

367

"""Compute hash of file"""

368

hasher = hashes.Hash(self.algorithm)

369

370

with open(filepath, 'rb') as f:

371

while chunk := f.read(65536): # 64KB chunks

372

hasher.update(chunk)

373

374

return hasher.finalize()

375

376

def verify_file(self, filepath, expected_hash):

377

"""Verify file matches expected hash"""

378

actual_hash = self.hash_file(filepath)

379

return actual_hash == expected_hash

380

381

# Usage

382

file_hasher = FileHasher(hashes.SHA256())

383

384

# Compute file hash

385

file_hash = file_hasher.hash_file('document.pdf')

386

print(f"File hash: {file_hash.hex()}")

387

388

# Later, verify file integrity

389

is_valid = file_hasher.verify_file('document.pdf', file_hash)

390

print(f"File integrity: {'OK' if is_valid else 'FAILED'}")

391

```

392

393

### Hash-based Message Authentication Code (HMAC) Integration

394

395

```python

396

from cryptography.hazmat.primitives import hashes, hmac

397

398

# HMAC typically uses hash functions

399

key = b"secret_key_32_bytes_long_for_hmac"

400

message = b"Message to authenticate"

401

402

# HMAC-SHA256

403

h = hmac.HMAC(key, hashes.SHA256())

404

h.update(message)

405

signature = h.finalize()

406

407

print(f"HMAC-SHA256: {signature.hex()}")

408

409

# Verify HMAC

410

h_verify = hmac.HMAC(key, hashes.SHA256())

411

h_verify.update(message)

412

try:

413

h_verify.verify(signature)

414

print("HMAC verification: SUCCESS")

415

except Exception:

416

print("HMAC verification: FAILED")

417

```

418

419

### Password Hashing (with Key Derivation)

420

421

```python

422

from cryptography.hazmat.primitives import hashes

423

from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

424

import os

425

426

def hash_password(password: str, salt: bytes = None) -> tuple:

427

"""Hash password using PBKDF2-HMAC-SHA256"""

428

if salt is None:

429

salt = os.urandom(16)

430

431

kdf = PBKDF2HMAC(

432

algorithm=hashes.SHA256(),

433

length=32,

434

salt=salt,

435

iterations=100000, # OWASP recommended minimum

436

)

437

438

key = kdf.derive(password.encode())

439

return key, salt

440

441

def verify_password(password: str, stored_hash: bytes, salt: bytes) -> bool:

442

"""Verify password against stored hash"""

443

kdf = PBKDF2HMAC(

444

algorithm=hashes.SHA256(),

445

length=32,

446

salt=salt,

447

iterations=100000,

448

)

449

450

try:

451

kdf.verify(password.encode(), stored_hash)

452

return True

453

except Exception:

454

return False

455

456

# Usage

457

password = "user_password123"

458

459

# Hash password for storage

460

password_hash, salt = hash_password(password)

461

print(f"Password hash: {password_hash.hex()}")

462

print(f"Salt: {salt.hex()}")

463

464

# Verify password

465

is_valid = verify_password(password, password_hash, salt)

466

print(f"Password valid: {is_valid}")

467

```

468

469

## Security Considerations

470

471

- **Algorithm Selection**: Use SHA-256 or higher for new applications

472

- **Legacy Algorithms**: MD5 and SHA-1 are cryptographically broken

473

- **Performance**: BLAKE2 offers excellent performance with strong security

474

- **XOF Usage**: SHAKE functions useful for custom output lengths

475

- **Salt Usage**: Always use random salts for password hashing

476

- **Incremental Hashing**: More efficient for large data than loading into memory

477

- **State Management**: Hash contexts cannot be used after finalization