@@ -105,10 +105,14 @@ def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm):
105105
106106 super (HashLibTestCase , self ).__init__ (* args , ** kwargs )
107107
108+ @property
109+ def hash_constructors (self ):
110+ constructors = self .constructors_to_test .values ()
111+ return itertools .chain .from_iterable (constructors )
112+
108113 def test_hash_array (self ):
109114 a = array .array ("b" , range (10 ))
110- constructors = self .constructors_to_test .values ()
111- for cons in itertools .chain .from_iterable (constructors ):
115+ for cons in self .hash_constructors :
112116 c = cons (a )
113117 c .hexdigest ()
114118
@@ -145,8 +149,8 @@ def test_get_builtin_constructor(self):
145149 self .assertRaises (TypeError , get_builtin_constructor , 3 )
146150
147151 def test_hexdigest (self ):
148- for name in self .supported_hash_names :
149- h = hashlib . new ( name )
152+ for cons in self .hash_constructors :
153+ h = cons ( )
150154 assert isinstance (h .digest (), bytes ), name
151155 self .assertEqual (hexstr (h .digest ()), h .hexdigest ())
152156
@@ -155,30 +159,48 @@ def test_large_update(self):
155159 aas = b'a' * 128
156160 bees = b'b' * 127
157161 cees = b'c' * 126
162+ dees = b'd' * 2048 # HASHLIB_GIL_MINSIZE
158163
159- for name in self .supported_hash_names :
160- m1 = hashlib . new ( name )
164+ for cons in self .hash_constructors :
165+ m1 = cons ( )
161166 m1 .update (aas )
162167 m1 .update (bees )
163168 m1 .update (cees )
169+ m1 .update (dees )
164170
165- m2 = hashlib . new ( name )
166- m2 .update (aas + bees + cees )
171+ m2 = cons ( )
172+ m2 .update (aas + bees + cees + dees )
167173 self .assertEqual (m1 .digest (), m2 .digest ())
168174
169- def check (self , name , data , digest ):
170- digest = digest .lower ()
175+ m3 = cons (aas + bees + cees + dees )
176+ self .assertEqual (m1 .digest (), m3 .digest ())
177+
178+ # verify copy() doesn't touch original
179+ m4 = cons (aas + bees + cees )
180+ m4_digest = m4 .digest ()
181+ m4_copy = m4 .copy ()
182+ m4_copy .update (dees )
183+ self .assertEqual (m1 .digest (), m4_copy .digest ())
184+ self .assertEqual (m4 .digest (), m4_digest )
185+
186+ def check (self , name , data , hexdigest ):
187+ hexdigest = hexdigest .lower ()
171188 constructors = self .constructors_to_test [name ]
172189 # 2 is for hashlib.name(...) and hashlib.new(name, ...)
173190 self .assertGreaterEqual (len (constructors ), 2 )
174191 for hash_object_constructor in constructors :
175- computed = hash_object_constructor (data ).hexdigest ()
192+ m = hash_object_constructor (data )
193+ computed = m .hexdigest ()
176194 self .assertEqual (
177- computed , digest ,
195+ computed , hexdigest ,
178196 "Hash algorithm %s constructed using %s returned hexdigest"
179197 " %r for %d byte input data that should have hashed to %r."
180198 % (name , hash_object_constructor ,
181- computed , len (data ), digest ))
199+ computed , len (data ), hexdigest ))
200+ computed = m .digest ()
201+ digest = bytes .fromhex (hexdigest )
202+ self .assertEqual (computed , digest )
203+ self .assertEqual (len (digest ), m .digest_size )
182204
183205 def check_no_unicode (self , algorithm_name ):
184206 # Unicode objects are not allowed as input.
@@ -198,6 +220,29 @@ def test_no_unicode(self):
198220 self .check_no_unicode ('sha3_384' )
199221 self .check_no_unicode ('sha3_512' )
200222
223+ def check_blocksize_name (self , name , block_size = 0 , digest_size = 0 ):
224+ constructors = self .constructors_to_test [name ]
225+ for hash_object_constructor in constructors :
226+ m = hash_object_constructor ()
227+ self .assertEqual (m .block_size , block_size )
228+ self .assertEqual (m .digest_size , digest_size )
229+ self .assertEqual (len (m .digest ()), digest_size )
230+ self .assertEqual (m .name .lower (), name .lower ())
231+ # split for sha3_512 / _sha3.sha3 object
232+ self .assertIn (name .split ("_" )[0 ], repr (m ).lower ())
233+
234+ def test_blocksize_name (self ):
235+ self .check_blocksize_name ('md5' , 64 , 16 )
236+ self .check_blocksize_name ('sha1' , 64 , 20 )
237+ self .check_blocksize_name ('sha224' , 64 , 28 )
238+ self .check_blocksize_name ('sha256' , 64 , 32 )
239+ self .check_blocksize_name ('sha384' , 128 , 48 )
240+ self .check_blocksize_name ('sha512' , 128 , 64 )
241+ self .check_blocksize_name ('sha3_224' , NotImplemented , 28 )
242+ self .check_blocksize_name ('sha3_256' , NotImplemented , 32 )
243+ self .check_blocksize_name ('sha3_384' , NotImplemented , 48 )
244+ self .check_blocksize_name ('sha3_512' , NotImplemented , 64 )
245+
201246 def test_case_md5_0 (self ):
202247 self .check ('md5' , b'' , 'd41d8cd98f00b204e9800998ecf8427e' )
203248
@@ -439,13 +484,13 @@ def test_gil(self):
439484 # for multithreaded operation (which is hardwired to 2048).
440485 gil_minsize = 2048
441486
442- for name in self .supported_hash_names :
443- m = hashlib . new ( name )
487+ for cons in self .hash_constructors :
488+ m = cons ( )
444489 m .update (b'1' )
445490 m .update (b'#' * gil_minsize )
446491 m .update (b'1' )
447492
448- m = hashlib . new ( name , b'x' * gil_minsize )
493+ m = cons ( b'x' * gil_minsize )
449494 m .update (b'1' )
450495
451496 m = hashlib .md5 ()
0 commit comments