doc/NEWS | 4 ++++ pygost/__init__.py | 2 +- pygost/sespake.py | 61 ++++++++++++++++------------------------------------- pygost/test_sespake.py | 45 +++++++++++++-------------------------------- diff --git a/doc/NEWS b/doc/NEWS index 0b784211323a2a83aacf4aaa6b841c4478493464afaad47e27d1a9ad3379572c..38fc98d59ce6db352421740eb30b69da67a34083d2b81016a590f69c088afc61 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -1,3 +1,7 @@ +A 6.1 +6.1 + * Simplified SESPAKE's API (no non-encoded points) + A 6.0 6.0 * Removed Python2 compatibility. diff --git a/pygost/__init__.py b/pygost/__init__.py index 871bf6b5c10e859d8408e3c9581e30c28d78d3f68c4fda409dd3276f8d83be5f..ab81568953604f707db73c8de206d4382aa80bd4923e319ddf021127122851a6 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__ = "6.0" +__version__ = "6.1" diff --git a/pygost/sespake.py b/pygost/sespake.py index 29ca49c2e780e20d41ed9b849baafe351553b7ed7f3cb361e018a941fba91fe6..242066e47599f5681cb996b665da076678bcecf53c3ae0ae252ff4379a2e5bf5 100644 --- a/pygost/sespake.py +++ b/pygost/sespake.py @@ -27,6 +27,8 @@ from pygost import gost34112012256 from pygost import gost34112012512 from pygost.gost3410 import GOST3410Curve from pygost.gost3410 import Point +from pygost.gost3410 import pub_marshal +from pygost.gost3410 import pub_unmarshal from pygost.pbkdf2 import pbkdf2 Qs = { @@ -95,47 +97,29 @@ int.from_bytes(urandom(self.curve.point_size), "big") % self.curve.q ) if alpha is None else alpha alphaP = self.curve.exp(self.alpha) tmp = self.curve.exp(self.curve.q-1, self.qpw[0], self.qpw[1]) - self.u1 = self.curve._add(alphaP[0], alphaP[1], tmp[0], tmp[1]) + self.u1 = pub_marshal(self.curve._add(alphaP[0], alphaP[1], tmp[0], tmp[1])) def ka(self, u2: Point, dataA=b""): + self.u2 = u2 + u2 = pub_unmarshal(u2) if not self.curve.contains(u2): raise ValueError("u2 is not on curve") - self.u2 = u2 self.dataA = dataA tmp = self.curve.exp(self.curve.q-1, self.qpw[0], self.qpw[1]) - qA = self.curve._add(self.u2[0], self.u2[1], tmp[0], tmp[1]) + qA = self.curve._add(u2[0], u2[1], tmp[0], tmp[1]) # TODO: check zero point tmp = self.curve.exp( (self.curve.cofactor * self.alpha) % self.curve.q, qA[0], qA[1]) - self.k = gost34112012256.new( - tmp[0].to_bytes(self.curve.point_size, "little") + - tmp[1].to_bytes(self.curve.point_size, "little") - ).digest() - u1 = ( - self.u1[0].to_bytes(self.curve.point_size, "little") + - self.u1[1].to_bytes(self.curve.point_size, "little") - ) - u2 = ( - self.u2[0].to_bytes(self.curve.point_size, "little") + - self.u2[1].to_bytes(self.curve.point_size, "little") - ) + self.k = gost34112012256.new(pub_marshal(tmp)).digest() macA = hmac.new(key=self.k, msg=b"".join(( - b"\x01", self.idA, self.ind, self.salt, u1, u2, self.idAlg, + b"\x01", self.idA, self.ind, self.salt, self.u1, self.u2, self.idAlg, self.dataA, )), digestmod=gost34112012256).digest() return macA def kc(self, macB: bytes, dataB=b""): - u1 = ( - self.u1[0].to_bytes(self.curve.point_size, "little") + - self.u1[1].to_bytes(self.curve.point_size, "little") - ) - u2 = ( - self.u2[0].to_bytes(self.curve.point_size, "little") + - self.u2[1].to_bytes(self.curve.point_size, "little") - ) _macB = hmac.new(key=self.k, msg=b"".join(( - b"\x02", self.idB, self.ind, self.salt, u1, u2, self.idAlg, + b"\x02", self.idB, self.ind, self.salt, self.u1, self.u2, self.idAlg, self.dataA, dataB, )), digestmod=gost34112012256).digest() if not hmac.compare_digest(_macB, macB): @@ -172,41 +156,32 @@ self.fpw = fpw self.qpw = self.curve.exp( int.from_bytes(fpw[:self.curve.point_size], "little"), q[0], q[1]) - def ka(self, u1: Point, beta=None): + def ka(self, u1: bytes, beta=None): + self.u1 = u1 + u1 = pub_unmarshal(u1) if not self.curve.contains(u1): raise ValueError("u1 is not on curve") - self.u1 = u1 - qB = self.curve._add(self.u1[0], self.u1[1], self.qpw[0], self.qpw[1]) + qB = self.curve._add(u1[0], u1[1], self.qpw[0], self.qpw[1]) # TODO: check zero point if beta is None: beta = int.from_bytes(urandom(self.curve.point_size), "big") % self.curve.q tmp = self.curve.exp((self.curve.cofactor * beta) % self.curve.q, qB[0], qB[1]) - self.k = gost34112012256.new( - tmp[0].to_bytes(self.curve.point_size, "little") + - tmp[1].to_bytes(self.curve.point_size, "little") - ).digest() + self.k = gost34112012256.new(pub_marshal(tmp)).digest() betaP = self.curve.exp(beta) - self.u2 = self.curve._add(betaP[0], betaP[1], self.qpw[0], self.qpw[1]) + self.u2 = pub_marshal(self.curve._add( + betaP[0], betaP[1], self.qpw[0], self.qpw[1])) return self.u2 def kc(self, macA: bytes, dataA=b"", dataB=b""): - u1 = ( - self.u1[0].to_bytes(self.curve.point_size, "little") + - self.u1[1].to_bytes(self.curve.point_size, "little") - ) - u2 = ( - self.u2[0].to_bytes(self.curve.point_size, "little") + - self.u2[1].to_bytes(self.curve.point_size, "little") - ) _macA = hmac.new(key=self.k, msg=b"".join(( - b"\x01", self.idA, self.ind, self.salt, u1, u2, self.idAlg, + b"\x01", self.idA, self.ind, self.salt, self.u1, self.u2, self.idAlg, dataA, )), digestmod=gost34112012256).digest() if not hmac.compare_digest(_macA, macA): raise ValueError("wrong macA") self.dataA = dataA macB = hmac.new(key=self.k, msg=b"".join(( - b"\x02", self.idB, self.ind, self.salt, u1, u2, self.idAlg, + b"\x02", self.idB, self.ind, self.salt, self.u1, self.u2, self.idAlg, self.dataA, dataB, )), digestmod=gost34112012256).digest() return macB diff --git a/pygost/test_sespake.py b/pygost/test_sespake.py index 3d4af2ab860715f4a86d44fa07feb6b1d1b1846d47870d1f10d1ba1bdaf81d71..417ee93921fd2a84908b502125e0d0262f018e68a8196fa14c2868bb250c0c40 100644 --- a/pygost/test_sespake.py +++ b/pygost/test_sespake.py @@ -23,6 +23,7 @@ from pygost import gost34112012256 from pygost import gost34112012512 from pygost import sespake from pygost.gost3410 import CURVES +from pygost.gost3410 import pub_marshal from pygost.pbkdf2 import pbkdf2 @@ -317,53 +318,38 @@ ): curve = CURVES[curveName] q = sespake.Qs[curveName] qpw = curve.exp(int.from_bytes(self.fpw[:curve.point_size], "little"), q[0], q[1]) - self.assertSequenceEqual(qpw[0].to_bytes(curve.point_size, "big").hex(), qpwExpected[0]) - self.assertSequenceEqual(qpw[1].to_bytes(curve.point_size, "big").hex(), qpwExpected[1]) + self.assertSequenceEqual(pub_marshal(qpw)[::-1].hex(), qpwExpected[1] + qpwExpected[0]) alphaP = curve.exp(alpha) - self.assertSequenceEqual(alphaP[0].to_bytes(curve.point_size, "big").hex(), alphaPExpected[0]) - self.assertSequenceEqual(alphaP[1].to_bytes(curve.point_size, "big").hex(), alphaPExpected[1]) + self.assertSequenceEqual(pub_marshal(alphaP)[::-1].hex(), alphaPExpected[1] + alphaPExpected[0]) tmp = curve.exp(curve.q-1, qpw[0], qpw[1]) u1 = curve._add(alphaP[0], alphaP[1], tmp[0], tmp[1]) - self.assertSequenceEqual(u1[0].to_bytes(curve.point_size, "big").hex(), u1Expected[0]) - self.assertSequenceEqual(u1[1].to_bytes(curve.point_size, "big").hex(), u1Expected[1]) + self.assertSequenceEqual(pub_marshal(u1)[::-1].hex(), u1Expected[1] + u1Expected[0]) self.assertTrue(curve.contains(u1)) qB = curve._add(u1[0], u1[1], qpw[0], qpw[1]) self.assertEqual(qB, alphaP) tmp = curve.exp((curve.cofactor * beta) % curve.q, qB[0], qB[1]) - self.assertSequenceEqual(tmp[0].to_bytes(curve.point_size, "little").hex(), kBSrcExpected[0]) - self.assertSequenceEqual(tmp[1].to_bytes(curve.point_size, "little").hex(), kBSrcExpected[1]) - kB = gost34112012256.new( - tmp[0].to_bytes(curve.point_size, "little") + - tmp[1].to_bytes(curve.point_size, "little") - ).digest() + self.assertSequenceEqual(pub_marshal(tmp).hex(), kBSrcExpected[0] + kBSrcExpected[1]) + kB = gost34112012256.new(pub_marshal(tmp)).digest() self.assertSequenceEqual(kB.hex(), kBExpected) betaP = curve.exp(beta) - self.assertSequenceEqual(betaP[0].to_bytes(curve.point_size, "big").hex(), betaPExpected[0]) - self.assertSequenceEqual(betaP[1].to_bytes(curve.point_size, "big").hex(), betaPExpected[1]) + self.assertSequenceEqual(pub_marshal(betaP)[::-1].hex(), betaPExpected[1]+ betaPExpected[0]) u2 = curve._add(betaP[0], betaP[1], qpw[0], qpw[1]) - self.assertSequenceEqual(u2[0].to_bytes(curve.point_size, "big").hex(), u2Expected[0]) - self.assertSequenceEqual(u2[1].to_bytes(curve.point_size, "big").hex(), u2Expected[1]) + self.assertSequenceEqual(pub_marshal(u2)[::-1].hex(), u2Expected[1] + u2Expected[0]) self.assertTrue(curve.contains(u2)) tmp = curve.exp(curve.q-1, qpw[0], qpw[1]) qA = curve._add(u2[0], u2[1], tmp[0], tmp[1]) tmp = curve.exp((curve.cofactor * alpha) % curve.q, qA[0], qA[1]) - kA = gost34112012256.new( - tmp[0].to_bytes(curve.point_size, "little") + - tmp[1].to_bytes(curve.point_size, "little") - ).digest() + kA = gost34112012256.new(pub_marshal(tmp)).digest() self.assertEqual(kA, kB) macA = hmac.new( key=kA, msg=b"".join(( b"\x01", self.idA, b"\x01", self.salt, - u1[0].to_bytes(curve.point_size, "little"), - u1[1].to_bytes(curve.point_size, "little"), - u2[0].to_bytes(curve.point_size, "little"), - u2[1].to_bytes(curve.point_size, "little"), + pub_marshal(u1), pub_marshal(u2), )), digestmod=gost34112012256, ).digest() @@ -373,10 +359,7 @@ macB = hmac.new( key=kB, msg=b"".join(( b"\x02", self.idB, b"\x01", self.salt, - u1[0].to_bytes(curve.point_size, "little"), - u1[1].to_bytes(curve.point_size, "little"), - u2[0].to_bytes(curve.point_size, "little"), - u2[1].to_bytes(curve.point_size, "little"), + pub_marshal(u1), pub_marshal(u2), )), digestmod=gost34112012256, ).digest() @@ -415,8 +398,7 @@ self.idB, fpw=self.fpw, alpha=alpha, ) - self.assertSequenceEqual(a.u1[0].to_bytes(curve.point_size, "big").hex(), u1Expected[0]) - self.assertSequenceEqual(a.u1[1].to_bytes(curve.point_size, "big").hex(), u1Expected[1]) + self.assertSequenceEqual(a.u1[::-1].hex(), u1Expected[1] + u1Expected[0]) b = sespake.B( curve, q, @@ -427,8 +409,7 @@ salt=self.salt, fpw=self.fpw, ) u2 = b.ka(a.u1, beta=beta) - self.assertSequenceEqual(u2[0].to_bytes(curve.point_size, "big").hex(), u2Expected[0]) - self.assertSequenceEqual(u2[1].to_bytes(curve.point_size, "big").hex(), u2Expected[1]) + self.assertSequenceEqual(u2[::-1].hex(), u2Expected[1] + u2Expected[0]) macA = a.ka(u2) self.assertSequenceEqual(macA.hex(), macAExpected) macB = b.kc(macA)