1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
Copyright (C) 2012 Sebastian Pancratz
Copyright (C) 2013 Mike Hansen
Copyright (C) 2017 Claus Fieker
This file is part of FLINT.
FLINT is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. See <https://www.gnu.org/licenses/>.
*/
#include "ulong_extras.h"
#include "nmod_poly.h"
#include "fmpz.h"
#include "fq_nmod.h"
/*
This computes the norm on $\mathbf{F}_q$.
*/
void _fq_nmod_norm(fmpz_t rop2, const ulong *op, slong len,
const fq_nmod_ctx_t ctx)
{
const slong d = fq_nmod_ctx_degree(ctx);
ulong rop;
if (d == 1)
{
rop = op[0];
}
else if (len == 1) /* element scalar */
{
rop = n_powmod2_ui_preinv(op[0], d, ctx->mod.n, ctx->mod.ninv);
}
else
{
rop = _nmod_poly_resultant(ctx->modulus->coeffs, ctx->modulus->length,
op, len, ctx->mod);
/*
XXX: This part of the code is currently untested as the Conway
polynomials used for the extension Fq/Fp are monic.
TODO: make polynomial monic!!!
reading the source, a[] is monic, modulus is not. Why????
*/
if (ctx->modulus->coeffs[d] != WORD(1))
{
ulong f;
f = n_powmod2_ui_preinv(ctx->modulus->coeffs[d], len - 1, ctx->mod.n, ctx->mod.ninv);
f = n_invmod(f, ctx->mod.n);
rop = n_mulmod2_preinv(f, rop, ctx->mod.n, ctx->mod.ninv);
}
}
fmpz_set_ui(rop2, rop);
}
void fq_nmod_norm(fmpz_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx)
{
if (fq_nmod_is_zero(op, ctx))
{
fmpz_zero(rop);
return;
}
else
{
_fq_nmod_norm(rop, op->coeffs, op->length, ctx);
}
}