Exemple #1
0
void
mpi_divexact(const mpi *a, const mpi *b, mpi *q)
{
    ASSERT(b->size != 0);

    if (a->size == 0 ||
            a->size < b->size) {
        /* FIXME: raise an error here? */
        mpi_zero(q);
        return;
    }
    if (a == b) {
        mpi_set_u32(q, 1);
        return;
    }

    mp_size qsize = a->size - b->size + 1;
    if (a == q || b == q) {
        mp_digit *quot = MP_TMP_ALLOC(qsize);
        mp_divexact(a->digits, a->size,
                    b->digits, b->size, quot);
        MP_NORMALIZE(quot, qsize);
        MPI_SIZE(q, qsize);
        mp_copy(quot, qsize, q->digits);
        MP_TMP_FREE(quot);
    } else {
        MPI_MIN_ALLOC(q, qsize);
        mp_divexact(a->digits, a->size,
                    b->digits, b->size, q->digits);
        MP_NORMALIZE(q->digits, qsize);
    }
    q->size = qsize;
    q->sign = a->sign ^ b->sign;
}
Exemple #2
0
// References : Cohen H., A course in computational algebraic number theory
// (1996), page 25.
bool multiplicative_order(const Ptr<RCP<const Integer>> &o,
                          const RCP<const Integer> &a,
                          const RCP<const Integer> &n)
{
    integer_class order, p, t;
    integer_class _a = a->as_integer_class(),
                  _n = mp_abs(n->as_integer_class());
    mp_gcd(t, _a, _n);
    if (t != 1)
        return false;

    RCP<const Integer> lambda = carmichael(n);
    map_integer_uint prime_mul;
    prime_factor_multiplicities(prime_mul, *lambda);
    _a %= _n;
    order = lambda->as_integer_class();

    for (const auto it : prime_mul) {
        p = it.first->as_integer_class();
        mp_pow_ui(t, p, it.second);
        mp_divexact(order, order, t);
        mp_powm(t, _a, order, _n);
        while (t != 1) {
            mp_powm(t, t, p, _n);
            order *= p;
        }
    }
    *o = integer(std::move(order));
    return true;
}
Exemple #3
0
RCP<const Integer> totient(const RCP<const Integer> &n)
{
    if (n->is_zero())
        return integer(1);

    integer_class phi = n->as_integer_class(), p;
    if (phi < 0)
        phi = -phi;
    map_integer_uint prime_mul;
    prime_factor_multiplicities(prime_mul, *n);

    for (const auto &it : prime_mul) {
        p = it.first->as_integer_class();
        mp_divexact(phi, phi, p);
        // phi is exactly divisible by p.
        phi *= p - 1;
    }
    return integer(std::move(phi));
}