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)