Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/cryptography/hazmat/primitives/hashes.py: 64%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

205 statements  

1# This file is dual licensed under the terms of the Apache License, Version 

2# 2.0, and the BSD License. See the LICENSE file in the root of this repository 

3# for complete details. 

4 

5from __future__ import annotations 

6 

7import abc 

8import sys 

9 

10from cryptography.hazmat.bindings._rust import openssl as rust_openssl 

11from cryptography.utils import Buffer 

12 

13__all__ = [ 

14 "MD5", 

15 "SHA1", 

16 "SHA3_224", 

17 "SHA3_256", 

18 "SHA3_384", 

19 "SHA3_512", 

20 "SHA224", 

21 "SHA256", 

22 "SHA384", 

23 "SHA512", 

24 "SHA512_224", 

25 "SHA512_256", 

26 "SHAKE128", 

27 "SHAKE256", 

28 "SM3", 

29 "BLAKE2b", 

30 "BLAKE2s", 

31 "ExtendableOutputFunction", 

32 "Hash", 

33 "HashAlgorithm", 

34 "HashContext", 

35 "XOFHash", 

36] 

37 

38 

39class HashAlgorithm(metaclass=abc.ABCMeta): 

40 @property 

41 @abc.abstractmethod 

42 def name(self) -> str: 

43 """ 

44 A string naming this algorithm (e.g. "sha256", "md5"). 

45 """ 

46 

47 @property 

48 @abc.abstractmethod 

49 def digest_size(self) -> int: 

50 """ 

51 The size of the resulting digest in bytes. 

52 """ 

53 

54 @property 

55 @abc.abstractmethod 

56 def block_size(self) -> int | None: 

57 """ 

58 The internal block size of the hash function, or None if the hash 

59 function does not use blocks internally (e.g. SHA3). 

60 """ 

61 

62 

63class HashContext(metaclass=abc.ABCMeta): 

64 @property 

65 @abc.abstractmethod 

66 def algorithm(self) -> HashAlgorithm: 

67 """ 

68 A HashAlgorithm that will be used by this context. 

69 """ 

70 

71 @abc.abstractmethod 

72 def update(self, data: Buffer) -> None: 

73 """ 

74 Processes the provided bytes through the hash. 

75 """ 

76 

77 @abc.abstractmethod 

78 def finalize(self) -> bytes: 

79 """ 

80 Finalizes the hash context and returns the hash digest as bytes. 

81 """ 

82 

83 @abc.abstractmethod 

84 def copy(self) -> HashContext: 

85 """ 

86 Return a HashContext that is a copy of the current context. 

87 """ 

88 

89 

90Hash = rust_openssl.hashes.Hash 

91HashContext.register(Hash) 

92 

93XOFHash = rust_openssl.hashes.XOFHash 

94 

95 

96class ExtendableOutputFunction(metaclass=abc.ABCMeta): 

97 """ 

98 An interface for extendable output functions. 

99 """ 

100 

101 

102class SHA1(HashAlgorithm): 

103 name = "sha1" 

104 digest_size = 20 

105 block_size = 64 

106 

107 def __eq__(self, other: object) -> bool: 

108 if not isinstance(other, SHA1): 

109 return NotImplemented 

110 

111 return True 

112 

113 

114class SHA512_224(HashAlgorithm): # noqa: N801 

115 name = "sha512-224" 

116 digest_size = 28 

117 block_size = 128 

118 

119 def __eq__(self, other: object) -> bool: 

120 if not isinstance(other, SHA512_224): 

121 return NotImplemented 

122 

123 return True 

124 

125 

126class SHA512_256(HashAlgorithm): # noqa: N801 

127 name = "sha512-256" 

128 digest_size = 32 

129 block_size = 128 

130 

131 def __eq__(self, other: object) -> bool: 

132 if not isinstance(other, SHA512_256): 

133 return NotImplemented 

134 

135 return True 

136 

137 

138class SHA224(HashAlgorithm): 

139 name = "sha224" 

140 digest_size = 28 

141 block_size = 64 

142 

143 def __eq__(self, other: object) -> bool: 

144 if not isinstance(other, SHA224): 

145 return NotImplemented 

146 

147 return True 

148 

149 

150class SHA256(HashAlgorithm): 

151 name = "sha256" 

152 digest_size = 32 

153 block_size = 64 

154 

155 def __eq__(self, other: object) -> bool: 

156 if not isinstance(other, SHA256): 

157 return NotImplemented 

158 

159 return True 

160 

161 

162class SHA384(HashAlgorithm): 

163 name = "sha384" 

164 digest_size = 48 

165 block_size = 128 

166 

167 def __eq__(self, other: object) -> bool: 

168 if not isinstance(other, SHA384): 

169 return NotImplemented 

170 

171 return True 

172 

173 

174class SHA512(HashAlgorithm): 

175 name = "sha512" 

176 digest_size = 64 

177 block_size = 128 

178 

179 def __eq__(self, other: object) -> bool: 

