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