]> Cypherpunks.ru repositories - pygost.git/commitdiff
gost3410 private key % Q 5.4
authorSergey Matveev <stargrave@stargrave.org>
Tue, 26 Jan 2021 11:45:36 +0000 (14:45 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Tue, 26 Jan 2021 12:18:12 +0000 (15:18 +0300)
README
news.texi
pygost/__init__.py
pygost/gost3410.py
pygost/stubs/pygost/gost3410.pyi
pygost/test_gost3410.py

diff --git a/README b/README
index 57952337541331fe16a74cd8933560a2bf44a0d2..acabfb1572879e64937635a3a0d4326b97662c71 100644 (file)
--- a/README
+++ b/README
@@ -39,7 +39,9 @@ Example 34.10-2012 keypair generation, signing and verifying:
     >>> from os import urandom
     >>> prv_raw = urandom(64)
     >>> from pygost.gost3410 import prv_unmarshal
+    >>> from pygost.gost3410 import prv_marshal
     >>> prv = prv_unmarshal(prv_raw)
+    >>> prv_raw = prv_marshal(curve, prv)
     >>> from pygost.gost3410 import public_key
     >>> pub = public_key(curve, prv)
     >>> from pygost.gost3410 import pub_marshal
index 564df7b992ec618b01873e2bedc45ba508d9392f..324c05c2a2bf1201e9b040f6bb271e726f9736ed 100644 (file)
--- a/news.texi
+++ b/news.texi
@@ -3,6 +3,11 @@
 
 @table @strong
 
+@anchor{Release 5.4}
+@item 5.4
+@item @code{gost3410.prv_marshal} helper can make private keys that are
+in curve's Q field, for better compatibility with some implementations.
+
 @anchor{Release 5.3}
 @item 5.3
     @itemize
index f1f6ad6ab52d6df21d7d8448a318e1a3f3aee633..21fbf59e593e3a5945dce9860ce47ea89c4b6852 100644 (file)
@@ -3,4 +3,4 @@
 PyGOST is free software: see the file COPYING for copying conditions.
 """
 
-__version__ = "5.3"
+__version__ = "5.4"
index 88cbfbe3493742e003cc6d9149c93739909207db..58a20e0fe7c6a06020dc90c34e80c76ca78b0150 100644 (file)
@@ -324,10 +324,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
 
index 4be9bbbadbd77ccbd02e7381fa03e9a94e6cd999..345a3e69f1d401c375796f60e4f4e34ae12f38c0 100644 (file)
@@ -55,6 +55,9 @@ def verify(curve: GOST3410Curve, pub: PublicKey, digest: bytes, signature: bytes
 def prv_unmarshal(prv: bytes) -> int: ...
 
 
+def prv_marshal(curve: GOST3410Curve, prv: int) -> bytes: ...
+
+
 def pub_marshal(pub: PublicKey) -> bytes: ...
 
 
index 51624dbd8d17144ffd32ccb5ef6e4b6b9e1131ed..677968d803c0fd7018eb5a88babbd9e81a5f1af1 100644 (file)
@@ -19,6 +19,8 @@ from unittest import TestCase
 
 from pygost.gost3410 import CURVES
 from pygost.gost3410 import GOST3410Curve
+from pygost.gost3410 import prv_marshal
+from pygost.gost3410 import prv_unmarshal
 from pygost.gost3410 import public_key
 from pygost.gost3410 import sign
 from pygost.gost3410 import uv2xy
@@ -81,8 +83,8 @@ class Test341001(TestCase):
 
     def test_sequence(self):
         c = CURVES["id-GostR3410-2001-TestParamSet"]
-        prv = bytes2long(urandom(32))
-        pubX, pubY = public_key(c, prv)
+        prv = prv_unmarshal(urandom(32))
+        pubX, pubY = public_key(c, prv_unmarshal(prv_marshal(c, prv)))
         for _ in range(20):
             digest = urandom(32)
             s = sign(c, prv, digest)
@@ -255,7 +257,7 @@ class Test34102012(TestCase):
     def test_sequence(self):
         c = CURVES["id-tc26-gost-3410-12-512-paramSetA"]
         prv = bytes2long(urandom(64))
-        pubX, pubY = public_key(c, prv)
+        pubX, pubY = public_key(c, prv_unmarshal(prv_marshal(c, prv)))
         for _ in range(20):
             digest = urandom(64)
             s = sign(c, prv, digest)