X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=pygost%2Fgost3410.py;h=433c8188f96144dd7457a308d1cf4c274b805376;hb=31b08d5a78505f0ae1a144e58d023d84eda2cc6e;hp=7e92e3422c29b0b5ae569257143196a945836a04;hpb=ccf38ecbf1c166c0817893afd85bcb0976e09789;p=pygost.git diff --git a/pygost/gost3410.py b/pygost/gost3410.py index 7e92e34..433c818 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)) @@ -54,13 +54,14 @@ class GOST3410Curve(object): :param long e, d: coefficients of the equation of the elliptic curve in the twisted Edwards form """ - def __init__(self, p, q, a, b, x, y, e=None, d=None): + def __init__(self, p, q, a, b, x, y, cofactor=1, e=None, d=None): self.p = p self.q = q self.a = a self.b = b self.x = x self.y = y + self.cofactor = cofactor self.e = e self.d = d r1 = self.y * self.y % self.p @@ -69,6 +70,10 @@ class GOST3410Curve(object): raise ValueError("Invalid parameters") self._st = None + @property + def point_size(self): + return point_size(self.p) + def pos(self, v): """Make positive number """ @@ -165,6 +170,7 @@ CURVES = { b=bytes2long(hexdec("295F9BAE7428ED9CCC20E7C359A9D41A22FCCD9108E17BF7BA9337A6F8AE9513")), x=bytes2long(hexdec("91E38443A5E82C0D880923425712B2BB658B9196932E02C78B2582FE742DAA28")), y=bytes2long(hexdec("32879423AB1A0375895786C4BB46E9565FDE0B5344766740AF268ADB32322E5C")), + cofactor=4, e=0x01, d=bytes2long(hexdec("0605F6B7C183FA81578BC39CFAD518132B9DF62897009AF7E522C32D6DC7BFFB")), ), @@ -199,6 +205,7 @@ CURVES = { b=bytes2long(hexdec("B4C4EE28CEBC6C2C8AC12952CF37F16AC7EFB6A9F69F4B57FFDA2E4F0DE5ADE038CBC2FFF719D2C18DE0284B8BFEF3B52B8CC7A5F5BF0A3C8D2319A5312557E1")), x=bytes2long(hexdec("E2E31EDFC23DE7BDEBE241CE593EF5DE2295B7A9CBAEF021D385F7074CEA043AA27272A7AE602BF2A7B9033DB9ED3610C6FB85487EAE97AAC5BC7928C1950148")), y=bytes2long(hexdec("F5CE40D95B5EB899ABBCCFF5911CB8577939804D6527378B8C108C3D2090FF9BE18E2D33E3021ED2EF32D85822423B6304F726AA854BAE07D0396E9A9ADDC40F")), + cofactor=4, e=0x01, d=bytes2long(hexdec("9E4F5D8C017D8D9F13A5CF3CDF5BFE4DAB402D54198E31EBDE28A0621050439CA6B39E0A515C06B304E2CE43E79E369E91A0CFC2BC2A22B4CA302DBB33EE7550")), ), @@ -212,7 +219,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 @@ -222,8 +229,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 @@ -231,10 +238,10 @@ def sign(curve, prv, digest, rand=None, mode=2001): :type digest: bytes, 32 or 64 bytes :param rand: optional predefined random data used for k/r generation :type rand: bytes, 32 or 64 bytes - :returns: signature + :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: @@ -260,8 +267,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) @@ -271,7 +278,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 @@ -305,7 +312,7 @@ def verify(curve, pub, digest, signature, mode=2001): def prv_unmarshal(prv): - """Unmarshal private key + """Unmarshal little-endian private key :param bytes prv: serialized private key :rtype: long @@ -313,23 +320,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]))