X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=pygost%2Fgost3410.py;h=a2cc7cef015507d4db84955cd4a9b9ea392adf29;hb=f3a3246bc9da027e0527b89204e1b95ed52af5c6;hp=9f0a11e656689745056b8f7c53cdf5c3779201b3;hpb=2bb1a163d32e4167e6904ff3c6b4cf64ea7287bb;p=pygost.git diff --git a/pygost/gost3410.py b/pygost/gost3410.py index 9f0a11e..a2cc7ce 100644 --- a/pygost/gost3410.py +++ b/pygost/gost3410.py @@ -13,7 +13,7 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -""" GOST R 34.10 public-key signature function. +"""GOST R 34.10 public-key signature function. This is implementation of GOST R 34.10-2001 (:rfc:`5832`), GOST R 34.10-2012 (:rfc:`7091`). The difference between 2001 and 2012 is the @@ -28,14 +28,14 @@ from pygost.utils import long2bytes from pygost.utils import modinvert -MODE2SIZE = { - 2001: 32, - 2012: 64, -} +def point_size(point): + """Determine is it either 256 or 512 bit point + """ + return (512 // 8) if point.bit_length() > 256 else (256 // 8) class GOST3410Curve(object): - """ GOST 34.10 validated curve + """GOST 34.10 validated curve >>> curve = CURVES["id-GostR3410-2001-TestParamSet"] >>> prv = prv_unmarshal(urandom(32)) @@ -64,12 +64,14 @@ class GOST3410Curve(object): self.cofactor = cofactor self.e = e self.d = d - r1 = self.y * self.y % self.p - r2 = ((self.x * self.x + self.a) * self.x + self.b) % self.p - if r1 != self.pos(r2): + if not self.contains((x, y)): raise ValueError("Invalid parameters") self._st = None + @property + def point_size(self): + return point_size(self.p) + def pos(self, v): """Make positive number """ @@ -77,6 +79,16 @@ class GOST3410Curve(object): return v + self.p return v + def contains(self, point): + """Is point on the curve? + + :type point: (long, long) + """ + x, y = point + r1 = y * y % self.p + r2 = ((x * x + self.a) * x + self.b) % self.p + return r1 == self.pos(r2) + def _add(self, p1x, p1y, p2x, p2y): if p1x == p2x and p1y == p2y: # double @@ -215,7 +227,7 @@ DEFAULT_CURVE = CURVES["id-GostR3410-2001-CryptoPro-A-ParamSet"] def public_key(curve, prv): - """ Generate public key from the private one + """Generate public key from the private one :param GOST3410Curve curve: curve to use :param long prv: private key @@ -225,8 +237,8 @@ def public_key(curve, prv): return curve.exp(prv) -def sign(curve, prv, digest, rand=None, mode=2001): - """ Calculate signature for provided digest +def sign(curve, prv, digest, rand=None): + """Calculate signature for provided digest :param GOST3410Curve curve: curve to use :param long prv: private key @@ -237,7 +249,7 @@ def sign(curve, prv, digest, rand=None, mode=2001): :returns: signature, BE(S) || BE(R) :rtype: bytes, 64 or 128 bytes """ - size = MODE2SIZE[mode] + size = curve.point_size q = curve.q e = bytes2long(digest) % q if e == 0: @@ -263,8 +275,8 @@ def sign(curve, prv, digest, rand=None, mode=2001): return long2bytes(s, size) + long2bytes(r, size) -def verify(curve, pub, digest, signature, mode=2001): - """ Verify provided digest with the signature +def verify(curve, pub, digest, signature): + """Verify provided digest with the signature :param GOST3410Curve curve: curve to use :type pub: (long, long) @@ -274,7 +286,7 @@ def verify(curve, pub, digest, signature, mode=2001): :type signature: bytes, 64 or 128 bytes :rtype: bool """ - size = MODE2SIZE[mode] + size = curve.point_size if len(signature) != size * 2: raise ValueError("Invalid signature length") q = curve.q @@ -316,25 +328,25 @@ def prv_unmarshal(prv): return bytes2long(prv[::-1]) -def pub_marshal(pub, mode=2001): +def pub_marshal(pub): """Marshal public key :type pub: (long, long) :rtype: bytes :returns: LE(X) || LE(Y) """ - size = MODE2SIZE[mode] + size = point_size(pub[0]) return (long2bytes(pub[1], size) + long2bytes(pub[0], size))[::-1] -def pub_unmarshal(pub, mode=2001): +def pub_unmarshal(pub): """Unmarshal public key :param pub: LE(X) || LE(Y) :type pub: bytes :rtype: (long, long) """ - size = MODE2SIZE[mode] + size = len(pub) // 2 pub = pub[::-1] return (bytes2long(pub[size:]), bytes2long(pub[:size]))