def test_mod_inverse(a, m):
    if gcd(a.norm, m) > 1:
        with pytest.raises(ValueError):
            a.mod_inverse(m)
    else:
        assert type(a.mod_inverse(m)) is QuaternionInteger
        assert (a * a.mod_inverse(m)) % m == 1
def test_pow_mod(a, exp, mod):
    power = a**exp
    mod_power = pow(a, exp, mod)
    assert type(power) is GaussianInteger
    assert type(mod_power) is GaussianInteger
    if gcd(a.norm, mod) > 1:
        with pytest.raises(ValueError):
            pow(a, -exp, mod)
    else:
        mod_power_inv = pow(a, -exp, mod)
        assert type(mod_power_inv) is GaussianInteger
        assert (mod_power * mod_power_inv) % mod == 1
def test_pow_mod(a, exp, mod):
    power = a**exp
    mod_power = pow(a, exp, mod)
    assert type(power) is QuaternionInteger
    assert type(mod_power) is QuaternionInteger
    assert power % mod == mod_power
    if exp > 0 and gcd(a.norm, mod) > 1:
        with pytest.raises(ValueError):
            pow(a, -exp, mod)
    else:
        mod_power_inv = pow(a, -exp, mod)
        assert type(mod_power_inv) is QuaternionInteger
        assert (mod_power * mod_power_inv) % mod == 1
Ejemplo n.º 4
0
def test_euler_phi_and_carmichael_lambda(number):
    factorization = factor(number)
    euler = euler_phi(factorization)
    carmichael = carmichael_lambda(factorization)
    assert euler == euler_phi(number)
    assert carmichael == carmichael_lambda(number)

    mult_group = [x for x in range(1, number) if gcd(x, number) == 1]
    half_carmichael_powers = map(
        lambda x: pow(x, carmichael // 2, number),
        mult_group
    )
    carmichael_powers = map(lambda x: pow(x, carmichael, number), mult_group)

    assert len(mult_group) == euler
    assert set(half_carmichael_powers) != set([1])
    assert set(carmichael_powers) == set([1])
Ejemplo n.º 5
0
def test_modular_ring(modulus, a, b, c):
    Zm = ModularRing(modulus)

    assert Zm._factorization is None
    assert Zm.factorization()
    assert Zm._factorization == Zm.factorization()

    assert Zm._euler is None
    assert Zm.euler() is not None
    assert Zm._euler == Zm.euler()

    assert Zm._carmichael is None
    assert Zm.carmichael() is not None
    assert Zm._carmichael == Zm.carmichael()

    assert Zm._carmichael_factorization is None
    assert Zm.carmichael_factorization() is not None
    assert Zm._carmichael_factorization == Zm.carmichael_factorization()

    assert Zm._multiplicative_group is None
    assert Zm.multiplicative_group() is not None
    assert Zm._multiplicative_group == Zm.multiplicative_group()

    if modulus == 2:
        assert Zm.orders == {1: 1}
    else:
        assert Zm.orders == {1: 1, modulus - 1: 2}

    if len(Zm.factorization().keys()) == 1:
        if 2 in Zm.factorization().keys():
            assert Zm.is_cyclic() == (Zm.factorization()[2] < 3)
        else:
            assert Zm.is_cyclic()
    elif len(Zm.factorization().keys()) == 2:
        assert Zm.is_cyclic() == ((2, 1) in Zm.factorization().items())
    else:
        assert not Zm.is_cyclic()

    if not Zm.is_cyclic():
        assert Zm.generator() is None
        assert Zm.cyclic_group_dict() is None
        assert Zm.discrete_log_dict() is None
        assert Zm.all_generators() == []
    else:
        assert Zm._generator is None
        assert Zm._cyclic_group_dict is None
        assert Zm._discrete_log_dict is None

    assert Zm.elem(a) == a % modulus
    assert Zm.add(a, b, c) == (a + b + c) % modulus
    assert Zm.mult(a, b, c) == (a * b * c) % modulus

    x = Zm.multiplicative_group()[a % Zm.euler()]
    assert Zm.power_of(x, b) == mod_power(x, b, modulus)
    order = Zm.order_of(x)
    assert len(Zm.cyclic_subgroup_from(x).keys()) == order

    Zm.all_inverses()
    inverse_pairs = set(tuple(sorted(x)) for x in Zm.inverses.items())
    for (x, y) in inverse_pairs:
        assert Zm.mult(x, y) == 1

    Zm.all_orders()
    assert Zm.orders == Zm.all_orders()
    assert max(Zm.orders.values()) == Zm.carmichael()

    if Zm.is_cyclic():
        gens = set(x for x in Zm.multiplicative_group()
                   if Zm.orders[x] == Zm.euler())
        gens2 = set(x for i, x in Zm.cyclic_group_dict().items()
                    if gcd(i, Zm.euler()) == 1)
        assert gens == gens2

    if Zm.is_field() and Zm.modulus > 2:
        assert is_prime(Zm.modulus)
        for x in (Zm.elem(y) for y in (a, b, c) if Zm.elem(y) != 0):
            if jacobi(x, Zm.modulus) == 1:
                for y in Zm.sqrt_of(x):
                    assert Zm.power_of(y, 2) == x
                    assert Zm.log_of(x) == (Zm.log_of(y) * 2) % (Zm.euler())