diff --git a/shamirss.py b/shamirss.py index d6a2f88..408f196 100644 --- a/shamirss.py +++ b/shamirss.py @@ -227,16 +227,39 @@ class GF2p8: if x == -1 and self._invcache: return self.__class__(self._invcache[self._v]) - if x < 0: - x += 255 + # we loop after 255, so no need to do extra work + x %= 255 - v = self.__class__(1) + # Note: not constant time, also, not optimial algorithm - # TODO - make faster via caching and squaring - for i in range(x): - v *= self + # The art of computer programming vol 2. ยง 4.6.3 Algorithm A + # https://archive.org/details/artofcomputerpro0000knut/page/400/mode/2up - return v + # A1 + n = x + y = self.__class__(1) + z = self + + while n: + # A2 + n, isodd = divmod(n, 2) + + if not isodd: + # A5 + z *= z + continue + + # A3 + y *= z + + # A4 + if not n: + break + + # A5 + z *= z + + return y def powerseries(self, cnt): '''Generate [ self ** 0, self ** 1, ..., self ** cnt ].''' @@ -340,11 +363,20 @@ class TestShamirSS(unittest.TestCase): a = GF2p8(random.randint(0, 255)) v = GF2p8(1) - for i in range(10): + for i in range(260): self.assertEqual(a ** i, v) v = v * a + for i in range(10): + neg = random.randint(-600, -1) + + p = neg + while p < 0: + p += 255 + + self.assertEqual(a ** neg, a ** p) + for i in range(10): a = GF2p8(random.randint(0, 255))