877 lines
30 KiB
C
877 lines
30 KiB
C
|
|
/** @file
|
|||
|
|
*
|
|||
|
|
* @authors Luca De Feo, Sina Schaeffler
|
|||
|
|
*
|
|||
|
|
* @brief Declarations for quaternion algebra operations
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
#ifndef QUATERNION_H
|
|||
|
|
#define QUATERNION_H
|
|||
|
|
|
|||
|
|
//#include <rng.h>
|
|||
|
|
#include <intbig.h>
|
|||
|
|
#include <assert.h>
|
|||
|
|
|
|||
|
|
|
|||
|
|
#define QUATERNION_lideal_generator_search_bound 1024
|
|||
|
|
|
|||
|
|
/** @defgroup quat_quat Quaternion algebra
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @defgroup quat_vec_t Types for integer vectors and matrices
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @brief Type for vectors of 4 integers
|
|||
|
|
*
|
|||
|
|
* @typedef ibz_vec_4_t
|
|||
|
|
*
|
|||
|
|
* Represented as a vector of 4 ibz_t (big integer) elements
|
|||
|
|
*/
|
|||
|
|
typedef ibz_t ibz_vec_4_t[4];
|
|||
|
|
|
|||
|
|
/** @brief Type for vectors of 5 integers
|
|||
|
|
*
|
|||
|
|
* @typedef ibz_vec_5_t
|
|||
|
|
*
|
|||
|
|
* Represented as a vector of 5 ibz_t (big integer) elements
|
|||
|
|
*/
|
|||
|
|
typedef ibz_t ibz_vec_5_t[5];
|
|||
|
|
|
|||
|
|
/** @brief Type for 2 by 2 matrices of integers
|
|||
|
|
*
|
|||
|
|
* @typedef ibz_mat_2x2_t
|
|||
|
|
*
|
|||
|
|
* Represented as a matrix of 2 vectors of 2 ibz_t (big integer) elements
|
|||
|
|
*/
|
|||
|
|
typedef ibz_t ibz_mat_2x2_t[2][2];
|
|||
|
|
|
|||
|
|
/** @brief Type for 4 by 4 matrices of integers
|
|||
|
|
*
|
|||
|
|
* @typedef ibz_mat_4x4_t
|
|||
|
|
*
|
|||
|
|
* Represented as a matrix of 4 vectors of 4 ibz_t (big integer) elements
|
|||
|
|
*/
|
|||
|
|
typedef ibz_t ibz_mat_4x4_t[4][4];
|
|||
|
|
|
|||
|
|
/** @brief Type for 4 by 5 matrices of integers
|
|||
|
|
*
|
|||
|
|
* @typedef ibz_mat_4x5_t
|
|||
|
|
*
|
|||
|
|
* Represented as a matrix of 4 vectors of 5 ibz_t (big integer) elements
|
|||
|
|
*/
|
|||
|
|
typedef ibz_t ibz_mat_4x5_t[4][5];
|
|||
|
|
|
|||
|
|
/** @brief Type for 4 by 8 matrices of integers
|
|||
|
|
*
|
|||
|
|
* @typedef ibz_mat_4x8_t
|
|||
|
|
*
|
|||
|
|
* Consists in and 4 by 8 matrix of ibz_t (big integers)
|
|||
|
|
*/
|
|||
|
|
typedef ibz_t ibz_mat_4x8_t[4][8];
|
|||
|
|
/**
|
|||
|
|
* @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @defgroup quat_quat_t Types for quaternion algebras
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @brief Type for quaternion algebras
|
|||
|
|
*
|
|||
|
|
* @typedef quat_alg_t
|
|||
|
|
*
|
|||
|
|
* @struct quat_alg
|
|||
|
|
*
|
|||
|
|
* The quaternion algebra ramified at p = 3 mod 4 and ∞.
|
|||
|
|
*/
|
|||
|
|
typedef struct quat_alg {
|
|||
|
|
ibz_t p; ///< Prime number, must be = 3 mod 4.
|
|||
|
|
ibz_mat_4x4_t gram; ///< Gram matrix of the norm form
|
|||
|
|
} quat_alg_t;
|
|||
|
|
|
|||
|
|
/** @brief Type for integer coordinates in a basis
|
|||
|
|
*
|
|||
|
|
* @typedef quat_alg_coord_t
|
|||
|
|
*
|
|||
|
|
* Represented as a vector of 4 ibz_t (big integer) elements
|
|||
|
|
*/
|
|||
|
|
typedef ibz_vec_4_t quat_alg_coord_t;
|
|||
|
|
|
|||
|
|
/** @brief Type for quaternion algebra elements
|
|||
|
|
*
|
|||
|
|
* @typedef quat_alg_elem_t
|
|||
|
|
*
|
|||
|
|
* @struct quat_alg_elem
|
|||
|
|
*
|
|||
|
|
* Represented as a array *coord* of 4 ibz_t integers and a common ibz_t denominator *denom*.
|
|||
|
|
*
|
|||
|
|
* The representation is not necessarily normalized, that is, gcd(denom, content(coord)) might not be 1.
|
|||
|
|
* For getting a normalized representation, use the quat_alg_normalize function
|
|||
|
|
*
|
|||
|
|
* The elements are always represented in basis (1,i,j,ij) of the quaternion algebra, with i^2=-1 and j^2 = -p
|
|||
|
|
*/
|
|||
|
|
typedef struct quat_alg_elem {
|
|||
|
|
ibz_t denom; ///< Denominator by which all coordinates are divided (big integer, must not be 0)
|
|||
|
|
quat_alg_coord_t coord; ///< Numerators of the 4 coordinates of the quaternion algebra element in basis (1,i,j,ij)
|
|||
|
|
} quat_alg_elem_t;
|
|||
|
|
|
|||
|
|
/** @brief Type for lattices in dimension 4
|
|||
|
|
*
|
|||
|
|
* @typedef quat_lattice_t
|
|||
|
|
*
|
|||
|
|
* @struct quat_lattice
|
|||
|
|
*
|
|||
|
|
* Represented as a rational (`frac`) times an integreal lattice (`basis`)
|
|||
|
|
*
|
|||
|
|
* The basis is in hermite normal form, and its columns divided by its denominator are elements of the quaternion algebra, represented in basis (1,i,j,ij) where i^2 = -1, j^2 = -p.
|
|||
|
|
*
|
|||
|
|
* All lattices must have full rank (4)
|
|||
|
|
*/
|
|||
|
|
typedef struct quat_lattice {
|
|||
|
|
ibz_t denom; ///< Denominator by which the basis is divided (big integer, must not be 0)
|
|||
|
|
ibz_mat_4x4_t basis; ///< Integer basis of the lattice in hermite normal form (its columns divided by denom are algebra elements in the usual basis)
|
|||
|
|
} quat_lattice_t;
|
|||
|
|
|
|||
|
|
/** @brief Type for quaternion orders
|
|||
|
|
*
|
|||
|
|
* @typedef quat_order_t
|
|||
|
|
*
|
|||
|
|
* Internally represented as a quat_lattice_t.
|
|||
|
|
*
|
|||
|
|
* That means that the basis is in hermite normal form, and its columns divided by its denominator are elements of the quaternion algebra, represented in basis (1,i,j,ij) where i^2 = -1, j^2 = -p.
|
|||
|
|
*/
|
|||
|
|
typedef quat_lattice_t quat_order_t;
|
|||
|
|
|
|||
|
|
/** @brief Type for left ideals in quaternion algebras
|
|||
|
|
*
|
|||
|
|
* @typedef quat_left_ideal_t
|
|||
|
|
*
|
|||
|
|
* @struct quat_left_ideal
|
|||
|
|
*
|
|||
|
|
* The basis of the lattice representing it is in hermite normal form, and its columns divided by its denominator are elements of the quaternion algebra, represented in basis (1,i,j,ij) where i^2 = -1, j^2 = -p.
|
|||
|
|
*/
|
|||
|
|
typedef struct quat_left_ideal {
|
|||
|
|
quat_lattice_t lattice; ///< lattice representing the ideal
|
|||
|
|
ibz_t norm; ///< norm of the lattice
|
|||
|
|
const quat_order_t* parent_order; ///< should be a maximal ideal
|
|||
|
|
} quat_left_ideal_t;
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @brief Type for extremal maximal orders
|
|||
|
|
*
|
|||
|
|
* @typedef quat_p_extremal_maximal_order_t
|
|||
|
|
*
|
|||
|
|
* @struct quat_p_extremal_maximal_order
|
|||
|
|
*
|
|||
|
|
* The basis of the order representing it is in hermite normal form, and its columns divid
|
|||
|
|
ed by its denominator are elements of the quaternion algebra, represented in basis (1,i,j,
|
|||
|
|
ij) where i^2 = -q, j^2 = -p.
|
|||
|
|
*/
|
|||
|
|
typedef struct quat_p_extremal_maximal_order {
|
|||
|
|
quat_order_t order; ///< the order represented as a lattice
|
|||
|
|
quat_alg_elem_t i; ///< the element of small discriminant
|
|||
|
|
quat_alg_elem_t j; ///< the element of norm p orthogonal to i
|
|||
|
|
int64_t q; ///< the absolute value of sqrt of i
|
|||
|
|
} quat_p_extremal_maximal_order_t;
|
|||
|
|
|
|||
|
|
/*************************** Functions *****************************/
|
|||
|
|
|
|||
|
|
|
|||
|
|
/** @defgroup quat_c Constructors and Destructors
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
void quat_alg_init_set(quat_alg_t *alg, const ibz_t *p);
|
|||
|
|
void quat_alg_finalize(quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
void quat_alg_elem_init(quat_alg_elem_t *elem);
|
|||
|
|
void quat_alg_elem_finalize(quat_alg_elem_t *elem);
|
|||
|
|
|
|||
|
|
void quat_alg_coord_init(quat_alg_coord_t *coord);
|
|||
|
|
void quat_alg_coord_finalize(quat_alg_coord_t *coord);
|
|||
|
|
|
|||
|
|
void ibz_vec_4_init(ibz_vec_4_t *vec);
|
|||
|
|
void ibz_vec_4_finalize(ibz_vec_4_t *vec);
|
|||
|
|
|
|||
|
|
void ibz_vec_5_init(ibz_vec_5_t *vec);
|
|||
|
|
void ibz_vec_5_finalize(ibz_vec_5_t *vec);
|
|||
|
|
|
|||
|
|
void ibz_mat_2x2_init(ibz_mat_2x2_t *mat);
|
|||
|
|
void ibz_mat_2x2_finalize(ibz_mat_2x2_t *mat);
|
|||
|
|
|
|||
|
|
void ibz_mat_4x4_init(ibz_mat_4x4_t *mat);
|
|||
|
|
void ibz_mat_4x4_finalize(ibz_mat_4x4_t *mat);
|
|||
|
|
|
|||
|
|
void ibz_mat_4x5_init(ibz_mat_4x5_t *mat);
|
|||
|
|
void ibz_mat_4x5_finalize(ibz_mat_4x5_t *mat);
|
|||
|
|
|
|||
|
|
void ibz_mat_4x8_init(ibz_mat_4x8_t *mat);
|
|||
|
|
void ibz_mat_4x8_finalize(ibz_mat_4x8_t *mat);
|
|||
|
|
|
|||
|
|
/** @brief initiazlize matrix with arbitrary dimensions
|
|||
|
|
*/
|
|||
|
|
void ibz_mat_init(int rows, int cols, ibz_t mat[rows][cols]);
|
|||
|
|
/** @brief finalize matrix with arbitrary dimensions
|
|||
|
|
*/
|
|||
|
|
void ibz_mat_finalize(int rows, int cols, ibz_t mat[rows][cols]);
|
|||
|
|
|
|||
|
|
void quat_lattice_init(quat_lattice_t *lat);
|
|||
|
|
void quat_lattice_finalize(quat_lattice_t *lat);
|
|||
|
|
|
|||
|
|
void quat_order_init(quat_order_t *order);
|
|||
|
|
void quat_order_finalize(quat_order_t *order);
|
|||
|
|
|
|||
|
|
void quat_left_ideal_init(quat_left_ideal_t *lideal);
|
|||
|
|
void quat_left_ideal_finalize(quat_left_ideal_t *lideal);
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
/** @defgroup quat_printers Print functions for types from the quaternion module
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
void ibz_mat_2x2_print(const ibz_mat_2x2_t *mat);
|
|||
|
|
void ibz_mat_4x4_print(const ibz_mat_4x4_t *mat);
|
|||
|
|
void ibz_mat_4x5_print(const ibz_mat_4x5_t *mat);
|
|||
|
|
void ibz_mat_4x8_print(const ibz_mat_4x8_t *mat);
|
|||
|
|
void ibz_mat_print(int rows, int cols, const ibz_t mat[rows][cols]);
|
|||
|
|
void ibz_vec_2_print(const ibz_vec_2_t *vec);
|
|||
|
|
void ibz_vec_4_print(const ibz_vec_4_t *vec);
|
|||
|
|
void ibz_vec_5_print(const ibz_vec_5_t *vec);
|
|||
|
|
|
|||
|
|
|
|||
|
|
void quat_lattice_print(const quat_lattice_t *lat);
|
|||
|
|
void quat_alg_print(const quat_alg_t *alg);
|
|||
|
|
void quat_alg_elem_print(const quat_alg_elem_t *elem);
|
|||
|
|
void quat_alg_coord_print(const quat_alg_coord_t *coord);
|
|||
|
|
void quat_order_print(const quat_order_t *order);
|
|||
|
|
void quat_left_ideal_print(const quat_left_ideal_t *lideal);
|
|||
|
|
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @defgroup quat_int Integer functions for quaternion algebra
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @defgroup quat_int_mat Integer matrix and vector functions
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @brief mat*vec in dimension 2 for integers
|
|||
|
|
*
|
|||
|
|
* @param res Output vector
|
|||
|
|
* @param mat Input vector
|
|||
|
|
* @param vec Input vector
|
|||
|
|
*/
|
|||
|
|
void ibz_mat_2x2_eval(ibz_vec_2_t *res, const ibz_mat_2x2_t *mat, const ibz_vec_2_t *vec);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief a*b for 2x2 integer matrices modulo m
|
|||
|
|
*
|
|||
|
|
* @param prod Output matrix
|
|||
|
|
* @param mat_a Input matrix
|
|||
|
|
* @param mat_b Input matrix
|
|||
|
|
* @param m Integer modulo
|
|||
|
|
*/
|
|||
|
|
void ibz_2x2_mul_mod(ibz_mat_2x2_t *prod, const ibz_mat_2x2_t *mat_a, const ibz_mat_2x2_t *mat_b, const ibz_t *m);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Inverse of 2x2 integer matrices modulo m
|
|||
|
|
*
|
|||
|
|
* @param inv Output matrix
|
|||
|
|
* @param mat Input matrix
|
|||
|
|
* @param m Integer modulo
|
|||
|
|
* @return 1 if inverse exists 0 otherwise
|
|||
|
|
*/
|
|||
|
|
int ibz_2x2_inv_mod(ibz_mat_2x2_t *inv, const ibz_mat_2x2_t *mat, const ibz_t *m);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief mat*vec
|
|||
|
|
*
|
|||
|
|
*
|
|||
|
|
* @param res Output: coordinate vector
|
|||
|
|
* @param mat Integer 4x4 matrix
|
|||
|
|
* @param vec Integer vector (coordinate vector)
|
|||
|
|
*
|
|||
|
|
* Multiplies 4x4 integer matrix mat by a 4-integers vector vec
|
|||
|
|
*/
|
|||
|
|
void ibz_mat_4x4_eval(ibz_vec_4_t *res, const ibz_mat_4x4_t *mat, const ibz_vec_4_t *vec);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Computes modulo p the left kernel of mat where p is prime
|
|||
|
|
*
|
|||
|
|
* Algorithm used is the one at number 2.3.1 in Henri Cohen's "A Course in Computational Algebraic Number Theory" (Springer Verlag, in series "Graduate texts in Mathematics") from 1993
|
|||
|
|
*
|
|||
|
|
* @param ker Output: a vector in kernel which is not 0 modulo p if exists, otherwise 0
|
|||
|
|
* @param mat A 4×5 matrix
|
|||
|
|
* @param p Integer modulo which the kernel computation is done, must be prime
|
|||
|
|
* @return 1 if a unique such vector was found, 0 otherwise
|
|||
|
|
*
|
|||
|
|
*/
|
|||
|
|
int ibz_4x5_right_ker_mod_prime(ibz_vec_5_t *ker, const ibz_mat_4x5_t *mat, const ibz_t *p);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Computes modulo p the left kernel of mat where p is prime
|
|||
|
|
*
|
|||
|
|
* Algorithm used is the one at number 2.3.1 in Henri Cohen's "A Course in Computational Algebraic Number Theory" (Springer Verlag, in series "Graduate texts in Mathematics") from 1993
|
|||
|
|
*
|
|||
|
|
* @param ker Output: a vector in kernel which is not 0 modulo p if exists, otherwise 0
|
|||
|
|
* @param mat A 4×4 matrix
|
|||
|
|
* @param p Integer modulo which the kernel computation is done, must be prime
|
|||
|
|
* @return 1 if a unique such vector was found, 0 otherwise
|
|||
|
|
*
|
|||
|
|
*/
|
|||
|
|
int ibz_4x4_right_ker_mod_prime(ibz_vec_4_t *ker, const ibz_mat_4x4_t *mat, const ibz_t *p);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Computes the right kernel of mat modulo 2^exp
|
|||
|
|
*
|
|||
|
|
* @param ker Output: a vector in kernel which is not 0 modulo 2, if it exists, otherwise 0
|
|||
|
|
* @param mat A 4×4 matrix
|
|||
|
|
* @param exp exponent defining the modulus
|
|||
|
|
* @return 1 if a unique such vector was found, 0 otherwise
|
|||
|
|
*
|
|||
|
|
*/
|
|||
|
|
int ibz_4x4_right_ker_mod_power_of_2(ibz_vec_4_t *ker, const ibz_mat_4x4_t *mat, unsigned short exp);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief content of a 4-vector of integers
|
|||
|
|
*
|
|||
|
|
* The content is the GCD of all entries.
|
|||
|
|
*
|
|||
|
|
* @param v A 4-vector of integers
|
|||
|
|
* @param content Output: the resulting gcd
|
|||
|
|
*/
|
|||
|
|
static inline void ibz_content(ibz_t *content, const ibz_vec_4_t *v) {
|
|||
|
|
ibz_gcd(content, &((*v)[0]), &((*v)[1]));
|
|||
|
|
ibz_gcd(content, &((*v)[2]), content);
|
|||
|
|
ibz_gcd(content, &((*v)[3]), content);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
/** @defgroup quat_integer Integer functions for quaternion algebra
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Find integers x and y such that x^2 + n*y^2 = p
|
|||
|
|
*
|
|||
|
|
* Uses Cornacchia's algorithm, should be used only for prime p
|
|||
|
|
*
|
|||
|
|
* @param x Output
|
|||
|
|
* @param y Output
|
|||
|
|
* @param n first parameter defining the equation
|
|||
|
|
* @param p seond parameter defining the equation, must be prime
|
|||
|
|
* @return 1 if success, 0 otherwise
|
|||
|
|
*/
|
|||
|
|
int ibz_cornacchia_prime(ibz_t *x, ibz_t *y, const ibz_t *n , const ibz_t *p);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Solving cornacchia to find x² + n y³ = 2^exp_adjust * p in the special case of n=3 mod 4
|
|||
|
|
*
|
|||
|
|
* This function sometimes fails to find a solution even if one exists and all parameters are as specified.
|
|||
|
|
*
|
|||
|
|
* @param x Output: an integer
|
|||
|
|
* @param y Output: an integer
|
|||
|
|
* @param n an integer
|
|||
|
|
* @param p a prime integer
|
|||
|
|
* @param exp_adjust an exponent, must be > 0
|
|||
|
|
* @returns 1 if success, 0 if failure to find a solution
|
|||
|
|
*/
|
|||
|
|
int ibz_cornacchia_special_prime(ibz_t *x, ibz_t *y, const ibz_t *n, const ibz_t *p, const int exp_adjust);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Find x and y such that x^2 + y^2 = n
|
|||
|
|
*
|
|||
|
|
* Uses "extended" version of Cornacchia's algorithm which also allows to solve x^2 + y^2 = n for some composite numbers.
|
|||
|
|
* This uses a prime factor decomposition of n via trial division for primes in the list, computes solutions for n's prime factors
|
|||
|
|
* and then uses complex multiplication. Since (x+iz)(x-iy) = x^2 + y^2,
|
|||
|
|
* so a solution xp,yp for p and xq,yq for q give a solution for pq by computing (xp+iyp)*(xq+iyq).
|
|||
|
|
*
|
|||
|
|
* @param x Output
|
|||
|
|
* @param y Output
|
|||
|
|
* @param n parameter defining the equation. To get an output if one exists, only 1 of its prime factors can exceed the largest prime in prime_list
|
|||
|
|
* @param prime_list list of consecutive primes starting from 2
|
|||
|
|
* @param prime_list_length number of elements of prime_list. Cans be smaller than that number, in which case only the beginning of the list is used.
|
|||
|
|
* @param primality_test_iterations number of Miller-Rabin iterations to verify primality before trying to compute a square root of 1 modulo the remaining number once all small primes were factored out
|
|||
|
|
* @param bad_primes_prod Assumed to be a product of small primes which are 3 mod 4. Used only to accelerate failure in case its gcd with n is not 1. Can be NULL
|
|||
|
|
* @return 1 if success, 0 otherwise
|
|||
|
|
*/
|
|||
|
|
int ibz_cornacchia_extended(ibz_t *x, ibz_t *y, const ibz_t *n, const short *prime_list, const int prime_list_length, short primality_test_iterations, const ibz_t *bad_primes_prod);
|
|||
|
|
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
/** @defgroup quat_qf Quadratic form functions
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Quadratic form evaluation
|
|||
|
|
*
|
|||
|
|
* qf and coord must be represented in the same basis.
|
|||
|
|
*
|
|||
|
|
* @param res Output: coordinate vector
|
|||
|
|
* @param qf Quadratic form (4x4 integer matrix)
|
|||
|
|
* @param coord Integer vector (coordinate vector)
|
|||
|
|
*/
|
|||
|
|
void quat_qf_eval(ibz_t *res, const ibz_mat_4x4_t *qf, const quat_alg_coord_t *coord);
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @defgroup quat_lat_2x2 Functions for lattices in dimension 2
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Find a lattice vector close to a target vector satisfying extra conditions.
|
|||
|
|
*
|
|||
|
|
* Given a target vector `target` = (x₀,y₀), enumerate vectors `v` = (x,y) in lattice `lat` with distance
|
|||
|
|
* (x₀ - x)² + `qf` (y₀ - y)² < 2^`dist_bound`. On each vector `condition(res, target - v, params)` is called: if it returns a
|
|||
|
|
* non-zero value, processing stops and the same value is returned; if it returns 0 processing continues
|
|||
|
|
* until `max_tries` vectors have been tried.
|
|||
|
|
*
|
|||
|
|
* The implementation will first reduce the basis by finding a short vector with algorithm 1.3.14 (Gauss) from Henri Cohen's "A Course in Computational Algebraic Number Theory" (Springer Verlag, in series "Graduate texts in Mathematics") from 1993.
|
|||
|
|
* Then a second one is added to this basis after reduction by projection on the first one.
|
|||
|
|
* A close vector is found using 2 projection as in https://cims.nyu.edu/~regev/teaching/lattices_fall_2004/ln/cvp.pdf (15.5.2023,16h15CEST) using the already reduced matrix
|
|||
|
|
* Finally, short vectors are enumerated below an enumeration bound set to (2 ^ dist_bound - (distance of target to close vector)).
|
|||
|
|
* Each short vector is added to the close vector, and then the distance to the target is measured. If it is below 2^dist_bound, it is tested for condition.
|
|||
|
|
* If coundition returns 1, the algorithm terminates and returns 1, otherwise it returns 0 when max_tries vectors have been tried
|
|||
|
|
*
|
|||
|
|
* The enumeration bound is an heuristic to avoid starting the search with vectors which will be too far from the target, since enumeration starts at the largest vectors.
|
|||
|
|
* It can in some cases lead to failures even though solutions do exist, an in other cases be insufficient to get a valid result in reasonable time.
|
|||
|
|
*
|
|||
|
|
* Enumeration uses algorithm 2.7.5 (Fincke-Pohst) from Henri Cohen's "A Course in Computational Algebraic Number Theory" (Springer Verlag, in series "Graduate texts in Mathematics") from 1993
|
|||
|
|
* Slightly adapted to work without rational numbers and their square roots
|
|||
|
|
* Therefore needing a test to make sure the bounds are respected, which is integrated in quat_dim2_lattice_bound_and_condition
|
|||
|
|
*
|
|||
|
|
* @param res Output: quaternion element returned by `condition`
|
|||
|
|
* @param lat_basis basis of an integral 2-dimensional lattice
|
|||
|
|
* @param target target vector for CVP
|
|||
|
|
* @param qf Small integer defining a quadratic form x² + qf y²
|
|||
|
|
* @param dist_bound Log of the maximum distance between `target` and the enumerated vectors
|
|||
|
|
* @param condition Filter the vectors of `lat` by passing them to `condition`. When it returns a non-zero value, the result is put into `res` and the processing stops.
|
|||
|
|
* @param params Extra parameters passed to `condition`. May be NULL.
|
|||
|
|
* @param max_tries Try at most `max_tries` vectors close to `target`
|
|||
|
|
* @return 1 if an element was found, 0 otherwise
|
|||
|
|
*/
|
|||
|
|
int quat_2x2_lattice_enumerate_cvp_filter(quat_alg_elem_t *res,
|
|||
|
|
const ibz_mat_2x2_t *lat_basis, const ibz_vec_2_t *target,
|
|||
|
|
unsigned int qf, unsigned int dist_bound,
|
|||
|
|
int (*condition)(quat_alg_elem_t* , const ibz_vec_2_t*, const void*), const void* params,
|
|||
|
|
unsigned int max_tries);
|
|||
|
|
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @defgroup quat_quat_f Quaternion algebra functions
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
void quat_alg_add(quat_alg_elem_t *res, const quat_alg_elem_t *a, const quat_alg_elem_t *b);
|
|||
|
|
void quat_alg_sub(quat_alg_elem_t *res, const quat_alg_elem_t *a, const quat_alg_elem_t *b);
|
|||
|
|
void quat_alg_mul(quat_alg_elem_t *res, const quat_alg_elem_t *a, const quat_alg_elem_t *b, const quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
/** @brief reduced norm of alg_elem x
|
|||
|
|
*
|
|||
|
|
* @param res Output: rational which will contain the reduced norm of a
|
|||
|
|
* @param x Algebra element whose norm is computed
|
|||
|
|
* @param alg The quaternion algebra
|
|||
|
|
*/
|
|||
|
|
void quat_alg_norm(ibq_t *res, const quat_alg_elem_t *x, const quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
/** @brief reduced trace of alg_elem x
|
|||
|
|
*
|
|||
|
|
* @param res Output: rational which will contain the reduced trace of a
|
|||
|
|
* @param x Algebra element whose trace will be computed
|
|||
|
|
*/
|
|||
|
|
void quat_alg_trace(ibq_t *res, const quat_alg_elem_t *x);
|
|||
|
|
|
|||
|
|
|
|||
|
|
/** @brief Normalize representation of alg_elem x
|
|||
|
|
*
|
|||
|
|
* @param x Algebra element whose representation will be normalized
|
|||
|
|
*
|
|||
|
|
* Modification of x.
|
|||
|
|
* Sets coord and denom of x so that gcd(denom, content(coord))=1
|
|||
|
|
* without changing the value of x = (coord0/denom, coord1/denom, coord2/denom, coord3/denom).
|
|||
|
|
*/
|
|||
|
|
void quat_alg_normalize(quat_alg_elem_t *x);
|
|||
|
|
|
|||
|
|
/** @brief Test if x is 0
|
|||
|
|
*
|
|||
|
|
* @returns 1 if x=0, 0 otherwise
|
|||
|
|
*
|
|||
|
|
* x is 0 iff all coordinates in x->coord are 0
|
|||
|
|
*/
|
|||
|
|
int quat_alg_elem_is_zero(const quat_alg_elem_t *x);
|
|||
|
|
|
|||
|
|
/** @brief Test if x is 0
|
|||
|
|
*
|
|||
|
|
* @returns 1 if x=0, 0 otherwise
|
|||
|
|
*
|
|||
|
|
* x is 0 iff all coordinates in x are 0
|
|||
|
|
*/
|
|||
|
|
int quat_alg_coord_is_zero(const quat_alg_coord_t *x);
|
|||
|
|
|
|||
|
|
|
|||
|
|
// end quat_quat_f
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @defgroup quat_lat_f Lattice functions
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
void quat_lattice_add(quat_lattice_t *res, const quat_lattice_t *lat1, const quat_lattice_t *lat2);
|
|||
|
|
void quat_lattice_intersect(quat_lattice_t *res, const quat_lattice_t *lat1, const quat_lattice_t *lat2);
|
|||
|
|
void quat_lattice_mul(quat_lattice_t *res, const quat_lattice_t *lat1, const quat_lattice_t *lat2, const quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Modifies a lattice to put it in hermite normal form
|
|||
|
|
*
|
|||
|
|
* In-place modification of the lattice.
|
|||
|
|
*
|
|||
|
|
* @param lat input lattice
|
|||
|
|
*
|
|||
|
|
* On a correct lattice this function changes nothing (since it is already in HNF), but it can be used to put a handmade one in correct form in order to use the other lattice functions.
|
|||
|
|
*/
|
|||
|
|
void quat_lattice_hnf(quat_lattice_t *lat);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Test whether x ∈ lat. If so, compute its coordinates in lat's basis.
|
|||
|
|
*
|
|||
|
|
* @param coord Output: Set to the coordinates of x in lat. May be NULL.
|
|||
|
|
* @param lat The lattice
|
|||
|
|
* @param x An element of the quaternion algebra
|
|||
|
|
* @param alg The quaternion algebra
|
|||
|
|
* @return true if x ∈ lat
|
|||
|
|
*/
|
|||
|
|
int quat_lattice_contains(quat_alg_coord_t *coord, const quat_lattice_t *lat, const quat_alg_elem_t *x, const quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
|
|||
|
|
/********************************* Functions from ideal.c ************************************/
|
|||
|
|
|
|||
|
|
/** @addtogroup quat_quat_f
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Creates algebra element from scalar
|
|||
|
|
*
|
|||
|
|
* Resulting element has 1-coordinate equal to numerator/denominator
|
|||
|
|
*
|
|||
|
|
* @param elem Output: algebra element with numerator/denominator as first coordiante (1-coordinate), 0 elsewhere (i,j,ij coordinates)
|
|||
|
|
* @param numerator
|
|||
|
|
* @param denominator Assumed non zero
|
|||
|
|
*/
|
|||
|
|
void quat_alg_scalar(quat_alg_elem_t *elem, const ibz_t *numerator, const ibz_t *denominator);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Standard involution in a quaternion algebra
|
|||
|
|
*
|
|||
|
|
* @param conj Output: image of x by standard involution of the quaternion algebra alg
|
|||
|
|
* @param x element of alg whose image is searched
|
|||
|
|
*/
|
|||
|
|
void quat_alg_conj(quat_alg_elem_t *conj, const quat_alg_elem_t *x);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Given `x` ∈ `order`, factor it into its primitive and impritive parts
|
|||
|
|
*
|
|||
|
|
* Given `x` ∈ `order`, return a coordinate vector `primitive_x` and an integer `content`
|
|||
|
|
* such that `x` = `content` · Λ `primitive_x`, where Λ is the basis of `order`
|
|||
|
|
* and `x` / `content` is primitive in `order`.
|
|||
|
|
*
|
|||
|
|
* @param primitive_x Output: coordinates of a primitive element of `order` (in `order`'s basis)
|
|||
|
|
* @param content Output: content of `x`'s coordinate vector in order's basis
|
|||
|
|
* @param alg the quaternion algebra
|
|||
|
|
* @param order order of `alg`
|
|||
|
|
* @param x element of order, must be in `order`
|
|||
|
|
*/
|
|||
|
|
static inline void quat_alg_make_primitive(quat_alg_coord_t *primitive_x, ibz_t *content, const quat_alg_elem_t *x, const quat_order_t *order, const quat_alg_t *alg) {
|
|||
|
|
int ok = quat_lattice_contains(primitive_x, order, x, alg);
|
|||
|
|
assert(ok);
|
|||
|
|
ibz_content(content, primitive_x);
|
|||
|
|
ibz_t r;
|
|||
|
|
ibz_init(&r);
|
|||
|
|
for(int i = 0; i < 4; i++) {
|
|||
|
|
ibz_div(*primitive_x + i, &r, *primitive_x + i, content);
|
|||
|
|
}
|
|||
|
|
ibz_finalize(&r);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Tests if x ∈ order is primitive
|
|||
|
|
*
|
|||
|
|
* @param alg quaternion algebra
|
|||
|
|
* @param order quaternion order
|
|||
|
|
* @param x element of the order (fails if x ∉ order)
|
|||
|
|
*
|
|||
|
|
* @returns 1 if x is primitive, 0 otherwise
|
|||
|
|
*/
|
|||
|
|
static inline int quat_alg_is_primitive(const quat_alg_elem_t *x, const quat_order_t *order, const quat_alg_t *alg) {
|
|||
|
|
quat_alg_coord_t coord;
|
|||
|
|
ibz_t cnt;
|
|||
|
|
quat_alg_coord_init(&coord);
|
|||
|
|
ibz_init(&cnt);
|
|||
|
|
|
|||
|
|
quat_alg_make_primitive(&coord,&cnt,x,order,alg);
|
|||
|
|
int ok = ibz_is_one(&cnt);
|
|||
|
|
|
|||
|
|
ibz_finalize(&cnt);
|
|||
|
|
quat_alg_coord_finalize(&coord);
|
|||
|
|
return ok;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//end quat_quat_f
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @defgroup quat_lideal_f Functions for left ideals
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @defgroup quat_lideal_c Creating left ideals
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Left principal ideal of order, generated by x
|
|||
|
|
*
|
|||
|
|
* @param lideal Output: left ideal
|
|||
|
|
* @param alg quaternion algebra
|
|||
|
|
* @param order maximal order of alg whose left ideal is searched
|
|||
|
|
* @param x generating element
|
|||
|
|
*
|
|||
|
|
* Creates the left ideal in 'order' generated by the element 'x'
|
|||
|
|
*/
|
|||
|
|
void quat_lideal_create_principal(quat_left_ideal_t *lideal, const quat_alg_elem_t *x, const quat_order_t *order, const quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Left ideal of order, generated by primitive x and N
|
|||
|
|
*
|
|||
|
|
* @param lideal Output: left ideal
|
|||
|
|
* @param alg quaternion algebra
|
|||
|
|
* @param order maximal order of alg whose left ideal is searched
|
|||
|
|
* @param x generating element, must be a primitive element of order
|
|||
|
|
* @param N generating integer
|
|||
|
|
*
|
|||
|
|
* Creates the left ideal in order generated by the element x and the integer N
|
|||
|
|
*
|
|||
|
|
*/
|
|||
|
|
void quat_lideal_create_from_primitive(quat_left_ideal_t *lideal, const quat_alg_elem_t *x, const ibz_t *N, const quat_order_t *order, const quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Make x primitive, remove content from N, then generate ideal
|
|||
|
|
*
|
|||
|
|
* @param lideal Output: left ideal
|
|||
|
|
* @param alg quaternion algebra
|
|||
|
|
* @param order maximal order of alg whose left ideal is searched
|
|||
|
|
* @param x generating element, a primitive element of order obtained from it will be used for generation
|
|||
|
|
* @param N generating integer
|
|||
|
|
*
|
|||
|
|
* Given `x` = n·y ∈ order` with `y` primitive, given an integer `N`, create the ideal
|
|||
|
|
* generated by `y` and `N / gcd(n, N)`.
|
|||
|
|
*
|
|||
|
|
*/
|
|||
|
|
void quat_lideal_make_primitive_then_create(quat_left_ideal_t *lideal, const quat_alg_elem_t *x, const ibz_t *N, const quat_order_t *order, const quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Random left ideal of norm 2^e
|
|||
|
|
*
|
|||
|
|
* @param lideal Output: random left ideal (of parents alg and order) with norm 2^e
|
|||
|
|
* @param alg parent algebra for which an ideal is chosen. Is a quaterion algebra
|
|||
|
|
* @param order parent order for which an ideal is chosen. Must be maximal
|
|||
|
|
* @param e int64_t determining the norm of the resulting ideal
|
|||
|
|
* @param n Parameter controlling the amount of randomness used by the algorithm
|
|||
|
|
* @return 0 if PRNG failed, 1 otherwise.
|
|||
|
|
*/
|
|||
|
|
int quat_lideal_random_2e(quat_left_ideal_t *lideal, const quat_order_t *order, const quat_alg_t *alg, int64_t e, unsigned char n);
|
|||
|
|
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @defgroup quat_lideal_gen Generators of left ideals
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Generator of 'lideal'
|
|||
|
|
*
|
|||
|
|
* @returns 1 if such a generator was found, 0 otherwise
|
|||
|
|
* @param gen Output: non scalar generator of lideal
|
|||
|
|
* @param lideal left ideal
|
|||
|
|
* @param alg the quaternion algebra
|
|||
|
|
* @param bound Bound used for enumeration of elements. Must be non-negative. If 0, a default value is used.
|
|||
|
|
*
|
|||
|
|
* Ideal is generated by gen and the ideal's norm
|
|||
|
|
*
|
|||
|
|
* Bound has as default value QUATERNION_lideal_generator_search_bound
|
|||
|
|
*/
|
|||
|
|
int quat_lideal_generator(quat_alg_elem_t *gen, const quat_left_ideal_t *lideal, const quat_alg_t *alg, int bound);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Primitive generator of a left ideal of norm coprime to a given integer
|
|||
|
|
*
|
|||
|
|
* @returns 1 if such a generator was found, 0 otherwise
|
|||
|
|
* @param gen Output: generator of lideal, coprime to n
|
|||
|
|
* @param lideal left ideal
|
|||
|
|
* @param n value to which the generator norm should be coprime. (assumes gcd(n, norm(lideal)) = 1). If this is not fulfilled, the returned element is a generator such that gcd(n^2,norm(gen)) = gcd(n,norm(lideal))
|
|||
|
|
* @param alg the quaternion algebra
|
|||
|
|
* @param bound Bound used for enumeration of elements. Must be non-negative. If 0, a default value 0 is used.
|
|||
|
|
*
|
|||
|
|
* Finds a primitive generator of 'lideal' of norm coprime with n (assumes gcd(n, norm(lideal)) = 1)
|
|||
|
|
*
|
|||
|
|
* gen is such that lideal is generated by gen and the ideal's norm
|
|||
|
|
*
|
|||
|
|
* Bound has as default value QUATERNION_lideal_generator_search_bound
|
|||
|
|
*/
|
|||
|
|
int quat_lideal_generator_coprime(quat_alg_elem_t *gen, const quat_left_ideal_t *lideal, const ibz_t *n, const quat_alg_t *alg, int bound);
|
|||
|
|
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/** @defgroup quat_lideal_op Operations on left ideals
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Left ideal product of left ideal I and element alpha
|
|||
|
|
*
|
|||
|
|
* @returns 1 if a product could be computed, 0 otherwise (in the later case, one might retry with a higher bound)
|
|||
|
|
* @param product Output: lideal I*alpha, must have integer norm
|
|||
|
|
* @param lideal left ideal
|
|||
|
|
* @param alpha element multiplied to lideal to get the product ideal
|
|||
|
|
* @param alg the quaternion algebra
|
|||
|
|
* @param bound used for internal ideal_generator search. Must be positive. Setting it to 0 uses the default value.
|
|||
|
|
*
|
|||
|
|
* I*alpha where I is a left-ideal and alpha an element of the algebra
|
|||
|
|
*
|
|||
|
|
* The resulting ideal must have an integer norm
|
|||
|
|
*
|
|||
|
|
* Bound has as default value QUATERNION_lideal_generator_search_bound
|
|||
|
|
*/
|
|||
|
|
int quat_lideal_mul(quat_left_ideal_t *product, const quat_left_ideal_t *lideal, const quat_alg_elem_t *alpha, const quat_alg_t *alg, int bound);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Sum of two left ideals
|
|||
|
|
*
|
|||
|
|
* @param sum Output: Left ideal which is the sum of the 2 inputs
|
|||
|
|
* @param lideal1 left ideal
|
|||
|
|
* @param lideal2 left ideal
|
|||
|
|
* @param alg the quaternion algebra
|
|||
|
|
*/
|
|||
|
|
void quat_lideal_add(quat_left_ideal_t *sum, const quat_left_ideal_t *lideal1, const quat_left_ideal_t *lideal2, const quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Intersection of two left ideals
|
|||
|
|
*
|
|||
|
|
* @param intersection Output: Left ideal which is the intersection of the 2 inputs
|
|||
|
|
* @param lideal1 left ideal
|
|||
|
|
* @param lideal2 left ideal
|
|||
|
|
* @param alg the quaternion algebra
|
|||
|
|
*/
|
|||
|
|
void quat_lideal_inter(quat_left_ideal_t *intersection, const quat_left_ideal_t *lideal1, const quat_left_ideal_t *lideal2, const quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Equality test for left ideals
|
|||
|
|
*
|
|||
|
|
* @returns 1 if both left ideals are equal, 0 otherwise
|
|||
|
|
* @param lideal1 left ideal
|
|||
|
|
* @param lideal2 left ideal
|
|||
|
|
* @param alg the quaternion algebra
|
|||
|
|
*/
|
|||
|
|
int quat_lideal_equals(const quat_left_ideal_t *lideal1, const quat_left_ideal_t *lideal2, const quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Element representing an isomorphism between I1 and I2
|
|||
|
|
*
|
|||
|
|
* @returns 1 if isomorphic, 0 otherwise
|
|||
|
|
* @param iso Output: algebra element such that I1*iso = I2.
|
|||
|
|
* @param lideal1 left ideal
|
|||
|
|
* @param lideal2 left ideal
|
|||
|
|
* @param alg the quaternion algebra
|
|||
|
|
*
|
|||
|
|
* If I1 and I2 are isomorphic, set `iso` to an element of `alg` such that I1*iso = I2,
|
|||
|
|
* and return 1. Otherwise return 0.
|
|||
|
|
*
|
|||
|
|
* I1 and I2 must have the same parent order (where "same" means they
|
|||
|
|
* point to the same object), in order to be considered isomorphic.
|
|||
|
|
*/
|
|||
|
|
int quat_lideal_isom(quat_alg_elem_t *iso, const quat_left_ideal_t *lideal1, const quat_left_ideal_t *lideal2, const quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Right order of a left ideal
|
|||
|
|
*
|
|||
|
|
* @param order Output: right order of the given ideal
|
|||
|
|
* @param lideal left ideal
|
|||
|
|
* @param alg the quaternion algebra
|
|||
|
|
*/
|
|||
|
|
void quat_lideal_right_order(quat_order_t *order, const quat_left_ideal_t *lideal, const quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief LLL-reduce the basis of the left ideal, without considering its denominator
|
|||
|
|
*
|
|||
|
|
* This function reduce the basis of the lattice of the ideal, but it does completely ignore its denominator.
|
|||
|
|
* So the outputs of this function must still e divided by the appropriate power of lideal.lattice.denom.
|
|||
|
|
*
|
|||
|
|
* @param reduced Output: Lattice defining the ideal, which has its basis in a lll-reduced form. Must be divided by lideal.lattice.denom before usage
|
|||
|
|
* @param gram Output: gram matrix of the reduced basis. Must be divided by (lideal.lattice.denom)^2 before usage
|
|||
|
|
* @param lideal Ideal whose basis will be reduced
|
|||
|
|
* @param alg the quaternion algebra
|
|||
|
|
*/
|
|||
|
|
void quat_lideal_reduce_basis(ibz_mat_4x4_t *reduced, ibz_mat_4x4_t *gram, const quat_left_ideal_t *lideal, const quat_alg_t *alg); //replaces lideal_lll
|
|||
|
|
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
// end quat_lideal_f
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/***************************** Functions from quaternion_tools.c ***************************************/
|
|||
|
|
|
|||
|
|
/** @defgroup quat_order_op Operations on orders
|
|||
|
|
* @{
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Connecting ideal of 2 orders in the same algebra
|
|||
|
|
*
|
|||
|
|
* @param connecting_ideal Output: ideal which is a right ideal of O1 and a left ideal of O2
|
|||
|
|
* @param alg quaternion algebra
|
|||
|
|
* @param order1 maximal order left of the searched ideal
|
|||
|
|
* @param order2 order right of the searched ideal
|
|||
|
|
*/
|
|||
|
|
void quat_connecting_ideal(quat_left_ideal_t *connecting_ideal, const quat_order_t *order1, const quat_order_t *order2, const quat_alg_t *alg);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief LLL reduction on 4-dimensional lattice, coefficient is 0.99
|
|||
|
|
*
|
|||
|
|
* @param red Output: LLL reduced basis
|
|||
|
|
* @param lattice lattice with 4-dimensional basis
|
|||
|
|
* @param q parameter q for non-standard basis
|
|||
|
|
* @param precision floating-point precision for LLL algorithm, if 0 is provided a default precision is taken
|
|||
|
|
*/
|
|||
|
|
int quat_lattice_lll(ibz_mat_4x4_t *red, const quat_lattice_t *lattice, const ibz_t *q, int precision);
|
|||
|
|
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
// end quat_quat
|
|||
|
|
/** @}
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
#endif
|