| @@ -141,7 +141,8 @@ class GF2p8: | |||||
| return r | return r | ||||
| _reduce = (0, 135, 137, 14, 149, 18, 28, 155, 173, 42, 36, 163, 56, 191, 177, 54) | |||||
| # bytes is smaller, 49 vs 168 bytes, so should fit in a cache line | |||||
| _reduce = b'\x00\x87\x89\x0e\x95\x12\x1c\x9b\xad*$\xa38\xbf\xb16' | |||||
| def __init__(self, v): | def __init__(self, v): | ||||
| '''v must be in the range [ 0, 255 ]. | '''v must be in the range [ 0, 255 ]. | ||||
| @@ -185,6 +186,17 @@ class GF2p8: | |||||
| m = o._v | m = o._v | ||||
| # possibly use log tables: | |||||
| # a = GF2p8(0x87) | |||||
| # logtbl = { idx: a ** idx for idx in range(256) } | |||||
| # invlogtbl = { v: k for k, v in logtbl.items() } | |||||
| # len(invlogtbl) | |||||
| # 255 | |||||
| # invlogtbl[GF2p8(6)] + invlogtbl[GF2p8(213)] | |||||
| # 254 | |||||
| # logtbl[254] | |||||
| # GF2p8(119) | |||||
| # multiply | # multiply | ||||
| r = self._primativemul(self._v, m) | r = self._primativemul(self._v, m) | ||||
| @@ -245,6 +257,9 @@ class GF2p8: | |||||
| def __int__(self): | def __int__(self): | ||||
| return self._v | return self._v | ||||
| def __hash__(self): | |||||
| return hash(self._v) | |||||
| def __repr__(self): | def __repr__(self): | ||||
| return '%s(%d)' % (self.__class__.__name__, self._v) | return '%s(%d)' % (self.__class__.__name__, self._v) | ||||
| @@ -298,7 +313,7 @@ class TestShamirSS(unittest.TestCase): | |||||
| self.assertEqual(val, recover_data([ a[j] for j in random.sample(range(30), 15) ], 15)) | self.assertEqual(val, recover_data([ a[j] for j in random.sample(range(30), 15) ], 15)) | ||||
| def test_gf2p8_reduce(self): | def test_gf2p8_reduce(self): | ||||
| reduce = tuple(_makered(x, 0x87) for x in range(0, 16)) | |||||
| reduce = bytes((_makered(x, 0x87) for x in range(0, 16))) | |||||
| if GF2p8._reduce != reduce: # pragma: no cover | if GF2p8._reduce != reduce: # pragma: no cover | ||||
| print('reduce:', repr(reduce)) | print('reduce:', repr(reduce)) | ||||