Tachyon /Users/simon/.local/share/uv/python/cpython-3.15.0-macos-aarch64-none/lib/python3.15/hashlib.py
532
Self Samples
532
Cumulative
7
Lines Hit
1.83%
% of Total
456
Max Self
456
Max Total
Intensity:
Cold Hot
Self Time
Total Time
Show All
Hot Only
Heat
Specialization
Line
Self
Total
Code
1
#. Copyright (C) 2005-2010 Gregory P. Smith (greg@krypto.org)
2
# Licensed to PSF under a Contributor Agreement.
3
#
4
5
__doc__ = r"""hashlib module - A common interface to many hash functions.
6
7
new(name, data=b'', **kwargs) - returns a new hash object implementing the
8
given hash function; initializing the hash
9
using the given binary data.
10
11
Named constructor functions are also available, these are faster
12
than using new(name):
13
14
md5(), sha1(), sha224(), sha256(), sha384(), sha512(), blake2b(), blake2s(),
15
sha3_224(), sha3_256(), sha3_384(), sha3_512(), shake_128(), and shake_256().
16
17
More algorithms may be available on your platform but the above are guaranteed
18
to exist. See the algorithms_guaranteed and algorithms_available attributes
19
to find out what algorithm names can be passed to new().
20
21
NOTE: If you want the adler32 or crc32 hash functions they are available in
22
the zlib module.
23
24
Choose your hash function wisely. Some have known collision weaknesses,
25
while others may be slower depending on the CPU architecture.
26
27
Hash objects have these methods:
28
- update(data): Update the hash object with the bytes in data. Repeated calls
29
are equivalent to a single call with the concatenation of all
30
the arguments.
31
- digest(): Return the digest of the bytes passed to the update() method
32
so far as a bytes object.
33
- hexdigest(): Like digest() except the digest is returned as a string
34
of double length, containing only hexadecimal digits.
35
- copy(): Return a copy (clone) of the hash object. This can be used to
36
efficiently compute the digests of data that share a common
37
initial substring.
38
39
Assuming that Python has been built with SHA-2 support, the SHA-256 digest
40
of the byte string b'Nobody inspects the spammish repetition' is computed
41
as follows:
42
43
>>> import hashlib
44
>>> m = hashlib.sha256()
45
>>> m.update(b"Nobody inspects")
46
>>> m.update(b" the spammish repetition")
47
>>> m.digest() # doctest: +ELLIPSIS
48
b'\x03\x1e\xdd}Ae\x15\x93\xc5\xfe\\\x00o\xa5u+7...'
49
50
More condensed:
51
52
>>> hashlib.sha256(b"Nobody inspects the spammish repetition").hexdigest()
53
'031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406'
54
"""
55
56
# This tuple and __get_builtin_constructor() must be modified if a new
57
# always available algorithm is added.
58
__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512',
59
'blake2b', 'blake2s',
60
'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
61
'shake_128', 'shake_256')
62
63
64
algorithms_guaranteed = set(__always_supported)
65
algorithms_available = set(__always_supported)
66
67
__all__ = __always_supported + ('new', 'algorithms_guaranteed',
68
'algorithms_available', 'file_digest')
69
70
71
__builtin_constructor_cache = {}
72
73
# Prefer our blake2 implementation
74
# OpenSSL 1.1.0 comes with a limited implementation of blake2b/s. The OpenSSL
75
# implementations neither support keyed blake2 (blake2 MAC) nor advanced
76
# features like salt, personalization, or tree hashing. OpenSSL hash-only
77
# variants are available as 'blake2b512' and 'blake2s256', though.
78
__block_openssl_constructor = {
79
'blake2b', 'blake2s',
80
}
81
82
def __get_builtin_constructor(name):
83
if not isinstance(name, str):
84
# Since this function is only used by new(), we use the same
85
# exception as _hashlib.new() when 'name' is of incorrect type.
86
err = f"new() argument 'name' must be str, not {type(name).__name__}"
87
raise TypeError(err)
88
cache = __builtin_constructor_cache
89
constructor = cache.get(name)
90
if constructor is not None:
91
return constructor
92
try:
93
if name in {'SHA1', 'sha1'}:
94
import _sha1
95
cache['SHA1'] = cache['sha1'] = _sha1.sha1
96
elif name in {'MD5', 'md5'}:
97
import _md5
98
cache['MD5'] = cache['md5'] = _md5.md5
99
elif name in {'SHA256', 'sha256', 'SHA224', 'sha224'}:
100
import _sha2
101
cache['SHA224'] = cache['sha224'] = _sha2.sha224
102
cache['SHA256'] = cache['sha256'] = _sha2.sha256
103
elif name in {'SHA512', 'sha512', 'SHA384', 'sha384'}:
104
import _sha2
105
cache['SHA384'] = cache['sha384'] = _sha2.sha384
106
cache['SHA512'] = cache['sha512'] = _sha2.sha512
107
elif name in {'blake2b', 'blake2s'}:
108
import _blake2
109
cache['blake2b'] = _blake2.blake2b
110
cache['blake2s'] = _blake2.blake2s
111
elif name in {'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512'}:
112
import _sha3
113
cache['sha3_224'] = _sha3.sha3_224
114
cache['sha3_256'] = _sha3.sha3_256
115
cache['sha3_384'] = _sha3.sha3_384
116
cache['sha3_512'] = _sha3.sha3_512
117
elif name in {'shake_128', 'shake_256'}:
118
import _sha3
119
cache['shake_128'] = _sha3.shake_128
120
cache['shake_256'] = _sha3.shake_256
121
except ImportError:
122
pass # no extension module, this hash is unsupported.
123
124
constructor = cache.get(name)
125
if constructor is not None:
126
return constructor
127
128
# Keep the message in sync with hashlib.h::HASHLIB_UNSUPPORTED_ALGORITHM.
129
raise ValueError(f'unsupported hash algorithm {name}')
130
131
132
def __get_openssl_constructor(name):
133
# This function is only used until the module has been initialized.
134
assert isinstance(name, str), "invalid call to __get_openssl_constructor()"
135
if name in __block_openssl_constructor:
136
# Prefer our builtin blake2 implementation.
137
return __get_builtin_constructor(name)
138
try:
139
# Fetch the OpenSSL hash function if it exists,
140
# independently of the context security policy.
141
f = getattr(_hashlib, 'openssl_' + name)
142
# Check if the context security policy blocks the digest or not
143
# by allowing the C module to raise a ValueError. The function
144
# will be defined but the hash will not be available at runtime.
145
#
146
# We use "usedforsecurity=False" to prevent falling back to the
147
# built-in function in case the security policy does not allow it.
148
#
149
# Note that this only affects the explicit named constructors,
150
# and not the algorithms exposed through hashlib.new() which
151
# can still be resolved to a built-in function even if the
152
# current security policy does not allow it.
153
#
154
# See https://github.com/python/cpython/issues/84872.
155
f(usedforsecurity=False)
156
# Use the C function directly (very fast)
157
return f
158
except (AttributeError, ValueError):
159
return __get_builtin_constructor(name)
160
161
162
def __py_new(name, *args, **kwargs):
163
"""new(name, data=b'', **kwargs) - Return a new hashing object using the
164
named algorithm; optionally initialized with data (which must be
165
a bytes-like object).
166
"""
167
return __get_builtin_constructor(name)(*args, **kwargs)
168
169
170
def __hash_new(name, *args, **kwargs):
171
"""new(name, data=b'') - Return a new hashing object using the named algorithm;
172
optionally initialized with data (which must be a bytes-like object).
173
"""
174
if name in __block_openssl_constructor:
175
# __block_openssl_constructor is expected to contain strings only
176
assert isinstance(name, str), f"unexpected name: {name}"
177
# Prefer our builtin blake2 implementation.
178
return __get_builtin_constructor(name)(*args, **kwargs)
179
try:
180
return _hashlib.new(name, *args, **kwargs)
181
except ValueError:
182
# If the _hashlib module (OpenSSL) doesn't support the named
183
# hash, try using our builtin implementations.
184
# This allows for SHA224/256 and SHA384/512 support even though
185
# the OpenSSL library prior to 0.9.8 doesn't provide them.
186
return __get_builtin_constructor(name)(*args, **kwargs)
187
188
189
try:
190
import _hashlib
191
new = __hash_new
192
__get_hash = __get_openssl_constructor
193
algorithms_available = algorithms_available.union(
194
_hashlib.openssl_md_meth_names)
195
except ImportError:
196
_hashlib = None
197
new = __py_new
198
__get_hash = __get_builtin_constructor
199
200
try:
201
# OpenSSL's PKCS5_PBKDF2_HMAC requires OpenSSL 1.0+ with HMAC and SHA
202
from _hashlib import pbkdf2_hmac
203
__all__ += ('pbkdf2_hmac',)
204
except ImportError:
205
pass
206
207
208
try:
209
# OpenSSL's scrypt requires OpenSSL 1.1+
210
from _hashlib import scrypt
211
__all__ += ('scrypt',)
212
except ImportError:
213
pass
214
215
216
def file_digest(fileobj, digest, /, *, _bufsize=2**18):
217
"""Hash the contents of a file-like object. Returns a digest object.
218
219
*fileobj* must be a file-like object opened for reading in binary mode.
220
It accepts file objects from open(), io.BytesIO(), and SocketIO objects.
221
The function may bypass Python's I/O and use the file descriptor *fileno*
222
directly.
223
224
*digest* must either be a hash algorithm name as a *str*, a hash
225
constructor, or a callable that returns a hash object.
226
"""
227
# On Linux we could use AF_ALG sockets and sendfile() to achieve zero-copy
228
# hashing with hardware acceleration.
229
1
1
if isinstance(digest, str):
230
4
4
digestobj = new(digest)
231
else:
232
digestobj = digest()
233
234
if hasattr(fileobj, "getbuffer"):
235
# io.BytesIO object, use zero-copy buffer
236
digestobj.update(fileobj.getbuffer())
237
return digestobj
238
239
# Only binary files implement readinto().
240
if not (
241
hasattr(fileobj, "readinto")
242
1
1
and hasattr(fileobj, "readable")
243
and fileobj.readable()
244
):
245
raise ValueError(
246
f"'{fileobj!r}' is not a file-like object in binary reading mode."
247
)
248
249
# binary file, socket.SocketIO object
250
# Note: socket I/O uses different syscalls than file I/O.
251
5
5
buf = bytearray(_bufsize) # Reusable buffer to reduce allocations.
252
view = memoryview(buf)
253
while True:
254
62
62
size = fileobj.readinto(buf)
255
if size is None:
256
raise BlockingIOError("I/O operation would block.")
257
if size == 0:
258
break # EOF
259
456
456
digestobj.update(view[:size])
260
261
3
3
return digestobj
262
263
264
for __func_name in __always_supported:
265
# try them all, some may not work due to the OpenSSL
266
# version not supporting that algorithm.
267
try:
268
globals()[__func_name] = __get_hash(__func_name)
269
except ValueError:
270
# Don't log here: logging at import time has global side effects and
271
# would tell the wrong audience; code that uses a missing algorithm
272
# gets a ValueError from the stub installed below.
273
# The following code can be simplified in Python 3.19
274
# once "string" is removed from the signature.
275
__code = f'''\
276
def {__func_name}(data=__UNSET, *, usedforsecurity=True, string=__UNSET):
277
if data is __UNSET and string is not __UNSET:
278
import warnings
279
warnings.warn(
280
"the 'string' keyword parameter is deprecated since "
281
"Python 3.15 and slated for removal in Python 3.19; "
282
"use the 'data' keyword parameter or pass the data "
283
"to hash as a positional argument instead",
284
DeprecationWarning, stacklevel=2)
285
if data is not __UNSET and string is not __UNSET:
286
raise TypeError("'data' and 'string' are mutually exclusive "
287
"and support for 'string' keyword parameter "
288
"is slated for removal in a future version.")
289
raise ValueError("unsupported hash algorithm {__func_name}")
290
'''
291
exec(__code, {"__UNSET": object()}, __locals := {})
292
globals()[__func_name] = __locals[__func_name]
293
del __code, __locals
294
295
# Cleanup locals()
296
del __always_supported, __func_name, __get_hash
297
del __py_new, __hash_new, __get_openssl_constructor