# GNU GPLv3, see LICENSE
import random
import unittest
from unittest import TestCase
from ..gf256 import _gfmul
from ..gf256 import *
class TestGF256(TestCase):
def test__gfmul(self):
self.assertEqual(_gfmul(0, 0), 0)
self.assertEqual(_gfmul(1, 1), 1)
self.assertEqual(_gfmul(2, 2), 4)
self.assertEqual(_gfmul(0, 21), 0)
self.assertEqual(_gfmul(0x53, 0xca), 0x01)
self.assertEqual(_gfmul(0xff, 0xff), 0x13)
def test_gfmul(self):
for a in range(256):
for b in range(256):
self.assertEqual(_gfmul(a, b), gfmul(a, b))
def test_gfpow(self):
self.assertEqual(gfpow(0, 0), 1)
for i in range(1, 256):
self.assertEqual(gfpow(i, 0), 1)
self.assertEqual(gfpow(i, 1), i)
self.assertEqual(gfpow(0, i), 0)
self.assertEqual(gfpow(1, i), 1)
self.assertEqual(gfpow(i, 256), i)
self.assertEqual(gfpow(i, 2), gfmul(i, i))
random.seed(1918)
for i in range(256):
j = random.randint(2, 255)
k = random.randint(3, 255)
y = 1
for m in range(k):
y = gfmul(y, j)
self.assertEqual(gfpow(j, k), y)
def test_evaluate(self):
for x in range(256):
(a0, a1, a2, a3) = (x, x>>1, x>>2, x>>3)
self.assertEqual(evaluate([17], x), 17) # constant polynomial
self.assertEqual(evaluate([a3, a2, a1, a0], 0), x) # any polynomial at 0
self.assertEqual(evaluate([a3, a2, a1, a0], 1), a0^a1^a2^a3) # polynomial at 1 == sum of coefficients
def test_get_constant_coef(self):
weights = compute_weights((1, 2, 3))
ys = (1, 2, 3)
self.assertEqual(get_constant_coef(weights, ys), 0)
random.seed(17)
random_matches = 0
for i in range(10):
k = random.randint(2, 255)
# exact
res = self.check_coefs_match(k, k)
self.assertEqual(res[0], res[1])
# overdetermined
res = self.check_coefs_match(k, 256)
self.assertEqual(res[0], res[1])
# underdetermined => random
res = self.check_coefs_match(k, k-1)
if res[0]==res[1]:
random_matches += 1
self.assertLess(random_matches, 2) # with a chance (255/256)**10=0.96 there should be no match
def check_coefs_match(self, k, m):
coefs = [random.randint(0, 255) for i in range(k)]
points = [(j, evaluate(coefs, j)) for j in range(1, 256)]
random.shuffle(points)
(xs, ys) = zip(*points[:m])
weights = compute_weights(xs)
return (get_constant_coef(weights, ys), coefs[-1])
if __name__=='__main__':
unittest.main()