# coding: utf-8
# PyGOST -- Pure Python GOST cryptographic functions library
-# Copyright (C) 2015-2017 Sergey Matveev <stargrave@stargrave.org>
+# Copyright (C) 2015-2019 Sergey Matveev <stargrave@stargrave.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
:param encrypter: Encrypting function, that takes block as an input
:param int bs: cipher's blocksize
:param bytes data: plaintext/ciphertext
- :param bytes iv: double blocksize-sized initialization vector
+ :param bytes iv: blocksize-sized initialization vector
For decryption you use the same function again.
"""
- if len(iv) != 2 * bs:
+ if len(iv) < bs or len(iv) % bs != 0:
raise ValueError("Invalid IV size")
- r = [iv[:bs], iv[bs:]]
+ r = [iv[i:i + bs] for i in range(0, len(iv), bs)]
result = []
for i in xrange(0, len(data) + pad_size(len(data), bs), bs):
- r = [r[1], encrypter(r[0])]
- result.append(strxor(r[1], data[i:i + bs]))
+ r = r[1:] + [encrypter(r[0])]
+ result.append(strxor(r[-1], data[i:i + bs]))
return b"".join(result)
:param encrypter: Encrypting function, that takes block as an input
:param int bs: cipher's blocksize
:param bytes pt: already padded plaintext
- :param bytes iv: double blocksize-sized initialization vector
+ :param bytes iv: blocksize-sized initialization vector
"""
if not pt or len(pt) % bs != 0:
raise ValueError("Plaintext is not blocksize aligned")
- if len(iv) != 2 * bs:
+ if len(iv) < bs or len(iv) % bs != 0:
raise ValueError("Invalid IV size")
- r = [iv[:bs], iv[bs:]]
+ r = [iv[i:i + bs] for i in range(0, len(iv), bs)]
ct = []
for i in xrange(0, len(pt), bs):
ct.append(encrypter(strxor(r[0], pt[i:i + bs])))
- r = [r[1], ct[-1]]
+ r = r[1:] + [ct[-1]]
return b"".join(ct)
:param decrypter: Decrypting function, that takes block as an input
:param int bs: cipher's blocksize
:param bytes ct: ciphertext
- :param bytes iv: double blocksize-sized initialization vector
+ :param bytes iv: blocksize-sized initialization vector
"""
if not ct or len(ct) % bs != 0:
raise ValueError("Ciphertext is not blocksize aligned")
- if len(iv) != 2 * bs:
+ if len(iv) < bs or len(iv) % bs != 0:
raise ValueError("Invalid IV size")
- r = [iv[:bs], iv[bs:]]
+ r = [iv[i:i + bs] for i in range(0, len(iv), bs)]
pt = []
for i in xrange(0, len(ct), bs):
blk = ct[i:i + bs]
pt.append(strxor(r[0], decrypter(blk)))
- r = [r[1], blk]
+ r = r[1:] + [blk]
return b"".join(pt)
:param encrypter: Encrypting function, that takes block as an input
:param int bs: cipher's blocksize
:param bytes pt: plaintext
- :param bytes iv: double blocksize-sized initialization vector
+ :param bytes iv: blocksize-sized initialization vector
"""
- if len(iv) != 2 * bs:
+ if len(iv) < bs or len(iv) % bs != 0:
raise ValueError("Invalid IV size")
- r = [iv[:bs], iv[bs:]]
+ r = [iv[i:i + bs] for i in range(0, len(iv), bs)]
ct = []
for i in xrange(0, len(pt) + pad_size(len(pt), bs), bs):
ct.append(strxor(encrypter(r[0]), pt[i:i + bs]))
- r = [r[1], ct[-1]]
+ r = r[1:] + [ct[-1]]
return b"".join(ct)
:param encrypter: Encrypting function, that takes block as an input
:param int bs: cipher's blocksize
:param bytes ct: ciphertext
- :param bytes iv: double blocksize-sized initialization vector
+ :param bytes iv: blocksize-sized initialization vector
"""
- if len(iv) != 2 * bs:
+ if len(iv) < bs or len(iv) % bs != 0:
raise ValueError("Invalid IV size")
- r = [iv[:bs], iv[bs:]]
+ r = [iv[i:i + bs] for i in range(0, len(iv), bs)]
pt = []
for i in xrange(0, len(ct) + pad_size(len(ct), bs), bs):
blk = ct[i:i + bs]
pt.append(strxor(encrypter(r[0]), blk))
- r = [r[1], blk]
+ r = r[1:] + [blk]
return b"".join(pt)