X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=pygost%2Fgost3413.py;h=3a539d2e4b1f9097e78774ea3cf263df648a9d5a;hb=54735617392b3988c2e24b59e0c552d74736e320;hp=bd8cc49ad7e8c2ae20fa6cf5f6ced910b60a68a9;hpb=43fdce36120844bc0fc38e0d5664dfc7090c119a;p=pygost.git diff --git a/pygost/gost3413.py b/pygost/gost3413.py index bd8cc49..3a539d2 100644 --- a/pygost/gost3413.py +++ b/pygost/gost3413.py @@ -1,11 +1,10 @@ # coding: utf-8 # PyGOST -- Pure Python GOST cryptographic functions library -# Copyright (C) 2015-2017 Sergey Matveev +# Copyright (C) 2015-2020 Sergey Matveev # # 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 @@ -75,7 +74,7 @@ def pad3(data, blocksize): def ecb_encrypt(encrypter, bs, pt): """ECB encryption mode of operation - :param encrypter: Encrypting function, that takes block as an input + :param encrypter: encrypting function, that takes block as an input :param int bs: cipher's blocksize :param bytes pt: already padded plaintext """ @@ -105,7 +104,7 @@ def ecb_decrypt(decrypter, bs, ct): def ctr(encrypter, bs, data, iv): """Counter mode of operation - :param encrypter: Encrypting function, that takes block as an input + :param encrypter: encrypting function, that takes block as an input :param int bs: cipher's blocksize :param bytes data: plaintext/ciphertext :param bytes iv: half blocksize-sized initialization vector @@ -125,40 +124,40 @@ def ctr(encrypter, bs, data, iv): def ofb(encrypter, bs, data, iv): """OFB mode of operation - :param encrypter: Encrypting function, that takes block as an input + :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) def cbc_encrypt(encrypter, bs, pt, iv): """CBC encryption mode of operation - :param encrypter: Encrypting function, that takes block as an input + :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) @@ -168,55 +167,55 @@ def cbc_decrypt(decrypter, bs, ct, iv): :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) def cfb_encrypt(encrypter, bs, pt, iv): """CFB encryption mode of operation - :param encrypter: Encrypting function, that takes block as an input + :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) def cfb_decrypt(encrypter, bs, ct, iv): """CFB decryption mode of operation - :param encrypter: Encrypting function, that takes block as an input + :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) @@ -236,7 +235,7 @@ def _mac_ks(encrypter, bs): def mac(encrypter, bs, data): """MAC (known here as CMAC, OMAC1) mode of operation - :param encrypter: Encrypting function, that takes block as an input + :param encrypter: encrypting function, that takes block as an input :param int bs: cipher's blocksize :param bytes data: data to authenticate