|
|
@@ -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)) |
|
|
|
|
|
|
|