180 if not isinstance(other, SHA512): 

181 return NotImplemented 

182 

183 return True 

184 

185 

186class SHA3_224(HashAlgorithm): # noqa: N801 

187 name = "sha3-224" 

188 digest_size = 28 

189 block_size = None 

190 

191 def __eq__(self, other: object) -> bool: 

192 if not isinstance(other, SHA3_224): 

193 return NotImplemented 

194 

195 return True 

196 

197 

198class SHA3_256(HashAlgorithm): # noqa: N801 

199 name = "sha3-256" 

200 digest_size = 32 

201 block_size = None 

202 

203 def __eq__(self, other: object) -> bool: 

204 if not isinstance(other, SHA3_256): 

205 return NotImplemented 

206 

207 return True 

208 

209 

210class SHA3_384(HashAlgorithm): # noqa: N801 

211 name = "sha3-384" 

212 digest_size = 48 

213 block_size = None 

214 

215 def __eq__(self, other: object) -> bool: 

216 if not isinstance(other, SHA3_384): 

217 return NotImplemented 

218 

219 return True 

220 

221 

222class SHA3_512(HashAlgorithm): # noqa: N801 

223 name = "sha3-512" 

224 digest_size = 64 

225 block_size = None 

226 

227 def __eq__(self, other: object) -> bool: 

228 if not isinstance(other, SHA3_512): 

229 return NotImplemented 

230 

231 return True 

232 

233 

234class SHAKE128(HashAlgorithm, ExtendableOutputFunction): 

235 name = "shake128" 

236 block_size = None 

237 

238 def __init__(self, digest_size: int): 

239 if not isinstance(digest_size, int): 

240 raise TypeError("digest_size must be an integer") 

241 

242 if digest_size < 1: 

243 raise ValueError("digest_size must be a positive integer") 

244 

245 self._digest_size = digest_size 

246 

247 def __eq__(self, other: object) -> bool: 

248 if not isinstance(other, SHAKE128): 

249 return NotImplemented 

250 

251 return self._digest_size == other._digest_size 

252 

253 @property 

254 def digest_size(self) -> int: 

255 return self._digest_size 

256 

257 @classmethod 

258 def xof(cls): 

259 return cls(sys.maxsize) 

260 

261 

262class SHAKE256(HashAlgorithm, ExtendableOutputFunction): 

263 name = "shake256" 

264 block_size = None 

265 

266 def __init__(self, digest_size: int): 

267 if not isinstance(digest_size, int): 

268 raise TypeError("digest_size must be an integer") 

269 

270 if digest_size < 1: 

271 raise ValueError("digest_size must be a positive integer") 

272 

273 self._digest_size = digest_size 

274 

275 def __eq__(self, other: object) -> bool: 

276 if not isinstance(other, SHAKE256): 

277 return NotImplemented 

278 

279 return self._digest_size == other._digest_size 

280 

281 @property 

282 def digest_size(self) -> int: 

283 return self._digest_size 

284 

285 @classmethod 

286 def xof(cls): 

287 return cls(sys.maxsize) 

288 

289 

290class MD5(HashAlgorithm): 

291 name = "md5" 

292 digest_size = 16 

293 block_size = 64 

294 

295 def __eq__(self, other: object) -> bool: 

296 if not isinstance(other, MD5): 

297 return NotImplemented 

298 

299 return True 

300 

301 

302class BLAKE2b(HashAlgorithm): 

303 name = "blake2b" 

304 _max_digest_size = 64 

305 _min_digest_size = 1 

306 block_size = 128 

307 

308 def __init__(self, digest_size: int): 

309 if digest_size != 64: 

310 raise ValueError("Digest size must be 64") 

311 

312 self._digest_size = digest_size 

313 

314 def __eq__(self, other: object) -> bool: 

315 if not isinstance(other, BLAKE2b): 

316 return NotImplemented 

317 

318 return self._digest_size == other._digest_size 

319 

320 @property 

321 def digest_size(self) -> int: 

322 return self._digest_size 

323 

324 

325class BLAKE2s(HashAlgorithm): 

326 name = "blake2s" 

327 block_size = 64 

328 _max_digest_size = 32 

329 _min_digest_size = 1 

330 

331 def __init__(self, digest_size: int): 

332 if digest_size != 32: 

333 raise ValueError("Digest size must be 32") 

334 

335 self._digest_size = digest_size 

336 

337 def __eq__(self, other: object) -> bool: 

338 if not isinstance(other, BLAKE2s): 

339 return NotImplemented 

340 

341 return self._digest_size == other._digest_size 

342 

343 @property 

344 def digest_size(self) -> int: 

345 return self._digest_size 

346 

347 

348class SM3(HashAlgorithm): 

349 name = "sm3" 

350 digest_size = 32 

351 block_size = 64 

352 

353 def __eq__(self, other: object) -> bool: 

354 if not isinstance(other, SM3): 

355 return NotImplemented 

356 

357 return True