Advertisement
CuriousStudent

fieldpy

Mar 8th, 2023
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.40 KB | None | 0 0
  1. from unittest import TestCase
  2.  
  3.  
  4.  
  5. class FieldElement:
  6.  
  7. def __init__(self, num, prime):
  8. if num >= prime or num < 0:
  9. error = 'Num {} not in field range 0 to {}'.format(
  10. num, prime - 1)
  11. raise ValueError(error)
  12. self.num = num
  13. self.prime = prime
  14.  
  15. def __repr__(self):
  16. return 'FieldElement_{}({})'.format(self.prime, self.num)
  17.  
  18. def __eq__(self, other):
  19. if other is None:
  20. return False
  21. return self.num == other.num and self.prime == other.prime
  22.  
  23. def __ne__(self, other):
  24. # this should be the inverse of the == operator
  25. return not (self == other)
  26.  
  27. def __add__(self, other):
  28. if self.prime != other.prime:
  29. raise TypeError('Cannot add two numbers in different Fields')
  30. # self.num and other.num are the actual values
  31. # self.prime is what we need to mod against
  32. num = (self.num + other.num) % self.prime
  33. # We return an element of the same class
  34. return self.__class__(num, self.prime)
  35.  
  36. def __sub__(self, other):
  37. if self.prime != other.prime:
  38. raise TypeError('Cannot subtract two numbers in different Fields')
  39. # self.num and other.num are the actual values
  40. # self.prime is what we need to mod against
  41. num = (self.num - other.num) % self.prime
  42. # We return an element of the same class
  43. return self.__class__(num, self.prime)
  44.  
  45. def __mul__(self, other):
  46. if self.prime != other.prime:
  47. raise TypeError('Cannot multiply two numbers in different Fields')
  48. # self.num and other.num are the actual values
  49. # self.prime is what we need to mod against
  50. num = (self.num * other.num) % self.prime
  51. # We return an element of the same class
  52. return self.__class__(num, self.prime)
  53.  
  54. def __pow__(self, exponent):
  55. n = exponent % (self.prime - 1)
  56. num = pow(self.num, n, self.prime)
  57. return self.__class__(num, self.prime)
  58.  
  59. def __truediv__(self, other):
  60. if self.prime != other.prime:
  61. raise TypeError('Cannot divide two numbers in different Fields')
  62. # self.num and other.num are the actual values
  63. # self.prime is what we need to mod against
  64. # use fermat's little theorem:
  65. # self.num**(p-1) % p == 1
  66. # this means:
  67. # 1/n == pow(n, p-2, p)
  68.  
  69. raise NotImplementedError
  70.  
  71. def __rmul__(self, coefficient):
  72. num = (self.num * coefficient) % self.prime
  73. return self.__class__(num=num, prime=self.prime)
  74.  
  75.  
  76. class FieldElementTest(TestCase):
  77.  
  78. def test_ne(self):
  79. a = FieldElement(2, 31)
  80. b = FieldElement(2, 31)
  81. c = FieldElement(15, 31)
  82. self.assertEqual(a, b)
  83. self.assertTrue(a != c)
  84. self.assertFalse(a != b)
  85.  
  86. def test_add(self):
  87. a = FieldElement(2, 31)
  88. b = FieldElement(15, 31)
  89. self.assertEqual(a + b, FieldElement(17, 31))
  90. a = FieldElement(17, 31)
  91. b = FieldElement(21, 31)
  92. self.assertEqual(a + b, FieldElement(7, 31))
  93. # TODO - implement another assertEqual test using 23 prime number
  94.  
  95. def test_sub(self):
  96. a = FieldElement(29, 31)
  97. b = FieldElement(4, 31)
  98. self.assertEqual(a - b, FieldElement(25, 31))
  99. a = FieldElement(15, 31)
  100. b = FieldElement(30, 31)
  101. self.assertEqual(a - b, FieldElement(16, 31))
  102. # TODO - implement another assertEqual test using 23 prime number
  103.  
  104. def test_mul(self):
  105. a = FieldElement(24, 31)
  106. b = FieldElement(19, 31)
  107. self.assertEqual(a * b, FieldElement(22, 31))
  108.  
  109. def test_rmul(self):
  110. a = FieldElement(24, 31)
  111. b = 2
  112. self.assertEqual(b * a, a + a)
  113.  
  114. def test_pow(self):
  115. a = FieldElement(17, 31)
  116. self.assertEqual(a**3, FieldElement(15, 31))
  117. a = FieldElement(5, 31)
  118. b = FieldElement(18, 31)
  119. self.assertEqual(a**5 * b, FieldElement(16, 31))
  120.  
  121. #def test_div(self):
  122. # a = FieldElement(3, 31)
  123. # b = FieldElement(24, 31)
  124. # self.assertEqual(a / b, FieldElement(4, 31))
  125. # a = FieldElement(17, 31)
  126. # self.assertEqual(a**-3, FieldElement(29, 31))
  127. # a = FieldElement(4, 31)
  128. # b = FieldElement(11, 31)
  129. # self.assertEqual(a**-4 * b, FieldElement(13, 31))
  130.  
  131.  
  132.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement