예제 #1
0
 def test_mod_7_gcd(self):
     """Test that the GCD works in mod-7 arithmetic."""
     Mod7 = IntegersModP(7)
     # TODO(rbharath): Why are these modular equations right? Is there a way to
     # do simple mental arithmetic to calculate these values?
     assert Mod7(6) == gcd(Mod7(6), Mod7(14))
     assert Mod7(2) == gcd(Mod7(6), Mod7(9))
예제 #2
0
 def test_gcd_ints(self):
     """Test that the GCD functions correctly on ints."""
     assert gcd(7, 9) == 1
     assert gcd(8, 18) == 2
     assert gcd(-12, 24) == -12
     # gcd is only unique up to multiplication by a unit, and so sometimes we'll get negatives.
     assert gcd(12, -24) == 12
     assert gcd(4864, 3458) == 38
예제 #3
0
 def test_mod_large_gcd(self):
     """Test that GCD works with a larger prime."""
     ModHuge = IntegersModP(9923)
     assert ModHuge(38) == gcd(ModHuge(4864), ModHuge(3458))
     assert (ModHuge(32), ModHuge(-45),
             ModHuge(38)) == extended_euclidean_algorithm(
                 ModHuge(4864), ModHuge(3458))
예제 #4
0
def is_irreducible(polynomial: Poly, p: int) -> bool:
    """is_irreducible: Polynomial, int -> bool

  Determine if the given monic polynomial with coefficients in Z/p is
  irreducible over Z/p where p is the given integer
  Algorithm 4.69 in the Handbook of Applied Cryptography
  """
    ZmodP = IntegersModP(p)
    if polynomial.ring is not ZmodP:
        raise TypeError(
            "Given a polynomial that's not over %s, but instead %r" %
            (ZmodP.__name__, polynomial.ring.__name__))

    poly = polynomials_over(ZmodP).factory
    x = poly([0, 1])
    power_term = x
    is_unit = lambda p: p.degree() == 0

    for _ in range(int(polynomial.degree() / 2)):
        power_term = power_term.powmod(p, polynomial)
        gcd_over_Zmodp = gcd(polynomial, power_term - x)
        if not is_unit(gcd_over_Zmodp):
            return False

    return True
예제 #5
0
        def __init__(self, m, n=1):
            """Constructor for rationals.

      If denominator is not specified, set it to 1.
      """
            try:
                # This is awkward constructor overloading
                if isinstance(m, bytes):
                    num = int.from_bytes(m[:32], 'big')
                    den = int.from_bytes(m[32:], 'big')
                else:
                    num = int(m) % RationalModP.p
                    den = int(n) % RationalModP.p
                common = gcd(num, den)
                # Handle case with 0
                if common == 0:
                    self.m, self.n = num, den
                else:
                    self.m = num // common
                    self.n = den // common
            except:
                raise TypeError("Can't cast type %s to %s in __init__" %
                                (type(n).__name__, type(self).__name__))

            self.field = RationalModP
예제 #6
0
 def test_mod_2_gcd(self):
     """Test that the GCD works in mod-2 arithmetic."""
     Mod2 = IntegersModP(2)
     assert Mod2(1) == gcd(Mod2(1), Mod2(0))
     assert Mod2(1) == gcd(Mod2(1), Mod2(1))
     assert Mod2(0) == gcd(Mod2(2), Mod2(2))
예제 #7
0
 def __sub__(self, other):
     num = (self.m * other.n - other.m * self.n) % RationalModP.p
     den = (self.n * other.n) % RationalModP.p
     common = gcd(num, den)
     return RationalModP(num // common, den // common)