-""" Pure Python GOST cryptographic functions library.
+"""Pure Python GOST cryptographic functions library.
PyGOST is free software: see the file COPYING for copying conditions.
"""
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-""" GOST 28147-89 block cipher
+"""GOST 28147-89 block cipher
This is implementation of :rfc:`5830` ECB, CNT, CFB and :rfc:`4357`
CBC modes of operation. N1, N2, K names are taken according to
def _K(s, _in):
- """ S-box substitution
+ """S-box substitution
:param s: S-box
:param _in: 32-bit word
def block2ns(data):
- """ Convert block to N1 and N2 integers
+ """Convert block to N1 and N2 integers
"""
data = bytearray(data)
return (
def ns2block(ns):
- """ Convert N1 and N2 integers to 8-byte block
+ """Convert N1 and N2 integers to 8-byte block
"""
n1, n2 = ns
return bytes(bytearray((
def _shift11(x):
- """ 11-bit cyclic shift
+ """11-bit cyclic shift
"""
return ((x << 11) & (2 ** 32 - 1)) | ((x >> (32 - 11)) & (2 ** 32 - 1))
def xcrypt(seq, sbox, key, ns):
- """ Perform full-round single-block operation
+ """Perform full-round single-block operation
:param seq: sequence of K_i S-box applying (either encrypt or decrypt)
:param sbox: S-box parameters to use
def encrypt(sbox, key, ns):
- """ Encrypt single block
+ """Encrypt single block
"""
return xcrypt(SEQ_ENCRYPT, sbox, key, ns)
def decrypt(sbox, key, ns):
- """ Decrypt single block
+ """Decrypt single block
"""
return xcrypt(SEQ_DECRYPT, sbox, key, ns)
def ecb(key, data, action, sbox=DEFAULT_SBOX):
- """ ECB mode of operation
+ """ECB mode of operation
:param bytes key: encryption key
:param data: plaintext
def cbc_encrypt(key, data, iv=8 * b"\x00", pad=True, sbox=DEFAULT_SBOX, mesh=False):
- """ CBC encryption mode of operation
+ """CBC encryption mode of operation
:param bytes key: encryption key
:param bytes data: plaintext
def cbc_decrypt(key, data, pad=True, sbox=DEFAULT_SBOX, mesh=False):
- """ CBC decryption mode of operation
+ """CBC decryption mode of operation
:param bytes key: encryption key
:param bytes data: ciphertext
def cnt(key, data, iv=8 * b"\x00", sbox=DEFAULT_SBOX):
- """ Counter mode of operation
+ """Counter mode of operation
:param bytes key: encryption key
:param bytes data: plaintext
def cfb_encrypt(key, data, iv=8 * b"\x00", sbox=DEFAULT_SBOX, mesh=False):
- """ CFB encryption mode of operation
+ """CFB encryption mode of operation
:param bytes key: encryption key
:param bytes data: plaintext
def cfb_decrypt(key, data, iv=8 * b"\x00", sbox=DEFAULT_SBOX, mesh=False):
- """ CFB decryption mode of operation
+ """CFB decryption mode of operation
:param bytes key: encryption key
:param bytes data: plaintext
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-""" GOST 28147-89 MAC
+"""GOST 28147-89 MAC
"""
from copy import copy
class MAC(PEP247):
- """ GOST 28147-89 MAC mode of operation
+ """GOST 28147-89 MAC mode of operation
>>> m = MAC(key=key)
>>> m.update("some data")
return MAC(self.key, copy(self.data), self.iv, self.sbox)
def update(self, data):
- """ Append data that has to be authenticated
+ """Append data that has to be authenticated
"""
self.data += data
def digest(self):
- """ Get MAC tag of supplied data
+ """Get MAC tag of supplied data
You have to provide at least single byte of data.
If you want to produce tag length of 3 bytes, then
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-""" GOST R 34.10 public-key signature function.
+"""GOST R 34.10 public-key signature function.
This is implementation of GOST R 34.10-2001 (:rfc:`5832`), GOST R
34.10-2012 (:rfc:`7091`). The difference between 2001 and 2012 is the
class GOST3410Curve(object):
- """ GOST 34.10 validated curve
+ """GOST 34.10 validated curve
>>> curve = CURVES["id-GostR3410-2001-TestParamSet"]
>>> prv = prv_unmarshal(urandom(32))
def public_key(curve, prv):
- """ Generate public key from the private one
+ """Generate public key from the private one
:param GOST3410Curve curve: curve to use
:param long prv: private key
def sign(curve, prv, digest, rand=None):
- """ Calculate signature for provided digest
+ """Calculate signature for provided digest
:param GOST3410Curve curve: curve to use
:param long prv: private key
def verify(curve, pub, digest, signature):
- """ Verify provided digest with the signature
+ """Verify provided digest with the signature
:param GOST3410Curve curve: curve to use
:type pub: (long, long)
def kek_34102001(curve, prv, pub, ukm):
- """ Key agreement (34.10-2001, 34.11-94)
+ """Key agreement (34.10-2001, 34.11-94)
:param GOST3410Curve curve: curve to use
:param long prv: private key
def kek_34102012256(curve, prv, pub, ukm=1):
- """ Key agreement (34.10-2012, 34.11-2012 256 bit)
+ """Key agreement (34.10-2012, 34.11-2012 256 bit)
:param GOST3410Curve curve: curve to use
:param long prv: private key
def kek_34102012512(curve, prv, pub, ukm=1):
- """ Key agreement (34.10-2012, 34.11-2012 512 bit)
+ """Key agreement (34.10-2012, 34.11-2012 512 bit)
:param GOST3410Curve curve: curve to use
:param long prv: private key
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-""" GOST R 34.11-2012 (Streebog) hash function common files
+"""GOST R 34.11-2012 (Streebog) hash function common files
This is implementation of :rfc:`6986`. Most function and variable names are
taken according to specification's terminology.
def add512bit(a, b):
- """ Add two 512 integers
+ """Add two 512 integers
"""
a = bytearray(a)
b = bytearray(b)
class GOST34112012(PEP247):
- """ GOST 34.11-2012 big-endian hash
+ """GOST 34.11-2012 big-endian hash
>>> m = GOST34112012(digest_size=32)
>>> m.update("foo")
return self._digest_size
def update(self, data):
- """ Append data that has to be hashed
+ """Append data that has to be hashed
"""
self.data += data
def digest(self):
- """ Get hash of the provided data
+ """Get hash of the provided data
"""
hsh = BLOCKSIZE * (b"\x01" if self.digest_size == 32 else b"\x00")
chk = bytearray(BLOCKSIZE * b"\x00")
-""" GOST R 34.11-2012 (Streebog) 256-bit hash function
+"""GOST R 34.11-2012 (Streebog) 256-bit hash function
This is implementation of :rfc:`6986`. Most function and variable names are
taken according to specification's terminology.
-""" GOST R 34.11-2012 (Streebog) 512-bit hash function
+"""GOST R 34.11-2012 (Streebog) 512-bit hash function
This is implementation of :rfc:`6986`. Most function and variable names are
taken according to specification's terminology.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-""" GOST R 34.11-94 hash function
+"""GOST R 34.11-94 hash function
This is implementation of :rfc:`5831`. Most function and variable names are
taken according to specification's terminology.
def _chi(Y):
- """ Chi function
+ """Chi function
This is some kind of LFSR.
"""
def _step(hin, m, sbox):
- """ Step function
+ """Step function
H_out = f(H_in, m)
"""
class GOST341194(PEP247):
- """ GOST 34.11-94 big-endian hash
+ """GOST 34.11-94 big-endian hash
>>> m = GOST341194()
>>> m.update("foo")
return GOST341194(copy(self.data), self.sbox)
def update(self, data):
- """ Append data that has to be hashed
+ """Append data that has to be hashed
"""
self.data += data
def digest(self):
- """ Get hash of the provided data
+ """Get hash of the provided data
"""
_len = 0
checksum = 0
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-""" GOST R 34.13-2015: Modes of operation for block ciphers
+"""GOST R 34.13-2015: Modes of operation for block ciphers
This module currently includes only padding methods.
"""
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-""" Multilinear Galois Mode (MGM) block cipher mode.
+"""Multilinear Galois Mode (MGM) block cipher mode.
"""
from hmac import compare_digest
# coding: utf-8
-""" PBKDF2 implementation suitable for GOST R 34.11-94/34.11-2012.
+"""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.
class ECBTest(TestCase):
def test_gcl(self):
- """ Test vectors from libgcl3
+ """Test vectors from libgcl3
"""
sbox = "id-Gost28147-89-TestParamSet"
key = hexdec(b"0475f6e05038fbfad2c7c390edb3ca3d1547124291ae1e8a2f79cd9ed2bcefbd")
self.assertSequenceEqual(decrypted, plaintext)
def test_cryptopp(self):
- """ Test vectors from Crypto++ 5.6.2
+ """Test vectors from Crypto++ 5.6.2
"""
sbox = "AppliedCryptography"
data = (
self.assertSequenceEqual(ecb_encrypt(key, pt, sbox=sbox), ct)
def test_cryptomanager(self):
- """ Test vector from http://cryptomanager.com/tv.html
+ """Test vector from http://cryptomanager.com/tv.html
"""
sbox = "id-GostR3411-94-TestParamSet"
key = hexdec(b"75713134B60FEC45A607BB83AA3746AF4FF99DA6D1B53B5B1B402A1BAA030D1B")
class CFBTest(TestCase):
def test_cryptomanager(self):
- """ Test vector from http://cryptomanager.com/tv.html
+ """Test vector from http://cryptomanager.com/tv.html
"""
key = hexdec(b"75713134B60FEC45A607BB83AA3746AF4FF99DA6D1B53B5B1B402A1BAA030D1B")
sbox = "id-GostR3411-94-TestParamSet"
)
def test_steps(self):
- """ Check step-by-step operation manually
+ """Check step-by-step operation manually
"""
key = urandom(KEYSIZE)
iv = urandom(BLOCKSIZE)
self.assertSequenceEqual(step[:4], ciphertext[16:])
def test_random(self):
- """ Random data with various sizes
+ """Random data with various sizes
"""
key = urandom(KEYSIZE)
iv = urandom(BLOCKSIZE)
class CTRTest(TestCase):
def test_gcl(self):
- """ Test vectors from libgcl3
+ """Test vectors from libgcl3
"""
sbox = "id-Gost28147-89-TestParamSet"
key = hexdec(b"0475f6e05038fbfad2c7c390edb3ca3d1547124291ae1e8a2f79cd9ed2bcefbd")
self.assertSequenceEqual(decrypted, plaintext)
def test_gcl2(self):
- """ Test vectors 2 from libgcl3
+ """Test vectors 2 from libgcl3
"""
sbox = "id-Gost28147-89-TestParamSet"
key = hexdec(b"fc7ad2886f455b50d29008fa622b57d5c65b3c637202025799cadf0768519e8a")
class TestMAC(TestCase):
- """ Test vectors generated with libgcl3 library
+ """Test vectors generated with libgcl3 library
"""
k = b"This is message\xFF length\x0032 bytes"
class Test341001(TestCase):
def test_rfc(self):
- """ Test vector from :rfc:`5832`
+ """Test vector from :rfc:`5832`
"""
prv = bytes(bytearray((
0x7A, 0x92, 0x9A, 0xDE, 0x78, 0x9B, 0xB9, 0xBE,
self.assertSequenceEqual(hexenc(signature), s + r)
def test_gcl3(self):
- """ Test vector from libgcl3
+ """Test vector from libgcl3
"""
p = bytes2long(bytes(bytearray((
0x45, 0x31, 0xAC, 0xD1, 0xFE, 0x00, 0x23, 0xC7,
class TestVectorsCryptoPro(TestCase):
- """ CryptoPro S-box test vectors
+ """CryptoPro S-box test vectors
"""
def test_empty(self):
self.assertSequenceEqual(
def strxor(a, b):
- """ XOR of two strings
+ """XOR of two strings
This function will process only shortest length of both strings,
ignoring remaining one.
def bytes2long(raw):
- """ Deserialize big-endian bytes into long number
+ """Deserialize big-endian bytes into long number
:param bytes raw: binary string
:returns: deserialized long number
def long2bytes(n, size=32):
- """ Serialize long number into big-endian bytestring
+ """Serialize long number into big-endian bytestring
:param long n: long number
:returns: serialized bytestring
def modinvert(a, n):
- """ Modular multiplicative inverse
+ """Modular multiplicative inverse
:returns: inverse number. -1 if it does not exist