X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=pygost%2Fpbkdf2.py;fp=pygost%2Fpbkdf2.py;h=33df6fec445b2b2c11ad2ddb67a8eb5f2bdad11d;hb=212bb9852fd66cf0b1ac054ed36408fd29752c62;hp=0000000000000000000000000000000000000000;hpb=5f31b66fe7bfc9e872108cef21fd82800c09b87d;p=pygost.git diff --git a/pygost/pbkdf2.py b/pygost/pbkdf2.py new file mode 100644 index 0000000..33df6fe --- /dev/null +++ b/pygost/pbkdf2.py @@ -0,0 +1,41 @@ +# coding: utf-8 +""" PBKDF2 implementation suitable for GOST R 34.11-94/34.11-2012. + +This implementation is based on Python 3.5.2 source code's one. +PyGOST does not register itself in hashlib anyway, so use it instead. +""" + + +from pygost.utils import bytes2long +from pygost.utils import long2bytes +from pygost.utils import strxor +from pygost.utils import xrange # pylint: disable=redefined-builtin + + +def pbkdf2(hasher, password, salt, iterations, dklen): + """PBKDF2 implementation suitable for GOST R 34.11-94/34.11-2012 + """ + inner = hasher() + outer = hasher() + password = password + b"\x00" * (inner.block_size - len(password)) + inner.update(strxor(password, len(password) * b"\x36")) + outer.update(strxor(password, len(password) * b"\x5C")) + + def prf(msg): + icpy = inner.copy() + ocpy = outer.copy() + icpy.update(msg) + ocpy.update(icpy.digest()) + return ocpy.digest() + + dkey = b'' + loop = 1 + while len(dkey) < dklen: + prev = prf(salt + long2bytes(loop, 4)) + rkey = bytes2long(prev) + for _ in xrange(iterations - 1): + prev = prf(prev) + rkey ^= bytes2long(prev) + loop += 1 + dkey += long2bytes(rkey, inner.digest_size) + return dkey[:dklen]