2 # PyGOST -- Pure Python GOST cryptographic functions library
3 # Copyright (C) 2015-2016 Sergey Matveev <stargrave@stargrave.org>
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 """ :rfc:`4491` (using GOST algorithms with X.509) compatibility helpers
19 Signature, public and private keys formats are defined in the RFC above.
22 from pygost.gost3410 import CURVE_PARAMS
23 from pygost.gost3410 import GOST3410Curve
24 from pygost.gost3410 import public_key as _public_key
25 from pygost.gost3410 import sign as _sign
26 from pygost.gost3410 import SIZE_3410_2001
27 from pygost.gost3410 import SIZE_3410_2012
28 from pygost.gost3410 import verify as _verify
29 from pygost.gost3411_2012 import GOST34112012
30 from pygost.gost3411_94 import GOST341194
31 from pygost.utils import bytes2long
32 from pygost.utils import long2bytes
35 GOST341194_SBOX = "GostR3411_94_CryptoProParamSet"
37 2001: "GostR3410_2001_CryptoPro_A_ParamSet",
38 2012: "GostR3410_2012_TC26_ParamSetA",
45 2001: lambda data: GOST341194(data, sbox=GOST341194_SBOX).digest(),
46 2012: lambda data: GOST34112012(data).digest(),
50 def keypair_gen(seed, mode=2001, curve_params=None):
53 :param bytes seed: random data used as an entropy source
54 :param int mode: either 2001 or 2012
55 :param str curve_params: :py:data:`gost3410.CURVE_PARAMS` key identifying
56 curve parameters. GostR3410_2001_CryptoPro_A_ParamSet
57 will be used by default for 2001 mode and
58 GostR3410_2012_TC26_ParamSetA for 2012 one.
59 :return: private and public keys
60 :rtype: (bytes, bytes), 32/64 and 64/128 bytes
62 if len(seed) != MODE2SIZE[mode]:
63 raise ValueError("Invalid seed size")
64 curve_params = curve_params or MODE2PARAMS[mode]
65 curve = GOST3410Curve(*CURVE_PARAMS[curve_params])
67 public_key_x, public_key_y = _public_key(curve, bytes2long(private_key))
68 public_key = (long2bytes(public_key_y) + long2bytes(public_key_x))[::-1]
69 return private_key[::-1], public_key
72 def sign_digest(private_key, digest, mode=2001, curve_params=None):
75 :param bytes private_key: private key to sign with
76 :param bytes digest: precalculated digest
77 :param int mode: either 2001 or 2012
78 :param str curve_params: :py:data:`gost3410.CURVE_PARAMS` key identifying
79 curve parameters. GostR3410_2001_CryptoPro_A_ParamSet
80 will be used by default for 2001 mode and
81 GostR3410_2012_TC26_ParamSetA for 2012 one.
83 :rtype: bytes, 64/128 bytes
85 curve_params = curve_params or MODE2PARAMS[mode]
86 curve = GOST3410Curve(*CURVE_PARAMS[curve_params])
89 bytes2long(private_key[::-1]),
95 def verify_digest(public_key, digest, signature, mode=2001, curve_params=None):
96 """ Verify signature of the digest
98 :param bytes public_key: public key to verify with
99 :param bytes digest: precalculated digest
100 :param bytes signature: signature
101 :param int mode: either 2001 or 2012
102 :param str curve_params: :py:data:`gost3410.CURVE_PARAMS` key identifying
103 curve parameters. GostR3410_2001_CryptoPro_A_ParamSet
104 will be used by default for 2001 mode and
105 GostR3410_2012_TC26_ParamSetA for 2012 one.
108 curve_params = curve_params or MODE2PARAMS[mode]
109 curve = GOST3410Curve(*CURVE_PARAMS[curve_params])
110 public_key = public_key[::-1]
111 size = MODE2SIZE[mode]
114 bytes2long(public_key[size:]),
115 bytes2long(public_key[:size]),
122 def sign(private_key, data, mode=2001, curve_params=None):
123 """ Calculate data's digest and sign it
125 :param bytes private_key: private key to sign with
126 :param bytes data: arbitrary data
127 :param int mode: either 2001 or 2012
128 :param str curve_params: :py:data:`gost3410.CURVE_PARAMS` key identifying
129 curve parameters. GostR3410_2001_CryptoPro_A_ParamSet
130 will be used by default for 2001 mode and
131 GostR3410_2012_TC26_ParamSetA for 2012 one.
133 :rtype: bytes, 64/128 bytes
135 return sign_digest(private_key, MODE2DIGEST[mode](data), mode, curve_params)
138 def verify(public_key, data, signature, mode=2001, curve_params=None):
139 """ Verify signature of the digest
141 :param bytes public_key: public key to verify with
142 :param bytes digest: precalculated digest
143 :param bytes signature: signature
144 :param int mode: either 2001 or 2012
145 :param str curve_params: :py:data:`gost3410.CURVE_PARAMS` key identifying
146 curve parameters. GostR3410_2001_CryptoPro_A_ParamSet
147 will be used by default for 2001 mode and
148 GostR3410_2012_TC26_ParamSetA for 2012 one.
151 return verify_digest(
153 MODE2DIGEST[mode](data),