OSDN Git Service

Python bindings: Significantly speed up computation by using NumPy package.
authorLoRd_MuldeR <mulder2@gmx.de>
Mon, 10 Jul 2017 20:01:21 +0000 (22:01 +0200)
committerLoRd_MuldeR <mulder2@gmx.de>
Mon, 10 Jul 2017 20:01:21 +0000 (22:01 +0200)
bindings/Python/library/MHashPy384.py

index f9f406b..1ae349e 100644 (file)
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.        #
 ##################################################################################################
 
+try:
+    np = __import__('numpy')
+except Exception as e:
+    raise RuntimeError('The required "NumPy" package appears to be missing. Please see http://www.numpy.org/ for details!') from e
+
 class MHash384:
     #------------------------------------------------------------------------
     # CONSTANTS
@@ -29,7 +34,7 @@ class MHash384:
     __VERSION_MINOR = 1
     __VERSION_PATCH = 0
 
-    __TABLE_XOR = (
+    __TABLE_XOR = tuple(np.frombuffer(row, dtype='uint8') for row in (
         b'\x41\xA8\xBF\xAF\xD3\xAA\xDA\x1F\x86\x12\xC9\xEE\x67\xA2\xE7\x9E\xEE\x7C\x12\xEE\x9E\xD9\xAA\x4A\x9F\x78\xE2\x88\x05\x5E\x46\x51\x8C\xBB\xAF\xFA\xE5\x6E\x69\x7C\xAF\x18\x95\x76\xBB\x07\xB2\x9B', #00
         b'\x56\x32\x92\x79\x33\x26\x36\x7D\xDF\x6F\x00\x18\xAC\xC7\x56\xC3\xF8\xF3\xAE\x1F\xFA\x61\x78\x9F\x8F\x4B\xC6\x31\x18\x69\x40\xA1\x09\xA3\xA9\x8E\x38\x0A\x28\xE0\x41\xE5\xBA\x67\xD7\xA2\xCE\xF0', #01
         b'\x04\xEA\xF6\x14\xB1\x73\x2B\x24\x20\x36\x94\x76\x2C\x03\x3D\x66\xAD\xD1\x23\x3D\x7F\x5A\x78\x63\x3D\x31\x72\x18\xC5\x3F\xE0\xBC\xB2\x86\x48\x49\xEF\xDF\x2F\xD6\xAF\x93\x22\x5D\x8A\x6F\xA9\x58', #02
@@ -287,9 +292,9 @@ class MHash384:
         b'\x64\x24\x4B\xC1\x2E\x07\x77\x1F\x73\x9B\xAC\x44\xAA\xF0\x0B\x40\x25\x24\xA4\x06\x8E\xDE\xD1\xD7\x50\x94\xD8\x38\x47\x04\x98\x07\x3A\x90\x12\x20\x70\xEF\xD4\xDB\xDC\x93\x19\x0E\x8B\x18\x2C\x77', #FE
         b'\xDB\xD3\x8F\xCA\x2B\xA2\xC9\xBE\x6D\x3E\xE4\x2F\x11\xBF\x0D\x6E\x9D\x00\x37\xD3\xED\x00\x90\xED\x42\x6F\x05\x9F\x15\x54\xA6\x89\xE8\xC2\x2A\xDC\x91\xE2\x24\x36\x8A\x15\x1A\x64\x83\xAA\x5F\xFC', #FF
         b'\x86\x03\x84\x37\xA0\x03\x00\x40\xC1\xC9\xC1\x6B\x9D\xE2\x8D\x82\x1D\x94\x59\x3C\xB7\xDD\xA8\xB1\x56\xFF\x9A\xE3\x34\x26\x4C\x2E\x88\x35\xB6\x00\x2D\x96\x65\x7A\x37\x30\x41\x9F\x5E\x43\xF2\x02'  #ZZ
-    )
+    ))
 
