Path: blob/master/sage/rings/bernmm/bern_modp_util.cpp
4057 views
/*1bern_modp_util.cpp: number-theoretic utility functions23Copyright (C) 2008, 2009, David Harvey45This file is part of the bernmm package (version 1.1).67bernmm is released under a BSD-style license. See the README file in8the source distribution for details.9*/101112#include <NTL/ZZ.h>13#include "bern_modp_util.h"141516NTL_CLIENT;171819namespace bernmm {202122long PowerMod(long a, long ee, long n, double ninv)23{24long x, y;2526unsigned long e;2728if (ee < 0)29e = - ((unsigned long) ee);30else31e = ee;3233x = 1;34y = a;35while (e) {36if (e & 1) x = MulMod(x, y, n, ninv);37y = MulMod(y, y, n, ninv);38e = e >> 1;39}4041if (ee < 0) x = InvMod(x, n);4243return x;44}45464748void Factorisation::helper(long k, long m)49{50if (m == 1)51return;5253for (long i = k + 1; i * i <= m; i++)54{55if (m % i == 0)56{57// found a factor58factors.push_back(i);59// remove that factor entirely60for (m /= i; m % i == 0; m /= i);61// recurse62helper(i, m);63return;64}65}6667// no more factors68factors.push_back(m);69}707172Factorisation::Factorisation(long n)73{74this->n = n;75helper(1, n);76}777879PrimeTable::PrimeTable(long bound)80{81long size = (bound - 1) / ULONG_BITS + 1; // = ceil(bound / ULONG_BITS)82data.resize(size);8384for (long i = 2; i * i < bound; i++)85if (is_prime(i))86for (long j = 2*i; j < bound; j += i)87set(j);88}899091long order(long x, long p, double pinv, const Factorisation& F)92{93// in the loop below, m is always some multiple of the order of x94long m = p - 1;9596// try to remove factors from m until we can't remove any more97for (int i = 0; i < F.factors.size(); i++)98{99long q = F.factors[i];100101while (m % q == 0)102{103long mm = m / q;104if (PowerMod(x, mm, p, pinv) != 1)105break;106m = mm;107}108}109110return m;111}112113114115long primitive_root(long p, double pinv, const Factorisation& F)116{117if (p == 2)118return 1;119120long g = 2;121for (; g < p; g++)122if (order(g, p, pinv, F) == p - 1)123return g;124125// no generator exists!?126abort();127}128129130131}; // end namespace132133134// end of file ================================================================135136137