diff --git a/alltests.py b/alltests.py new file mode 100644 index 0000000..23d5331 --- /dev/null +++ b/alltests.py @@ -0,0 +1,7 @@ +import unittest + +from rstest import * +from polynomialtest import * +from fftest import * + +unittest.main() diff --git a/ff.py b/ff.py index 047b723..eb7f553 100644 --- a/ff.py +++ b/ff.py @@ -101,3 +101,24 @@ def __rdiv__(self, other): def __repr__(self): n = self.__class__.__name__ return "%s(%r)" % (n, int(self)) + + def multiply(self, other): + """A slow multiply method. This method gives the same results as the + other multiply method, but is implemented to illustrate how it works + and how the above tables were generated. + + This procedure is called Peasant's Algorithm (I believe) + """ + a = int(self) + b = int(other) + + p = a + r = 0 + while b: + if b & 1: r = r ^ p + b = b >> 1 + p = p << 1 + if p & 0x100: p = p ^ 0x11b + + return GF256int(r) + diff --git a/fftest.py b/fftest.py index 0e6fa5f..2efe791 100644 --- a/fftest.py +++ b/fftest.py @@ -1,4 +1,5 @@ import unittest +import itertools from ff import GF256int @@ -41,5 +42,13 @@ def test_fermats_theorem(self): for x in range(1,256): self.assertEqual(GF256int(x)**255, 1) + def test_other_multiply(self): + + a = GF256int(3) + b = GF256int(9) + + self.assertEqual(a * b, a.multiply(b)) + + if __name__ == "__main__": unittest.main() diff --git a/polynomial.py b/polynomial.py index 0ee0122..0218da2 100644 --- a/polynomial.py +++ b/polynomial.py @@ -95,30 +95,28 @@ def __floordiv__(self, other): return divmod(self, other)[0] def __mod__(self, other): return divmod(self, other)[1] - def __divmod__(self, other): + def __divmod__(dividend, divisor): # See how many times the highest order term - # of other can go into the highest order term of self + # of the divisor can go into the highest order term of the dividend - # "self" - dividend_power = len(self) - 1 - dividend_coefficient = self.coefficients[0] + dividend_power = len(dividend) - 1 + dividend_coefficient = dividend.coefficients[0] - # "other" - divisor_power = len(other) - 1 - divisor_coefficient = other.coefficients[0] + divisor_power = len(divisor) - 1 + divisor_coefficient = divisor.coefficients[0] quotient_power = dividend_power - divisor_power if quotient_power < 0: # Doesn't divide at all, return 0 for the quotient and the entire # dividend as the remander - return Polynomial((0,)), self + return Polynomial((0,)), dividend # Compute how many times the highest order term in the divisor goes # into the dividend quotient_coefficient = dividend_coefficient / divisor_coefficient quotient = Polynomial( (quotient_coefficient,) + (0,) * quotient_power ) - remander = self - quotient * other + remander = dividend - quotient * divisor if remander.coefficients == (0,): # Goes in evenly with no remainder, we're done @@ -126,7 +124,7 @@ def __divmod__(self, other): # There was a remander, see how many times the remainder goes into the # divisor - morequotient, remander = divmod(remander, other) + morequotient, remander = divmod(remander, divisor) return quotient + morequotient, remander def __eq__(self, other):