# 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
__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
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',
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)
#------------------------------------------------------------------------
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
#------------------------------------------------------------------------
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
raise AssertionError('Test vector did NOT compare equal!')
print('\r' + str(bin2hex.hexlify(result)))
print('Self-test completed successfully.')
+