second-round version of SQIsign
Co-authored-by: Marius A. Aardal <marius.andre.aardal@gmail.com> Co-authored-by: Gora Adj <gora.adj@tii.ae> Co-authored-by: Diego F. Aranha <dfaranha@cs.au.dk> Co-authored-by: Andrea Basso <sqisign@andreabasso.com> Co-authored-by: Isaac Andrés Canales Martínez <icanalesm0500@gmail.com> Co-authored-by: Jorge Chávez-Saab <jorgechavezsaab@gmail.com> Co-authored-by: Maria Corte-Real Santos <mariascrsantos98@gmail.com> Co-authored-by: Luca De Feo <github@defeo.lu> Co-authored-by: Max Duparc <max.duparc@epfl.ch> Co-authored-by: Jonathan Komada Eriksen <jonathan.eriksen97@gmail.com> Co-authored-by: Décio Luiz Gazzoni Filho <decio@decpp.net> Co-authored-by: Basil Hess <bhe@zurich.ibm.com> Co-authored-by: Antonin Leroux <antonin.leroux@polytechnique.org> Co-authored-by: Patrick Longa <plonga@microsoft.com> Co-authored-by: Luciano Maino <mainoluciano.96@gmail.com> Co-authored-by: Michael Meyer <michael@random-oracles.org> Co-authored-by: Hiroshi Onuki <onuki@mist.i.u-tokyo.ac.jp> Co-authored-by: Lorenz Panny <lorenz@yx7.cc> Co-authored-by: Giacomo Pope <giacomopope@gmail.com> Co-authored-by: Krijn Reijnders <reijnderskrijn@gmail.com> Co-authored-by: Damien Robert <damien.robert@inria.fr> Co-authored-by: Francisco Rodríguez-Henriquez <francisco.rodriguez@tii.ae> Co-authored-by: Sina Schaeffler <sschaeffle@student.ethz.ch> Co-authored-by: Benjamin Wesolowski <benjamin.wesolowski@ens-lyon.fr>
This commit is contained in:
committed by
Lorenz Panny
parent
ff34a8cd18
commit
91e9e464fe
139
src/quaternion/ref/generic/lat_ball.c
Normal file
139
src/quaternion/ref/generic/lat_ball.c
Normal file
@@ -0,0 +1,139 @@
|
||||
#include <quaternion.h>
|
||||
#include <rng.h>
|
||||
#include <stdio.h>
|
||||
#include "internal.h"
|
||||
#include "lll_internals.h"
|
||||
|
||||
int
|
||||
quat_lattice_bound_parallelogram(ibz_vec_4_t *box, ibz_mat_4x4_t *U, const ibz_mat_4x4_t *G, const ibz_t *radius)
|
||||
{
|
||||
ibz_t denom, rem;
|
||||
ibz_init(&denom);
|
||||
ibz_init(&rem);
|
||||
ibz_mat_4x4_t dualG;
|
||||
ibz_mat_4x4_init(&dualG);
|
||||
|
||||
// Compute the Gram matrix of the dual lattice
|
||||
#ifndef NDEBUG
|
||||
int inv_check = ibz_mat_4x4_inv_with_det_as_denom(&dualG, &denom, G);
|
||||
assert(inv_check);
|
||||
#else
|
||||
(void)ibz_mat_4x4_inv_with_det_as_denom(&dualG, &denom, G);
|
||||
#endif
|
||||
// Initialize the dual lattice basis to the identity matrix
|
||||
ibz_mat_4x4_identity(U);
|
||||
// Reduce the dual lattice
|
||||
quat_lll_core(&dualG, U);
|
||||
|
||||
// Compute the parallelogram's bounds
|
||||
int trivial = 1;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ibz_mul(&(*box)[i], &dualG[i][i], radius);
|
||||
ibz_div(&(*box)[i], &rem, &(*box)[i], &denom);
|
||||
ibz_sqrt_floor(&(*box)[i], &(*box)[i]);
|
||||
trivial &= ibz_is_zero(&(*box)[i]);
|
||||
}
|
||||
|
||||
// Compute the transpose transformation matrix
|
||||
#ifndef NDEBUG
|
||||
int inv = ibz_mat_4x4_inv_with_det_as_denom(U, &denom, U);
|
||||
#else
|
||||
(void)ibz_mat_4x4_inv_with_det_as_denom(U, &denom, U);
|
||||
#endif
|
||||
// U is unitary, det(U) = ± 1
|
||||
ibz_mat_4x4_scalar_mul(U, &denom, U);
|
||||
#ifndef NDEBUG
|
||||
assert(inv);
|
||||
ibz_abs(&denom, &denom);
|
||||
assert(ibz_is_one(&denom));
|
||||
#endif
|
||||
|
||||
ibz_mat_4x4_finalize(&dualG);
|
||||
ibz_finalize(&denom);
|
||||
ibz_finalize(&rem);
|
||||
return !trivial;
|
||||
}
|
||||
|
||||
int
|
||||
quat_lattice_sample_from_ball(quat_alg_elem_t *res,
|
||||
const quat_lattice_t *lattice,
|
||||
const quat_alg_t *alg,
|
||||
const ibz_t *radius)
|
||||
{
|
||||
assert(ibz_cmp(radius, &ibz_const_zero) > 0);
|
||||
|
||||
ibz_vec_4_t box;
|
||||
ibz_vec_4_init(&box);
|
||||
ibz_mat_4x4_t U, G;
|
||||
ibz_mat_4x4_init(&U);
|
||||
ibz_mat_4x4_init(&G);
|
||||
ibz_vec_4_t x;
|
||||
ibz_vec_4_init(&x);
|
||||
ibz_t rad, tmp;
|
||||
ibz_init(&rad);
|
||||
ibz_init(&tmp);
|
||||
|
||||
// Compute the Gram matrix of the lattice
|
||||
quat_lattice_gram(&G, lattice, alg);
|
||||
|
||||
// Correct ball radius by the denominator
|
||||
ibz_mul(&rad, radius, &lattice->denom);
|
||||
ibz_mul(&rad, &rad, &lattice->denom);
|
||||
// Correct by 2 (Gram matrix corresponds to twice the norm)
|
||||
ibz_mul(&rad, &rad, &ibz_const_two);
|
||||
|
||||
// Compute a bounding parallelogram for the ball, stop if it only
|
||||
// contains the origin
|
||||
int ok = quat_lattice_bound_parallelogram(&box, &U, &G, &rad);
|
||||
if (!ok)
|
||||
goto err;
|
||||
|
||||
// Rejection sampling from the parallelogram
|
||||
#ifndef NDEBUG
|
||||
int cnt = 0;
|
||||
#endif
|
||||
do {
|
||||
// Sample vector
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (ibz_is_zero(&box[i])) {
|
||||
ibz_copy(&x[i], &ibz_const_zero);
|
||||
} else {
|
||||
ibz_add(&tmp, &box[i], &box[i]);
|
||||
ok &= ibz_rand_interval(&x[i], &ibz_const_zero, &tmp);
|
||||
ibz_sub(&x[i], &x[i], &box[i]);
|
||||
if (!ok)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
// Map to parallelogram
|
||||
ibz_mat_4x4_eval_t(&x, &x, &U);
|
||||
// Evaluate quadratic form
|
||||
quat_qf_eval(&tmp, &G, &x);
|
||||
#ifndef NDEBUG
|
||||
cnt++;
|
||||
if (cnt % 100 == 0)
|
||||
printf("Lattice sampling rejected %d times", cnt - 1);
|
||||
#endif
|
||||
} while (ibz_is_zero(&tmp) || (ibz_cmp(&tmp, &rad) > 0));
|
||||
|
||||
// Evaluate linear combination
|
||||
ibz_mat_4x4_eval(&(res->coord), &(lattice->basis), &x);
|
||||
ibz_copy(&(res->denom), &(lattice->denom));
|
||||
quat_alg_normalize(res);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Check norm is smaller than radius
|
||||
quat_alg_norm(&tmp, &rad, res, alg);
|
||||
ibz_mul(&rad, &rad, radius);
|
||||
assert(ibz_cmp(&tmp, &rad) <= 0);
|
||||
#endif
|
||||
|
||||
err:
|
||||
ibz_finalize(&rad);
|
||||
ibz_finalize(&tmp);
|
||||
ibz_vec_4_finalize(&x);
|
||||
ibz_mat_4x4_finalize(&U);
|
||||
ibz_mat_4x4_finalize(&G);
|
||||
ibz_vec_4_finalize(&box);
|
||||
return ok;
|
||||
}
|
||||
Reference in New Issue
Block a user