]> Cypherpunks.ru repositories - pygost.git/blobdiff - pygost/gost3410.py
Locally-named variables
[pygost.git] / pygost / gost3410.py
index a2cc7cef015507d4db84955cd4a9b9ea392adf29..a3e2f7ad8c316458ee8916398842c6dde1af1f07 100644 (file)
@@ -1,6 +1,6 @@
 # coding: utf-8
 # PyGOST -- Pure Python GOST cryptographic functions library
-# Copyright (C) 2015-2020 Sergey Matveev <stargrave@stargrave.org>
+# Copyright (C) 2015-2021 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
@@ -53,8 +53,9 @@ class GOST3410Curve(object):
                       the canonical form
     :param long e, d: coefficients of the equation of the elliptic curve in
                       the twisted Edwards form
+    :param str name: human-readable curve name
     """
-    def __init__(self, p, q, a, b, x, y, cofactor=1, e=None, d=None):
+    def __init__(self, p, q, a, b, x, y, cofactor=1, e=None, d=None, name=None):
         self.p = p
         self.q = q
         self.a = a
@@ -67,11 +68,15 @@ class GOST3410Curve(object):
         if not self.contains((x, y)):
             raise ValueError("Invalid parameters")
         self._st = None
+        self.name = name
 
     @property
     def point_size(self):
         return point_size(self.p)
 
+    def __repr__(self):
+        return "<%s: %s>" % (self.__class__.__name__, self.name)
+
     def pos(self, v):
         """Make positive number
         """
@@ -120,7 +125,7 @@ class GOST3410Curve(object):
         """Compute s/t parameters for twisted Edwards curve points conversion
         """
         if self.e is None or self.d is None:
-            raise ValueError("non twisted Edwards curve")
+            raise ValueError("Non twisted Edwards curve")
         if self._st is not None:
             return self._st
         self._st = (
@@ -147,7 +152,18 @@ CURVES = {
         x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000002")),
         y=bytes2long(hexdec("08E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8")),
     ),
-    "id-GostR3410-2001-CryptoPro-A-ParamSet": GOST3410Curve(
+    "id-tc26-gost-3410-12-256-paramSetA": GOST3410Curve(
+        p=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97")),
+        q=bytes2long(hexdec("400000000000000000000000000000000FD8CDDFC87B6635C115AF556C360C67")),
+        a=bytes2long(hexdec("C2173F1513981673AF4892C23035A27CE25E2013BF95AA33B22C656F277E7335")),
+        b=bytes2long(hexdec("295F9BAE7428ED9CCC20E7C359A9D41A22FCCD9108E17BF7BA9337A6F8AE9513")),
+        x=bytes2long(hexdec("91E38443A5E82C0D880923425712B2BB658B9196932E02C78B2582FE742DAA28")),
+        y=bytes2long(hexdec("32879423AB1A0375895786C4BB46E9565FDE0B5344766740AF268ADB32322E5C")),
+        cofactor=4,
+        e=0x01,
+        d=bytes2long(hexdec("0605F6B7C183FA81578BC39CFAD518132B9DF62897009AF7E522C32D6DC7BFFB")),
+    ),
+    "id-tc26-gost-3410-12-256-paramSetB": GOST3410Curve(
         p=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97")),
         q=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893")),
         a=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94")),
@@ -155,7 +171,7 @@ CURVES = {
         x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000001")),
         y=bytes2long(hexdec("8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14")),
     ),
-    "id-GostR3410-2001-CryptoPro-B-ParamSet": GOST3410Curve(
+    "id-tc26-gost-3410-12-256-paramSetC": GOST3410Curve(
         p=bytes2long(hexdec("8000000000000000000000000000000000000000000000000000000000000C99")),
         q=bytes2long(hexdec("800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F")),
         a=bytes2long(hexdec("8000000000000000000000000000000000000000000000000000000000000C96")),
@@ -163,7 +179,7 @@ CURVES = {
         x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000001")),
         y=bytes2long(hexdec("3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC")),
     ),
-    "id-GostR3410-2001-CryptoPro-C-ParamSet": GOST3410Curve(
+    "id-tc26-gost-3410-12-256-paramSetD": GOST3410Curve(
         p=bytes2long(hexdec("9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B")),
         q=bytes2long(hexdec("9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9")),
         a=bytes2long(hexdec("9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598")),
@@ -171,18 +187,7 @@ CURVES = {
         x=bytes2long(hexdec("0000000000000000000000000000000000000000000000000000000000000000")),
         y=bytes2long(hexdec("41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67")),
     ),
-    "id-tc26-gost-3410-2012-256-paramSetA": GOST3410Curve(
-        p=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97")),
-        q=bytes2long(hexdec("400000000000000000000000000000000FD8CDDFC87B6635C115AF556C360C67")),
-        a=bytes2long(hexdec("C2173F1513981673AF4892C23035A27CE25E2013BF95AA33B22C656F277E7335")),
-        b=bytes2long(hexdec("295F9BAE7428ED9CCC20E7C359A9D41A22FCCD9108E17BF7BA9337A6F8AE9513")),
-        x=bytes2long(hexdec("91E38443A5E82C0D880923425712B2BB658B9196932E02C78B2582FE742DAA28")),
-        y=bytes2long(hexdec("32879423AB1A0375895786C4BB46E9565FDE0B5344766740AF268ADB32322E5C")),
-        cofactor=4,
-        e=0x01,
-        d=bytes2long(hexdec("0605F6B7C183FA81578BC39CFAD518132B9DF62897009AF7E522C32D6DC7BFFB")),
-    ),
-    "id-tc26-gost-3410-2012-512-paramSetTest": GOST3410Curve(
+    "id-tc26-gost-3410-12-512-paramSetTest": GOST3410Curve(
         p=bytes2long(hexdec("4531ACD1FE0023C7550D267B6B2FEE80922B14B2FFB90F04D4EB7C09B5D2D15DF1D852741AF4704A0458047E80E4546D35B8336FAC224DD81664BBF528BE6373")),
         q=bytes2long(hexdec("4531ACD1FE0023C7550D267B6B2FEE80922B14B2FFB90F04D4EB7C09B5D2D15DA82F2D7ECB1DBAC719905C5EECC423F1D86E25EDBE23C595D644AAF187E6E6DF")),
         a=7,
@@ -206,7 +211,7 @@ CURVES = {
         x=bytes2long(hexdec("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002")),
         y=bytes2long(hexdec("1A8F7EDA389B094C2C071E3647A8940F3C123B697578C213BE6DD9E6C8EC7335DCB228FD1EDF4A39152CBCAAF8C0398828041055F94CEEEC7E21340780FE41BD")),
     ),
-    "id-tc26-gost-3410-2012-512-paramSetC": GOST3410Curve(
+    "id-tc26-gost-3410-12-512-paramSetC": GOST3410Curve(
         p=bytes2long(hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7")),
         q=bytes2long(hexdec("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC98CDBA46506AB004C33A9FF5147502CC8EDA9E7A769A12694623CEF47F023ED")),
         a=bytes2long(hexdec("DC9203E514A721875485A529D2C722FB187BC8980EB866644DE41C68E143064546E861C0E2C9EDD92ADE71F46FCF50FF2AD97F951FDA9F2A2EB6546F39689BD3")),
@@ -218,12 +223,22 @@ CURVES = {
         d=bytes2long(hexdec("9E4F5D8C017D8D9F13A5CF3CDF5BFE4DAB402D54198E31EBDE28A0621050439CA6B39E0A515C06B304E2CE43E79E369E91A0CFC2BC2A22B4CA302DBB33EE7550")),
     ),
 }
+CURVES["id-GostR3410-2001-CryptoPro-A-ParamSet"] = CURVES["id-tc26-gost-3410-12-256-paramSetB"]
+CURVES["id-GostR3410-2001-CryptoPro-B-ParamSet"] = CURVES["id-tc26-gost-3410-12-256-paramSetC"]
+CURVES["id-GostR3410-2001-CryptoPro-C-ParamSet"] = CURVES["id-tc26-gost-3410-12-256-paramSetD"]
 CURVES["id-GostR3410-2001-CryptoPro-XchA-ParamSet"] = CURVES["id-GostR3410-2001-CryptoPro-A-ParamSet"]
 CURVES["id-GostR3410-2001-CryptoPro-XchB-ParamSet"] = CURVES["id-GostR3410-2001-CryptoPro-C-ParamSet"]
-CURVES["id-tc26-gost-3410-2012-256-paramSetB"] = CURVES["id-GostR3410-2001-CryptoPro-A-ParamSet"]
-CURVES["id-tc26-gost-3410-2012-256-paramSetC"] = CURVES["id-GostR3410-2001-CryptoPro-B-ParamSet"]
-CURVES["id-tc26-gost-3410-2012-256-paramSetD"] = CURVES["id-GostR3410-2001-CryptoPro-C-ParamSet"]
-DEFAULT_CURVE = CURVES["id-GostR3410-2001-CryptoPro-A-ParamSet"]
+CURVES["id-tc26-gost-3410-2012-256-paramSetA"] = CURVES["id-tc26-gost-3410-12-256-paramSetA"]
+CURVES["id-tc26-gost-3410-2012-256-paramSetB"] = CURVES["id-tc26-gost-3410-12-256-paramSetB"]
+CURVES["id-tc26-gost-3410-2012-256-paramSetC"] = CURVES["id-tc26-gost-3410-12-256-paramSetC"]
+CURVES["id-tc26-gost-3410-2012-256-paramSetD"] = CURVES["id-tc26-gost-3410-12-256-paramSetD"]
+CURVES["id-tc26-gost-3410-2012-512-paramSetTest"] = CURVES["id-tc26-gost-3410-12-512-paramSetTest"]
+CURVES["id-tc26-gost-3410-2012-512-paramSetA"] = CURVES["id-tc26-gost-3410-12-512-paramSetA"]
+CURVES["id-tc26-gost-3410-2012-512-paramSetB"] = CURVES["id-tc26-gost-3410-12-512-paramSetB"]
+CURVES["id-tc26-gost-3410-2012-512-paramSetC"] = CURVES["id-tc26-gost-3410-12-512-paramSetC"]
+for _name, _curve in CURVES.items():
+    _curve.name = _name
+DEFAULT_CURVE = CURVES["id-tc26-gost-3410-12-256-paramSetB"]
 
 
 def public_key(curve, prv):
@@ -324,10 +339,26 @@ def prv_unmarshal(prv):
 
     :param bytes prv: serialized private key
     :rtype: long
+
+    It is advisable to use :py:func:`pygost.gost3410.prv_marshal` to
+    assure that key i in curve's Q field for better compatibility with
+    some implementations.
     """
     return bytes2long(prv[::-1])
 
 
+def prv_marshal(curve, prv):
+    """Marshal little-endian private key
+
+    :param GOST3410Curve curve: curve to use
+    :param long prv: serialized private key
+    :rtype: bytes
+
+    Key is in curve's Q field.
+    """
+    return long2bytes(prv % curve.q, point_size(prv))[::-1]
+
+
 def pub_marshal(pub):
     """Marshal public key