A Pure Python implementation of Shamir's Secret Sharing
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
2.2 KiB

  1. import unittest
  2. import random
  3. def _makered(x, y):
  4. '''Make reduction table entry.
  5. given x * 2^8, reduce it assuming polynomial y.
  6. '''
  7. x = x << 8
  8. for i in range(3, -1, -1):
  9. if x & (1 << (i + 8)):
  10. x ^= (0x100 + y) << i
  11. assert x < 256
  12. return x
  13. class GF2p8:
  14. @staticmethod
  15. def _primativemul(a, b):
  16. masks = [ 0, 0xff ]
  17. r = 0
  18. for i in range(0, 8):
  19. mask = a & 1
  20. r ^= (masks[mask] & b) << i
  21. a = a >> 1
  22. return r
  23. # polynomial 0x187
  24. _reduce = { x: _makered(x, 0x87) for x in range(0, 16) }
  25. def __init__(self, v):
  26. if v >= 256:
  27. raise ValueError('%d is not a member of GF(2^8)' % v)
  28. self._v = v
  29. def __add__(self, o):
  30. if isinstance(o, int):
  31. return self + self.__class__(o)
  32. return self.__class__(self._v ^ o._v)
  33. def __radd__(self, o):
  34. return self.__add__(o)
  35. def __rmul__(self, o):
  36. return self.__mul__(o)
  37. def __sub__(self, o):
  38. return self.__class__(self._v ^ o._v)
  39. def __mul__(self, o):
  40. if isinstance(o, int):
  41. o = self.__class__(o)
  42. m = o._v
  43. # multiply
  44. r = self._primativemul(self._v, m)
  45. # reduce
  46. r ^= self._reduce[r >> 12] << 4
  47. r ^= self._reduce[(r >> 8) & 0xf ]
  48. r &= 0xff
  49. return self.__class__(r)
  50. def __eq__(self, o):
  51. if isinstance(o, int):
  52. return self._v == o
  53. return self._v == o._v
  54. def __repr__(self):
  55. return '%s(%d)' % (self.__class__.__name__, self._v)
  56. class TestShamirSS(unittest.TestCase):
  57. def test_gf28(self):
  58. for i in range(10):
  59. a = GF2p8(random.randint(0, 255))
  60. b = GF2p8(random.randint(0, 255))
  61. c = GF2p8(random.randint(0, 255))
  62. self.assertEqual(a * 0, 0)
  63. # Identity
  64. self.assertEqual(a + 0, a)
  65. self.assertEqual(a * 1, a)
  66. self.assertEqual(0 + a, a)
  67. self.assertEqual(1 * a, a)
  68. # Associativity
  69. self.assertEqual((a + b) + c, a + (b + c))
  70. self.assertEqual((a * b) * c, a * (b * c))
  71. # Communitative
  72. self.assertEqual(a + b, b + a)
  73. self.assertEqual(a * b, b * a)
  74. # Distributive
  75. self.assertEqual(a * (b + c), a * b + a * c)
  76. self.assertEqual((b + c) * a, b * a + c * a)
  77. # Basic mul
  78. self.assertEqual(GF2p8(0x80) * 2, 0x87)
  79. self.assertEqual(GF2p8(0x80) * 6, (0x80 * 6) ^ (0x187 << 1))
  80. self.assertEqual(GF2p8(0x80) * 8, (0x80 * 8) ^ (0x187 << 2) ^ (0x187 << 1) ^ 0x187)
  81. self.assertEqual(a + b - b, a)