news.texi | 4 ++++ pygost/__init__.py | 2 +- pygost/gost3410.py | 18 +++++++++++++----- pygost/gost3410_vko.py | 4 +++- diff --git a/news.texi b/news.texi index 110503cd5e1bbc517f983e6fda843ea389281fe8d4da757bbbe825a552ac1a73..9abd0b3f955321f950a922f9e6680f043b90059d5ee9c3d6dd110682be7021a3 100644 --- a/news.texi +++ b/news.texi @@ -3,6 +3,10 @@ @unnumbered News @table @strong +@anchor{Release 5.13} +@item 5.13 +Ability to use masked 34.10 private keys. + @anchor{Release 5.12} @item 5.12 Fixed incorrect digest calculation when using @code{GOST34112012*.update()} diff --git a/pygost/__init__.py b/pygost/__init__.py index 032adc8b2e2c305420fd59ba7828193e9f85561ac7ebde32c5e3e982cf7f749d..7b1183a6e6474f958ba3f550f8888e83508581e37d98850e1fa99665ab09221d 100644 --- a/pygost/__init__.py +++ b/pygost/__init__.py @@ -3,4 +3,4 @@ PyGOST is free software: see the file COPYING for copying conditions. """ -__version__ = "5.12" +__version__ = "5.13" diff --git a/pygost/gost3410.py b/pygost/gost3410.py index c3c63a0f48e0c231bed9c768a85df14e5bcb9112f2ae3f53f45d1a9a50f93a2f..4128eb31b792b6393c623978535ebd7a7386bd2ef998b4aec266605a91e7df1f 100644 --- a/pygost/gost3410.py +++ b/pygost/gost3410.py @@ -242,7 +242,7 @@ _curve.name = _name DEFAULT_CURVE = CURVES["id-tc26-gost-3410-12-256-paramSetB"] -def public_key(curve, prv): +def public_key(curve, prv, mask=None): """Generate public key from the private one :param GOST3410Curve curve: curve to use @@ -250,10 +250,13 @@ :param long prv: private key :returns: public key's parts, X and Y :rtype: (long, long) """ - return curve.exp(prv) + pub = curve.exp(prv) + if mask is not None: + pub = curve.exp(mask, pub[0], pub[1]) + return pub -def sign(curve, prv, digest, rand=None): +def sign(curve, prv, digest, rand=None, mask=None): """Calculate signature for provided digest :param GOST3410Curve curve: curve to use @@ -278,13 +281,18 @@ raise ValueError("rand length != %d" % size) k = bytes2long(rand) % q if k == 0: continue - r, _ = curve.exp(k) + r, y = curve.exp(k) + if mask is not None: + r, y = curve.exp(mask, x=r, y=y) r %= q if r == 0: continue d = prv * r k *= e - s = (d + k) % q + s = d + k + if mask is not None: + s *= mask + s %= q if s == 0: continue break diff --git a/pygost/gost3410_vko.py b/pygost/gost3410_vko.py index a44199b5bed0c8c268d6c21396974239f6a1be85b4fba3cd4115c67652068582..f820aee5a3f4be55c6677667c3b6af00414728e98f1e71d07dd6c0bf32365381 100644 --- a/pygost/gost3410_vko.py +++ b/pygost/gost3410_vko.py @@ -32,11 +32,13 @@ """ return bytes2long(ukm[::-1]) -def kek(curve, prv, pub, ukm): +def kek(curve, prv, pub, ukm, mask=None): if not curve.contains(pub): raise ValueError("pub is not on the curve") key = curve.exp(prv, pub[0], pub[1]) key = curve.exp(curve.cofactor * ukm, key[0], key[1]) + if mask is not None: + key = curve.exp(mask, key[0], key[1]) return pub_marshal(key)