Exemple #1
0
/* assume m is invertible */
void
dirichlet_char_log(dirichlet_char_t x, const dirichlet_group_t G, ulong m)
{
    slong k;
    /* even part */
    if (G->neven >= 1)
    {
      x->log[0] = (m % 4 == 3);
      if (G->neven == 2)
      {
        ulong m2 = (x->log[0]) ? -m % G->q_even : m % G->q_even;
        if (G->P[1].dlog == NULL)
            x->log[1] = dlog_mod2e_1mod4(m2, G->P[1].e,
                    nmod_inv(5, G->P[1].pe), G->P[1].pe);
        else
            x->log[1] = dlog_precomp(G->P[1].dlog, m2);
      }
    }
    /* odd part */
    for (k = G->neven; k < G->num; k++)
    {
        dirichlet_prime_group_struct P = G->P[k];
        if (P.dlog == NULL)
        {
            x->log[k] = dlog_once(m % P.pe.n, P.g, P.pe, P.phi.n);
        }
        else
        {
            x->log[k] = dlog_precomp(P.dlog, m % P.pe.n);
        }
    }
    /* keep value m */
    x->n = m;
}
Exemple #2
0
static void
dirichlet_group_lift_generators(dirichlet_group_t G)
{
    slong k;
    dirichlet_prime_group_struct * P = G->P;

    G->expo = G->phi_q = 1;
    if (G->neven)
    {
        G->phi_q = G->q_even / 2;
        G->expo = P[G->neven - 1].phi.n;
    }
    for (k = G->neven; k < G->num; k++)
    {
        G->phi_q *= P[k].phi.n;
        G->expo *= P[k].phi.n / n_gcd(G->expo, P[k].p - 1);
    }

    for (k = 0; k < G->num; k++)
    {
        nmod_t pe;
        ulong qpe, v;
        G->PHI[k] = G->expo / G->P[k].phi.n;
        /* lift generators mod q */
        /* u * p^e + v * q/p^e = 1 -> g mod q = 1 + (g-1) * v*(q/p^e) */
        pe = G->P[k].pe;
        qpe = G->q / pe.n;
        if (G->q < G->P[k].pe.n)
        {
            flint_printf("lift generator %wu from %wu to %wu e=%wu\n",
                G->P[k].g, G->P[k].pe.n, G->q, G->P[k].e);
        }
        v = nmod_inv(qpe % pe.n, pe);
        /* no overflow since v * qpe < q */
        G->generators[k] = (1 + (G->P[k].g-1) * v * qpe) % G->q;
    }
}