A new hash object is created by one of the following three functions:
These constructor functions return a corresponding hash object for Skein-256, Skein-512, or Skein-1024 (i.e. 256, 512, or 1024 bits internal state). They optionally take an initial chunk of data to hash (init) and the desired digest length in bits (digest_bits, must be < 2**31).
Further optional parameters are:
- mac: a key for use of Skein as a MAC, arbitrary bytes
- pers: a personalization string, arbitrary bytes
- nonce: a nonce value, arbitrary bytes
- tree: tree hashing parameters, a tuple (leaf, fan_out, max_height)
For details about the meaning of these parameters please consult the Skein specification.
Note: Specifying these four parameters as positional arguments is deprecated - please use them as keyword arguments only!
Hash objects have the following methods:
Hash the given message (of type bytes) into the internal state. (Strings have to be encoded to bytes first.) Repeated calls are equivalent to a single call with the concatenation of all the arguments.
If given, the argument bits has to be <=8*len(message) and specifies how many bits of the message are hashed. Specifically, the first bits//8 full bytes and the bits%8 most significant bits of the following byte are hashed. If omitted, bits defaults to 8*len(message).
Caveat: If the number of hashed bits so far is not a multiple of 8, then bits must be specified with a value of at most 8-hashed_bits%8. Otherwise a ValueError will be raised. This ensures proper byte alignment of subsequent hashing operations.
In addition each hash object has the following attributes:
Note: Hash objects are picklable, but the pickle data may contain a buffer with up to one block of still unhashed data. To avoid exposure of unhashed data, make sure that you have hashed a multiple of block_size bytes before pickling.
Make a Skein-512 hash object with default digest length (512 bits) and hash some data:
>>> from skein import skein256, skein512, skein1024
>>> h = skein512()
>>> h.update(b'Nobody inspects')
>>> h.update(b' the spammish repetition')
>>> h.digest()
b'\xad\xd2\xc32\x8a \xa6\xfc\xeb\x89i\xcbr\x0e\xa3\x83~>\x9e\x1e%\xfb\x17\x8f\xa8h8\xbb\x8f\xac\x8f\xf6\x84\xbb~\x02\x0cZ\xdbK\x89:b\x84\x9dWq\x0c\x9f\x8c\xc65\xc6k>HZ\x9a\xbd$\x9f39\x1e'
>>> h.digest_size, h.digest_bits
(64, 512)
>>> h.block_size, h.block_bits
(64, 512)
Similarly for Skein-1024-384:
>>> h = skein1024(b'Nobody inspects the spammish repetition', digest_bits=384)
>>> h.hexdigest()
'ee9c327d52b960fe443885c8000508d3ce5ef0700d3e5d7646b5c99605dbb327c8bcd5a93b3dbe5c439243795c7bf780'
>>> h.digest_size, h.digest_bits
(48, 384)
>>> h.block_size, h.block_bits
(128, 1024)
Hashing with a MAC key, a personalization string or a nonce value (or all of them) changes the digest:
>>> skein256(b'message').hexdigest()
'23f5b683765f67bd3d8de82938a949f1b5bc83b83ee4d621b5d74fff5c40c8e9'
>>> skein256(b'message', mac=b'foobar').hexdigest()
'283299f2ef51392b312193478a520402b53f3ea79605d3daa42251daff8709e8'
>>> skein256(b'message', pers=b'foobar').hexdigest()
'4afd97f1f703bc9dff89a2a189171e935c15598ce74df0639d080cbd5e76cdee'
>>> skein256(b'message', nonce=b'foobar').hexdigest()
'dd265cda71330e4c5c8efe95763d1fe76cd1603ca80f8da5819ac6de664772f1'
>>> skein256(b'message', mac=b'foo', pers=b'bar', nonce=b'baz').hexdigest()
'58da697148a1b26332197015ba618a61beab1452dc0ddefbe227bf5ccd684451'
Tree hashing uses the same incremental interface as sequential hashing. To hash with a leaf size of 2**L blocks, a fan-out of 2**F children per node and a maximum tree height of M, simply specify a tree parameter of (L, F, M):
>>> h = skein256(tree=(5, 2, 255))
>>> for _ in range(1000):
... h.update(b'\0' * 10**6)
...
>>> h.update(b'foobar')
>>> h.hexdigest()
'2c1531d8e1b7d28de7c3e47085d94738270f0d05bfb40e87b8613b05792828cf'
In tree hashing mode, PySkein will use two threads to speed up hashing on multi-core systems. Note that the digests produced in tree hashing differ from those produced in sequential hashing, and also depend on the tree parameter. If you are not restricted by interoperability issues, you can try different leaf sizes to find the value leading to optimal performance on your machine.