pqc/external/flint-2.4.3/qadic/doc/qadic.txt
2014-05-24 23:16:06 +02:00

621 lines
22 KiB
Plaintext

/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011, 2012, 2013 Sebastian Pancratz
******************************************************************************/
*******************************************************************************
Data structures
We represent an element of the extension
$\mathbf{Q}_q \cong \mathbf{Q}_p[X] / (f(X))$ as
a polynomial in $\mathbf{Q}_p[X]$ of degree less
than $\deg(f)$.
As such, \code{qadic_struct} and \code{qadic_t} are
typedef'ed as \code{padic_poly_struct} and \code{padic_poly_t}.
*******************************************************************************
*******************************************************************************
Context
We represent an unramified extension of $\mathbf{Q}_p$
via $\mathbf{Q}_q \cong \mathbf{Q}_p[X] / (f(X))$,
where $f \in \mathbf{Q}_p[X]$ is a monic, irreducible
polynomial which we assume to actually be in $\mathbf{Z}[X]$.
The first field in the context structure is a $p$-adic
context struct \code{pctx}, which contains data about
the prime~$p$, precomputed powers, the printing mode etc.
The polynomial $f$ is represented as a sparse polynomial
using two arrays $j$ and $a$ of length \code{len}, where
$f(X) = \sum_{i} a_{i} X^{j_{i}}$. We also assume that
the array~$j$ is sorted in ascending order.
We choose this data structure to improve reduction
modulo $f(X)$ in $\mathbf{Q}_p[X]$, assuming a sparse
polynomial $f(X)$ is chosen.
The field \code{var} contains the name of a generator
of the extension, which is used when printing the
elements.
*******************************************************************************
void qadic_ctx_init_conway(qadic_ctx_t ctx,
const fmpz_t p, slong d, slong min, slong max,
const char *var, enum padic_print_mode mode)
Initialises the context \code{ctx} with prime $p$, extension degree $d$,
variable name \code{var} and printing mode \code{mode}.
Stores powers of $p$ with exponents between \code{min} (inclusive) and
\code{max} exclusive. Assumes that \code{min} is at most \code{max}.
Assumes that $p$ is a prime.
Assumes that the string \code{var} is a null-terminated string
of length at least one.
Assumes that the printing mode is one of \code{PADIC_TERSE},
\code{PADIC_SERIES}, or \code{PADIC_VAL_UNIT}.
This function also carries out some relevant precomputation for
arithmetic in $\mathbf{Q}_p / (p^N)$ such as powers of $p$ close
to $p^N$.
void qadic_ctx_clear(qadic_ctx_t ctx);
Clears all memory that has been allocated as part of the context.
slong qadic_ctx_degree(const qadic_ctx_t ctx)
Returns the extension degree.
static __inline__ void qadic_ctx_print(const qadic_ctx_t ctx)
Prints the data from the given context.
*******************************************************************************
Memory management
*******************************************************************************
void qadic_init(qadic_t rop)
Initialises the element \code{rop}, setting its value to~$0$.
void qadic_init2(qadic_t rop, slong prec)
Initialises the element \code{rop} with the given output precision,
setting the value to~$0$.
void qadic_clear(qadic_t rop)
Clears the element \code{rop}.
void _fmpz_poly_reduce(fmpz *R, slong lenR,
const fmpz *a, const slong *j, slong len)
Reduces a polynomial \code{(R, lenR)} modulo a sparse monic
polynomial $f(X) = \sum_{i} a_{i} X^{j_{i}}$ of degree at
least~$2$.
Assumes that the array $j$ of positive length \code{len} is
sorted in ascending order.
Allows zero-padding in \code{(R, lenR)}.
void _fmpz_mod_poly_reduce(fmpz *R, slong lenR,
const fmpz *a, const slong *j, slong len, const fmpz_t p)
Reduces a polynomial \code{(R, lenR)} modulo a sparse monic
polynomial $f(X) = \sum_{i} a_{i} X^{j_{i}}$ of degree at
least~$2$ in $\mathbf{Z}/(p)$, where $p$ is typically a prime
power.
Assumes that the array $j$ of positive length \code{len} is
sorted in ascending order.
Allows zero-padding in \code{(R, lenR)}.
void qadic_reduce(qadic_t rop, const qadic_ctx_t ctx)
Reduces \code{rop} modulo $f(X)$ and $p^N$.
*******************************************************************************
Properties
*******************************************************************************
slong qadic_val(const qadic_t op)
Returns the valuation of \code{op}.
slong qadic_prec(const qadic_t op)
Returns the precision of \code{op}.
*******************************************************************************
Randomisation
*******************************************************************************
void qadic_randtest(qadic_t rop, flint_rand_t state, const qadic_ctx_t ctx)
Generates a random element of $\mathbf{Q}_q$.
void qadic_randtest_not_zero(qadic_t rop, flint_rand_t state,
const qadic_ctx_t ctx)
Generates a random non-zero element of $\mathbf{Q}_q$.
void qadic_randtest_val(qadic_t rop, flint_rand_t state, slong v,
const qadic_ctx_t ctx)
Generates a random element of $\mathbf{Q}_q$ with prescribed
valuation \code{val}.
Note that if $v \geq N$ then the element is necessarily zero.
void qadic_randtest_int(qadic_t rop, flint_rand_t state, const qadic_ctx_t ctx)
Generates a random element of $\mathbf{Q}_q$ with non-negative valuation.
*******************************************************************************
Assignments and conversions
*******************************************************************************
void qadic_set(qadic_t rop, const qadic_t op)
Sets \code{rop} to \code{op}.
void qadic_zero(qadic_t rop)
Sets \code{rop} to zero.
void qadic_one(qadic_t rop, const qadic_ctx_t ctx)
Sets \code{rop} to one, reduced in the given context.
Note that if the precision $N$ is non-positive then \code{rop}
is actually set to zero.
void qadic_gen(qadic_t rop, const qadic_ctx_t ctx)
Sets \code{rop} to the generator $X$ for the extension
when $N > 0$, and zero otherwise. If the extension degree
is one, raises an abort signal.
void qadic_set_ui(qadic_t rop, ulong op, const qadic_ctx_t ctx)
Sets \code{rop} to the integer \code{op}, reduced in the
context.
int qadic_get_padic(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)
If the element \code{op} lies in $\mathbf{Q}_p$, sets \code{rop}
to its value and returns~$1$; otherwise, returns~$0$.
*******************************************************************************
Comparison
*******************************************************************************
int qadic_is_zero(const qadic_t op)
Returns whether \code{op} is equal to zero.
int qadic_is_one(const qadic_t op, const qadic_ctx_t ctx)
Returns whether \code{op} is equal to one in the given
context.
int qadic_equal(const qadic_t op1, const qadic_t op2)
Returns whether \code{op1} and \code{op2} are equal.
*******************************************************************************
Basic arithmetic
*******************************************************************************
void qadic_add(qadic_t rop, const qadic_t op1, const qadic_t op2,
const qadic_ctx_t ctx)
Sets \code{rop} to the sum of \code{op1} and \code{op2}.
Assumes that both \code{op1} and \code{op2} are reduced in the
given context and ensures that \code{rop} is, too.
void qadic_sub(qadic_t rop, const qadic_t op1, const qadic_t op2,
const qadic_ctx_t ctx)
Sets \code{rop} to the difference of \code{op1} and \code{op2}.
Assumes that both \code{op1} and \code{op2} are reduced in the
given context and ensures that \code{rop} is, too.
void qadic_neg(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)
Sets \code{rop} to the negative of \code{op}.
Assumes that \code{op} is reduced in the given context and
ensures that \code{rop} is, too.
void qadic_mul(qadic_t rop, const qadic_t op1, const qadic_t op2,
const qadic_ctx_t ctx)
Sets \code{rop} to the product of \code{op1} and \code{op2},
reducing the output in the given context.
void _qadic_inv(fmpz *rop, const fmpz *op, slong len,
const fmpz *a, const slong *j, slong lena,
const fmpz_t p, slong N)
Sets \code{(rop, d)} to the inverse of \code{(op, len)}
modulo $f(X)$ given by \code{(a,j,lena)} and $p^N$.
Assumes that \code{(op,len)} has valuation~$0$, that is,
that it represents a $p$-adic unit.
Assumes that \code{len} is at most $d$.
Does not support aliasing.
void qadic_inv(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)
Sets \code{rop} to the inverse of \code{op}, reduced in the given context.
void _qadic_pow(fmpz *rop, const fmpz *op, slong len, const fmpz_t e,
const fmpz *a, const slong *j, slong lena,
const fmpz_t p)
Sets \code{(rop, 2*d-1)} to \code{(op,len)} raised to the power~$e$,
reduced modulo $f(X)$ given by \code{(a, j, lena)} and $p$, which
is expected to be a prime power.
Assumes that $e \geq 0$ and that \code{len} is positive and at most~$d$.
Although we require that \code{rop} provides space for
$2d - 1$ coefficients, the output will be reduces modulo
$f(X)$, which is a polynomial of degree~$d$.
Does not support aliasing.
void qadic_pow(qadic_t rop, const qadic_t op, const fmpz_t e,
const qadic_ctx_t ctx)
Sets \code{rop} the \code{op} raised to the power~$e$.
Currently assumes that $e \geq 0$.
Note that for any input \code{op}, \code{rop} is set to one in the
given context whenever $e = 0$.
*******************************************************************************
Special functions
*******************************************************************************
void _qadic_exp_rectangular(fmpz *rop, const fmpz *op, slong v, slong len,
const fmpz *a, const slong *j, slong lena,
const fmpz_t p, slong N, const fmpz_t pN)
Sets \code{(rop, 2*d - 1)} to the exponential of \code{(op, v, len)}
reduced modulo $p^N$, assuming that the series converges.
Assumes that \code{(op, v, len)} is non-zero.
Does not support aliasing.
int qadic_exp_rectangular(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)
Returns whether the exponential series converges at \code{op}
and sets \code{rop} to its value reduced modulo in the given
context.
void _qadic_exp_balanced(fmpz *rop, const fmpz *x, slong v, slong len,
const fmpz *a, const slong *j, slong lena,
const fmpz_t p, slong N, const fmpz_t pN)
Sets \code{(rop, d)} to the exponential of \code{(op, v, len)}
reduced modulo $p^N$, assuming that the series converges.
Assumes that \code{len} is in $[1,d)$ but supports zero padding,
including the special case when \code{(op, len)} is zero.
Supports aliasing between \code{rop} and \code{op}.
int qadic_exp_balanced(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)
Returns whether the exponential series converges at \code{op}
and sets \code{rop} to its value reduced modulo in the given
context.
void _qadic_exp(fmpz *rop, const fmpz *op, slong v, slong len,
const fmpz *a, const slong *j, slong lena,
const fmpz_t p, slong N)
Sets \code{(rop, 2*d - 1)} to the exponential of \code{(op, v, len)}
reduced modulo $p^N$, assuming that the series converges.
Assumes that \code{(op, v, len)} is non-zero.
Does not support aliasing.
int qadic_exp(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)
Returns whether the exponential series converges at \code{op}
and sets \code{rop} to its value reduced modulo in the given
context.
The exponential series converges if the valuation of \code{op}
is at least~$2$ or $1$ when $p$ is even or odd, respectively.
void _qadic_log_rectangular(fmpz *z, const fmpz *y, slong v, slong len,
const fmpz *a, const slong *j, slong lena,
const fmpz_t p, slong N, const fmpz_t pN)
Computes
\begin{equation*}
z = - \sum_{i = 1}^{\infty} \frac{y^i}{i} \pmod{p^N}.
\end{equation*}
Note that this can be used to compute the $p$-adic logarithm
via the equation
\begin{align*}
\log(x) & = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i} \\
& = - \sum_{i=1}^{\infty} \frac{(1-x)^i}{i}.
\end{align*}
Assumes that $y = 1 - x$ is non-zero and that $v = \ord_p(y)$
is at least $1$ when $p$ is odd and at least $2$ when $p = 2$
so that the series converges.
Assumes that $y$ is reduced modulo $p^N$.
Assumes that $v < N$, and in particular $N \geq 2$.
Supports aliasing between $y$ and $z$.
int qadic_log_rectangular(qadic_t rop, const qadic_t op, const padic_ctx_t ctx)
Returns whether the $p$-adic logarithm function converges at
\code{op}, and if so sets \code{rop} to its value.
void _qadic_log_balanced(fmpz *z, const fmpz *y, slong len,
const fmpz *a, const slong *j, slong lena,
const fmpz_t p, slong N, const fmpz_t pN)
Computes $(z, d)$ as
\begin{equation*}
z = - \sum_{i = 1}^{\infty} \frac{y^i}{i} \pmod{p^N}.
\end{equation*}
Assumes that $v = \ord_p(y)$ is at least $1$ when $p$ is odd and
at least $2$ when $p = 2$ so that the series converges.
Supports aliasing between $z$ and $y$.
int qadic_log_balanced(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)
Returns whether the $p$-adic logarithm function converges at
\code{op}, and if so sets \code{rop} to its value.
void _qadic_log(fmpz *z, const fmpz *y, slong v, slong len,
const fmpz *a, const slong *j, slong lena,
const fmpz_t p, slong N, const fmpz_t pN)
Computes $(z, d)$ as
\begin{equation*}
z = - \sum_{i = 1}^{\infty} \frac{y^i}{i} \pmod{p^N}.
\end{equation*}
Note that this can be used to compute the $p$-adic logarithm
via the equation
\begin{align*}
\log(x) & = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i} \\
& = - \sum_{i=1}^{\infty} \frac{(1-x)^i}{i}.
\end{align*}
Assumes that $y = 1 - x$ is non-zero and that $v = \ord_p(y)$
is at least $1$ when $p$ is odd and at least $2$ when $p = 2$
so that the series converges.
Assumes that $(y, d)$ is reduced modulo $p^N$.
Assumes that $v < N$, and hence in particular $N \geq 2$.
Supports aliasing between $z$ and $y$.
int qadic_log(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)
Returns whether the $p$-adic logarithm function converges at
\code{op}, and if so sets \code{rop} to its value.
The $p$-adic logarithm function is defined by the usual series
\begin{equation*}
\log_p(x) = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i}
\end{equation*}
but this only converges when $\ord_p(x)$ is at least $2$ or $1$
when $p = 2$ or $p > 2$, respectively.
void _qadic_frobenius_a(fmpz *rop, slong e,
const fmpz *a, const slong *j, slong lena,
const fmpz_t p, slong N)
Computes $\sigma^e(X) \bmod{p^N}$ where $X$ is such that
$\mathbf{Q}_q \cong \mathbf{Q}_p[X]/(f(X))$.
Assumes that the precision $N$ is at least~$2$ and that the
extension is non-trivial, i.e.\ $d \geq 2$.
Assumes that $0 < e < d$.
Sets \code{(rop, 2*d-1)}, although the actual length of the
output will be at most~$d$.
void _qadic_frobenius(fmpz *rop, const fmpz *op, slong len, slong e,
const fmpz *a, const slong *j, slong lena,
const fmpz_t p, slong N)
Sets \code{(rop, 2*d-1)} to $\Sigma$ evaluated at \code{(op, len)}.
Assumes that \code{len} is positive but at most~$d$.
Assumes that $0 < e < d$.
Does not support aliasing.
void qadic_frobenius(qadic_t rop, const qadic_t op, slong e, const qadic_ctx_t ctx)
Evaluates the homomorphism $\Sigma^e$ at \code{op}.
Recall that $\mathbf{Q}_q / \mathbf{Q}_p$ is Galois with Galois group
$\langle \Sigma \rangle \cong \langle \sigma \rangle$, which is also
isomorphic to $\mathbf{Z}/d\mathbf{Z}$, where
$\sigma \in \Gal(\mathbf{F}_q/\mathbf{F}_p)$ is the Frobenius element
$\sigma \colon x \mapsto x^p$ and $\Sigma$ is its lift to
$\Gal(\mathbf{Q}_q/\mathbf{Q}_p)$.
This functionality is implemented as \code{GaloisImage()} in Magma.
void _qadic_teichmuller(fmpz *rop, const fmpz *op, slong len,
const fmpz *a, const slong *j, slong lena,
const fmpz_t p, slong N)
Sets \code{(rop, d)} to the Teichm\"uller lift of \code{(op, len)}
modulo~$p^N$.
Does not support aliasing.
void qadic_teichmuller(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx)
Sets \code{rop} to the Teichm\"uller lift of \code{op} to the
precision given in the context.
For a unit \code{op}, this is the unique $(q-1)$th root of unity
which is congruent to \code{op} modulo~$p$.
Sets \code{rop} to zero if \code{op} is zero in the given context.
Raises an exception if the valuation of \code{op} is negative.
void _qadic_trace(fmpz_t rop, const fmpz *op, slong len,
const fmpz *a, const slong *j, slong lena, const fmpz_t pN)
void qadic_trace(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)
Sets \code{rop} to the trace of \code{op}.
For an element $a \in \mathbf{Q}_q$, multiplication by $a$ defines
a $\mathbf{Q}_p$-linear map on $\mathbf{Q}_q$. We define the trace
of $a$ as the trace of this map. Equivalently, if $\Sigma$ generates
$\Gal(\mathbf{Q}_q / \mathbf{Q}_p)$ then the trace of $a$ is equal to
$\sum_{i=0}^{d-1} \Sigma^i (a)$.
void _qadic_norm(fmpz_t rop, const fmpz *op, slong len,
const fmpz *a, const slong *j, slong lena,
const fmpz_t p, slong N)
Sets \code{rop} to the norm of the element \code{(op,len)}
in $\mathbf{Z}_q$ to precision $N$, where \code{len} is at
least one.
The result will be reduced modulo $p^N$.
Note that whenever \code{(op,len)} is a unit, so is its norm.
Thus, the output \code{rop} of this function will typically
not have to be canonicalised or reduced by the caller.
void qadic_norm(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)
Computes the norm of \code{op} to the given precision.
Algorithm selection is automatic depending on the input.
void qadic_norm_analytic(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)
Whenever \code{op} has valuation greater than $(p-1)^{-1}$, this
routine computes its norm \code{rop} via
\begin{equation*}
\Norm (x) = \exp \Bigl( \bigl( \Trace \log (x) \bigr) \Bigr).
\end{equation*}
In the special case that \code{op} lies in $\mathbf{Q}_p$, returns
its norm as $\Norm(x) = x^d$, where $d$ is the extension degree.
Otherwise, raises an \code{abort} signal.
The complexity of this implementation is quasi-linear in $d$ and $N$,
and polynomial in $\log p$.
void qadic_norm_resultant(padic_t rop, const qadic_t op, const qadic_ctx_t ctx)
Sets \code{rop} to the norm of \code{op}, using the formula
\begin{equation*}
\Norm(x) = \ell(f)^{-\deg(a)} \Res(f(X), a(X)),
\end{equation*}
where $\mathbf{Q}_q \cong \mathbf{Q}_p[X] / (f(X))$, $\ell(f)$ is the
leading coefficient of $f(X)$, and $a(X) \in mathbf{Q}_p[X]$ denotes
the same polynomial as $x$.
The complexity of the current implementation is given by
$\mathcal{O}(d^4 M(N \log p))$, where $M(n)$ denotes the
complexity of multiplying to $n$-bit integers.
*******************************************************************************
Output
*******************************************************************************
int qadic_fprint_pretty(FILE *file, const qadic_t op, const qadic_ctx_t ctx)
Prints a pretty representation of \code{op} to \code{file}.
In the current implementation, always returns~$1$. The return code is
part of the function's signature to allow for a later implementation to
return the number of characters printed or a non-positive error code.
int qadic_print_pretty(const qadic_t op, const qadic_ctx_t ctx)
Prints a pretty representation of \code{op} to \code{stdout}.
In the current implementation, always returns~$1$. The return code is
part of the function's signature to allow for a later implementation to
return the number of characters printed or a non-positive error code.