|
|
@@ -0,0 +1,117 @@ |
|
|
|
import unittest |
|
|
|
import random |
|
|
|
|
|
|
|
def _makered(x, y): |
|
|
|
'''Make reduction table entry. |
|
|
|
|
|
|
|
given x * 2^8, reduce it assuming polynomial y. |
|
|
|
''' |
|
|
|
|
|
|
|
x = x << 8 |
|
|
|
|
|
|
|
for i in range(3, -1, -1): |
|
|
|
if x & (1 << (i + 8)): |
|
|
|
x ^= (0x100 + y) << i |
|
|
|
|
|
|
|
assert x < 256 |
|
|
|
|
|
|
|
return x |
|
|
|
|
|
|
|
class GF2p8: |
|
|
|
@staticmethod |
|
|
|
def _primativemul(a, b): |
|
|
|
masks = [ 0, 0xff ] |
|
|
|
|
|
|
|
r = 0 |
|
|
|
|
|
|
|
for i in range(0, 8): |
|
|
|
mask = a & 1 |
|
|
|
r ^= (masks[mask] & b) << i |
|
|
|
a = a >> 1 |
|
|
|
|
|
|
|
return r |
|
|
|
|
|
|
|
# polynomial 0x187 |
|
|
|
_reduce = { x: _makered(x, 0x87) for x in range(0, 16) } |
|
|
|
|
|
|
|
def __init__(self, v): |
|
|
|
if v >= 256: |
|
|
|
raise ValueError('%d is not a member of GF(2^8)' % v) |
|
|
|
|
|
|
|
self._v = v |
|
|
|
|
|
|
|
def __add__(self, o): |
|
|
|
if isinstance(o, int): |
|
|
|
return self + self.__class__(o) |
|
|
|
|
|
|
|
return self.__class__(self._v ^ o._v) |
|
|
|
|
|
|
|
def __radd__(self, o): |
|
|
|
return self.__add__(o) |
|
|
|
|
|
|
|
def __rmul__(self, o): |
|
|
|
return self.__mul__(o) |
|
|
|
|
|
|
|
def __sub__(self, o): |
|
|
|
return self.__class__(self._v ^ o._v) |
|
|
|
|
|
|
|
def __mul__(self, o): |
|
|
|
|
|
|
|
if isinstance(o, int): |
|
|
|
o = self.__class__(o) |
|
|
|
|
|
|
|
m = o._v |
|
|
|
|
|
|
|
# multiply |
|
|
|
r = self._primativemul(self._v, m) |
|
|
|
|
|
|
|
# reduce |
|
|
|
r ^= self._reduce[r >> 12] << 4 |
|
|
|
r ^= self._reduce[(r >> 8) & 0xf ] |
|
|
|
|
|
|
|
r &= 0xff |
|
|
|
|
|
|
|
return self.__class__(r) |
|
|
|
|
|
|
|
def __eq__(self, o): |
|
|
|
if isinstance(o, int): |
|
|
|
return self._v == o |
|
|
|
|
|
|
|
return self._v == o._v |
|
|
|
|
|
|
|
def __repr__(self): |
|
|
|
return '%s(%d)' % (self.__class__.__name__, self._v) |
|
|
|
|
|
|
|
class TestShamirSS(unittest.TestCase): |
|
|
|
def test_gf28(self): |
|
|
|
for i in range(10): |
|
|
|
a = GF2p8(random.randint(0, 255)) |
|
|
|
b = GF2p8(random.randint(0, 255)) |
|
|
|
c = GF2p8(random.randint(0, 255)) |
|
|
|
|
|
|
|
self.assertEqual(a * 0, 0) |
|
|
|
|
|
|
|
# Identity |
|
|
|
self.assertEqual(a + 0, a) |
|
|
|
self.assertEqual(a * 1, a) |
|
|
|
self.assertEqual(0 + a, a) |
|
|
|
self.assertEqual(1 * a, a) |
|
|
|
|
|
|
|
# Associativity |
|
|
|
self.assertEqual((a + b) + c, a + (b + c)) |
|
|
|
self.assertEqual((a * b) * c, a * (b * c)) |
|
|
|
|
|
|
|
# Communitative |
|
|
|
self.assertEqual(a + b, b + a) |
|
|
|
self.assertEqual(a * b, b * a) |
|
|
|
|
|
|
|
# Distributive |
|
|
|
self.assertEqual(a * (b + c), a * b + a * c) |
|
|
|
self.assertEqual((b + c) * a, b * a + c * a) |
|
|
|
|
|
|
|
# Basic mul |
|
|
|
self.assertEqual(GF2p8(0x80) * 2, 0x87) |
|
|
|
self.assertEqual(GF2p8(0x80) * 6, (0x80 * 6) ^ (0x187 << 1)) |
|
|
|
self.assertEqual(GF2p8(0x80) * 8, (0x80 * 8) ^ (0x187 << 2) ^ (0x187 << 1) ^ 0x187) |
|
|
|
|
|
|
|
self.assertEqual(a + b - b, a) |