I came across an issue and realized that I had no idea what SHA-2 is, which, designed by NSA, consists of SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and SHA-512/256, even I was aware of a variant like hashlib.sha512, I really didn’t know those functions from hashlib are part of SHA-2 set. SHA-2 was published in 2001.

I then learned that there is even a SHA-3, which is a subset of Keccak, and it’s actually becoming the official SHA-3 hash function in NIST hash function competition in October, 2012. It’s designed by Guido Bertoni, Joan Daemen, MichaĆ«l Peeters, and Gilles Van Assche.

For SHA-2, you can have some variants from hashlib, SHA-3, the variants are shipped with Python 3.4 (March 16, 2014) according to pysha3‘s README.

1   Result

There doesn’t seem to much difference between Python 2 and 3, so I am just posting one result with 2.7.6:

2.7.6 (default, Jun  6 2014, 09:33:35) [GCC 4.7.3]

Generating random data 1048576...
timeit for 3 repeats, 10 runs

md5     :  0.032268 seconds @ 30.990791 MiB/s
sha1    :  0.038351 seconds @ 26.075115 MiB/s
sha224  :  0.093446 seconds @ 10.701402 MiB/s
sha256  :  0.092506 seconds @ 10.810108 MiB/s
sha384  :  0.058980 seconds @ 16.954812 MiB/s
sha512  :  0.058883 seconds @ 16.982821 MiB/s
sha3_224:  0.506505 seconds @  1.974315 MiB/s
sha3_256:  0.534688 seconds @  1.870251 MiB/s
sha3_384:  0.697314 seconds @  1.434074 MiB/s
sha3_512:  1.004131 seconds @  0.995886 MiB/s

Since I don’t have Python 3.4—don’t want to install ~amd64 package on my Gentoo—so I have to use pysha3 package, but I think it wouldn’t have much differences. The pysha3 version I used is hg-r110:fd8c17b3cd97 (Wed Jul 31 13:33:01 2013 +0200, post v0.3 (hg-r79:fac6bea132d3, Sun Oct 14 23:42:22 2012 +0200)). The version 0.3 is compatible with Python 3.3, which raises an undefined symbol error, with latest from respository, it runs normally.

2   Script

#!/usr/bin/env python
# Written by Yu-Jie Lin
# Public Domain

from __future__ import print_function
import hashlib
import os
import sys
import timeit

# https://pypi.python.org/pypi/pysha3/
# sha3_* are introduced in Python 3.4+
if sys.version_info < (3, 4):
  import sha3

DATASIZE = 2**20
REPEAT = 3
NUMBER = 10
HASHES = (
  'md5',
  'sha1', 'sha224', 'sha256', 'sha384', 'sha512',
  'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
)

width = max(len(f) for f in HASHES)

print(sys.version.replace('\n', ''))
print()

print('Generating random data %d...' % DATASIZE)
data = os.urandom(DATASIZE)

print('timeit for %d repeats, %d runs' % (REPEAT, NUMBER))
print()

for f in HASHES:
  t = timeit.Timer(
    '%s(data).hexdigest()' % f,
    'from __main__ import data; from hashlib import %s' % f
  )
  result = t.repeat(repeat=REPEAT, number=NUMBER)
  average = sum(result) / len(result)
  print('{:{width}s}: {:9.6f} seconds @ {:9.6f} MiB/s'.format(
    f,
    average,
    DATASIZE / average / (2**20),
    width=width
  ))