-    __TABLE_MIX = (
+    __TABLE_MIX = tuple(np.frombuffer(row, dtype='uint8') for row in (
         b'\x06\x17\x05\x21\x10\x2A\x12\x0F\x13\x00\x1B\x23\x1E\x2C\x0A\x2E\x0B\x25\x18\x2F\x29\x04\x0D\x1F\x07\x1A\x09\x20\x15\x26\x08\x22\x2D\x03\x19\x11\x0C\x16\x27\x2B\x24\x1D\x1C\x02\x01\x28\x0E\x14',
         b'\x29\x16\x27\x02\x2C\x08\x2E\x0C\x05\x18\x20\x28\x2D\x0E\x15\x11\x0D\x25\x10\x17\x26\x1D\x00\x1C\x2A\x0B\x09\x0A\x23\x06\x07\x04\x2B\x1E\x1A\x24\x21\x2F\x22\x19\x0F\x01\x14\x03\x13\x1B\x12\x1F',
         b'\x25\x19\x12\x28\x2D\x06\x21\x01\x09\x17\x0F\x16\x2A\x11\x1B\x24\x14\x1E\x2C\x2B\x0B\x23\x02\x10\x13\x26\x29\x20\x07\x1C\x1D\x27\x22\x1A\x0A\x18\x1F\x0D\x00\x2E\x15\x0E\x2F\x04\x0C\x03\x05\x08',
@@ -1287,7 +1292,7 @@ class MHash384:
         b'\x23\x08\x22\x20\x14\x28\x04\x12\x2E\x03\x1E\x21\x0F\x2F\x19\x29\x24\x02\x0C\x1A\x2C\x1D\x26\x07\x1F\x10\x15\x2D\x27\x0A\x13\x00\x06\x09\x17\x0D\x18\x16\x05\x1B\x25\x01\x1C\x0E\x0B\x2B\x11\x2A',
         b'\x1F\x06\x29\x22\x1A\x11\x1D\x04\x14\x15\x2D\x02\x0E\x0B\x0F\x08\x27\x2A\x00\x17\x25\x1B\x1E\x05\x26\x2E\x07\x01\x10\x16\x21\x09\x2F\x0D\x24\x20\x2B\x0C\x18\x23\x1C\x03\x28\x12\x0A\x13\x2C\x19',
         b'\x13\x0C\x2B\x2D\x02\x0D\x24\x19\x12\x29\x10\x05\x0E\x22\x06\x14\x09\x20\x26\x2C\x1F\x21\x00\x03\x07\x2F\x23\x18\x16\x0F\x1B\x1E\x1D\x11\x27\x25\x17\x08\x04\x15\x01\x2A\x0B\x1A\x1C\x2E\x28\x0A'
-    )
+    ))
 
     __TSIZE_XOR = len(__TABLE_XOR)
     __TSIZE_MIX = len(__TABLE_MIX)
@@ -1297,7 +1302,7 @@ class MHash384:
     #------------------------------------------------------------------------
 
     def __init__(self):
-        self.__digest = bytes(0x00 for _ in range(self.__class__.__HASH_LEN))
+        self.__digest = np.zeros(self.__class__.__HASH_LEN, dtype='uint8')
         self.__rnd = 0
 
     #------------------------------------------------------------------------
@@ -1309,18 +1314,16 @@ class MHash384:
             raise TypeError('input must be sequence of bytes')
         cls, digest, rnd = self.__class__, self.__digest, self.__rnd
         for val in input:
-            digest = bytes(digest[mix] ^ xor for (mix,xor) \
-                in zip(cls.__TABLE_MIX[rnd], cls.__TABLE_XOR[val]))
+            np.bitwise_xor(digest[cls.__TABLE_MIX[rnd]], cls.__TABLE_XOR[val], out=digest)
             rnd = (rnd + 1) % cls.__TSIZE_MIX
         self.__digest, self.__rnd = digest, rnd
 
     def digest(self):
         cls = self.__class__
-        return bytes(val ^ xor for (val,xor) \
-            in zip(self.__digest, cls.__TABLE_XOR[cls.__TSIZE_XOR - 1]))
+        return bytes(np.bitwise_xor(self.__digest, cls.__TABLE_XOR[cls.__TSIZE_XOR - 1]))
 
     def reset(self):
-        self.__digest = bytes(0x00 for _ in range(self.__class__.__HASH_LEN))
+        self.__digest.fill(0)
         self.__rnd = 0
 
     @classmethod
@@ -1385,3 +1388,4 @@ class MHash384:
                 raise AssertionError('Test vector did NOT compare equal!')
             print('\r' + str(bin2hex.hexlify(result)))
         print('Self-test completed successfully.')
+