]> Cypherpunks.ru repositories - pygost.git/blob - pygost/x509.py
2.3 release is ready
[pygost.git] / pygost / x509.py
1 # coding: utf-8
2 # PyGOST -- Pure Python GOST cryptographic functions library
3 # Copyright (C) 2015-2016 Sergey Matveev <stargrave@stargrave.org>
4 #
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.
9 #
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.
14 #
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
18
19 Signature, public and private keys formats are defined in the RFC above.
20 """
21
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
33
34
35 GOST341194_SBOX = "GostR3411_94_CryptoProParamSet"
36 MODE2PARAMS = {
37     2001: "GostR3410_2001_CryptoPro_A_ParamSet",
38     2012: "GostR3410_2012_TC26_ParamSetA",
39 }
40 MODE2SIZE = {
41     2001: SIZE_3410_2001,
42     2012: SIZE_3410_2012,
43 }
44 MODE2DIGEST = {
45     2001: lambda data: GOST341194(data, sbox=GOST341194_SBOX).digest(),
46     2012: lambda data: GOST34112012(data).digest(),
47 }
48
49
50 def keypair_gen(seed, mode=2001, curve_params=None):
51     """ Generate keypair
52
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
61     """
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])
66     private_key = seed
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
70
71
72 def sign_digest(private_key, digest, mode=2001, curve_params=None):
73     """ Sign digest
74
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.
82     :return: signature
83     :rtype: bytes, 64/128 bytes
84     """
85     curve_params = curve_params or MODE2PARAMS[mode]
86     curve = GOST3410Curve(*CURVE_PARAMS[curve_params])
87     return _sign(
88         curve,
89         bytes2long(private_key[::-1]),
90         digest,
91         size=MODE2SIZE[mode],
92     )
93
94
95 def verify_digest(public_key, digest, signature, mode=2001, curve_params=None):
96     """ Verify signature of the digest
97
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.
106     :rtype: bool
107     """
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]
112     return _verify(
113         curve,
114         bytes2long(public_key[size:]),
115         bytes2long(public_key[:size]),
116         digest,
117         signature,
118         size=MODE2SIZE[mode],
119     )
120
121
122 def sign(private_key, data, mode=2001, curve_params=None):
123     """ Calculate data's digest and sign it
124
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.
132     :return: signature
133     :rtype: bytes, 64/128 bytes
134     """
135     return sign_digest(private_key, MODE2DIGEST[mode](data), mode, curve_params)
136
137
138 def verify(public_key, data, signature, mode=2001, curve_params=None):
139     """ Verify signature of the digest
140
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.
149     :rtype: bool
150     """
151     return verify_digest(
152         public_key,
153         MODE2DIGEST[mode](data),
154         signature,
155         mode,
156         curve_params,
157     )