2023-06-01 00:00:00 +00:00
|
|
|
#include <protocols.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void signature_init(signature_t *sig)
|
|
|
|
|
{
|
|
|
|
|
id2iso_compressed_long_two_isog_init(&sig->zip, SQISIGN_signing_length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void signature_finalize(signature_t *sig)
|
|
|
|
|
{
|
|
|
|
|
id2iso_compressed_long_two_isog_finalize(&sig->zip);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void protocols_commit(quat_left_ideal_t *ideal, ec_curve_t *E1, ec_basis_t *basis)
|
|
|
|
|
{
|
|
|
|
|
ibz_vec_2_t vec;
|
|
|
|
|
ibz_vec_2_init(&vec);
|
|
|
|
|
|
|
|
|
|
ibz_t tmp;
|
|
|
|
|
ibz_init(&tmp);
|
|
|
|
|
|
|
|
|
|
// sample the random scalars
|
|
|
|
|
do {
|
|
|
|
|
ibz_rand_interval(&vec[0], &ibz_const_one, &DEGREE_COMMITMENT);
|
|
|
|
|
ibz_rand_interval(&vec[1], &ibz_const_one, &DEGREE_COMMITMENT);
|
|
|
|
|
ibz_gcd(&tmp, &vec[0], &vec[1]);
|
|
|
|
|
ibz_gcd(&tmp, &tmp, &DEGREE_COMMITMENT);
|
|
|
|
|
} while (!ibz_is_one(&tmp));
|
|
|
|
|
|
|
|
|
|
// deduce the commitment ideal
|
|
|
|
|
{
|
|
|
|
|
quat_alg_elem_t gen;
|
|
|
|
|
quat_alg_elem_init(&gen);
|
|
|
|
|
|
|
|
|
|
ibz_set(&gen.denom, 1);
|
|
|
|
|
for (unsigned i = 0; i < 4; ++i) {
|
|
|
|
|
ibz_mul(&gen.coord[i], &COMMITMENT_IDEAL_DISTORTION_ENDO.coord[i], &vec[1]);
|
|
|
|
|
if (i)
|
|
|
|
|
ibz_neg(&gen.coord[i], &gen.coord[i]); // conjugate
|
|
|
|
|
}
|
|
|
|
|
ibz_add(&gen.coord[0], &gen.coord[0], &vec[0]);
|
|
|
|
|
// now gen = a + b*dual(theta) where vec=(a,b) and theta is the distortion map
|
|
|
|
|
|
|
|
|
|
quat_alg_mul(&gen, &COMMITMENT_IDEAL_UNDISTORTED_GEN, &gen, &QUATALG_PINFTY);
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
quat_alg_coord_t coeffs;
|
|
|
|
|
ibz_t temp,remainder;
|
|
|
|
|
quat_alg_coord_init(&coeffs);
|
|
|
|
|
ibz_init(&temp);ibz_init(&remainder);
|
|
|
|
|
quat_alg_make_primitive(&coeffs,&temp,&gen,&MAXORD_O0,&QUATALG_PINFTY);
|
|
|
|
|
ibz_mul(&gen.denom,&gen.denom,&temp);
|
|
|
|
|
quat_alg_normalize(&gen);
|
|
|
|
|
assert(quat_alg_is_primitive(&gen,&MAXORD_O0,&QUATALG_PINFTY));
|
|
|
|
|
ibq_t ibq_norm;
|
|
|
|
|
ibq_init(&ibq_norm);
|
|
|
|
|
quat_alg_norm(&ibq_norm,&gen,&QUATALG_PINFTY);
|
|
|
|
|
assert(ibq_to_ibz(&temp,&ibq_norm));
|
|
|
|
|
ibq_finalize(&ibq_norm);
|
|
|
|
|
ibz_gcd(&temp,&temp,&DEGREE_COMMITMENT);
|
|
|
|
|
ibz_div(&temp,&remainder,&temp,&DEGREE_COMMITMENT);
|
|
|
|
|
assert(0==ibz_cmp(&remainder,&ibz_const_zero));
|
2023-07-11 11:30:28 +02:00
|
|
|
ibz_finalize(&temp);ibz_finalize(&remainder);
|
|
|
|
|
quat_alg_coord_finalize(&coeffs);
|
2023-06-01 00:00:00 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
quat_lideal_make_primitive_then_create(ideal, &gen, &DEGREE_COMMITMENT, &MAXORD_O0, &QUATALG_PINFTY);
|
|
|
|
|
assert(!ibz_cmp(&ideal->norm, &DEGREE_COMMITMENT));
|
|
|
|
|
|
|
|
|
|
quat_alg_elem_finalize(&gen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// deduce the commitment isogeny
|
|
|
|
|
ec_isog_odd_t isogeny;
|
|
|
|
|
{
|
|
|
|
|
isogeny.curve = CURVE_E0;
|
|
|
|
|
for (size_t i = 0; i < sizeof(TORSION_ODD_PRIMES)/sizeof(*TORSION_ODD_PRIMES); ++i)
|
|
|
|
|
isogeny.degree[i] = DEGREE_COMMITMENT_POWERS[i];
|
|
|
|
|
|
|
|
|
|
digit_t scalars_plus[2][NWORDS_FIELD], scalars_minus[2][NWORDS_FIELD];
|
|
|
|
|
ibz_mod(&tmp, &vec[0], &DEGREE_COMMITMENT_PLUS);
|
|
|
|
|
ibz_to_digit_array(scalars_plus[0], &tmp);
|
|
|
|
|
ibz_mod(&tmp, &vec[1], &DEGREE_COMMITMENT_PLUS);
|
|
|
|
|
ibz_to_digit_array(scalars_plus[1], &tmp);
|
|
|
|
|
ibz_mod(&tmp, &vec[0], &DEGREE_COMMITMENT_MINUS);
|
|
|
|
|
ibz_to_digit_array(scalars_minus[0], &tmp);
|
|
|
|
|
ibz_mod(&tmp, &vec[1], &DEGREE_COMMITMENT_MINUS);
|
|
|
|
|
ibz_to_digit_array(scalars_minus[1], &tmp);
|
|
|
|
|
|
|
|
|
|
ec_biscalar_mul(&isogeny.ker_plus, &CURVE_E0, scalars_plus[0], scalars_plus[1], &BASIS_COMMITMENT_PLUS);
|
|
|
|
|
ec_biscalar_mul(&isogeny.ker_minus, &CURVE_E0, scalars_minus[0], scalars_minus[1], &BASIS_COMMITMENT_MINUS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ec_curve_t E1comp;
|
|
|
|
|
ec_eval_odd_basis(&E1comp, &isogeny, basis, 1);
|
|
|
|
|
|
|
|
|
|
// normalize E1 with the pushed basis
|
|
|
|
|
{
|
|
|
|
|
ec_isom_t isom;
|
|
|
|
|
ec_curve_normalize(E1, &isom, &E1comp);
|
|
|
|
|
ec_iso_eval(&basis->P, &isom);
|
|
|
|
|
ec_iso_eval(&basis->Q, &isom);
|
|
|
|
|
ec_iso_eval(&basis->PmQ, &isom);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ibz_finalize(&tmp);
|
|
|
|
|
ibz_vec_2_finalize(&vec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void protocols_challenge(quat_left_ideal_t *ideal, signature_t *sig, const ec_curve_t *E1, const ec_basis_t *pushedbasis6, const ibz_vec_2_t *hash, ec_curve_t *out_E2)
|
|
|
|
|
{
|
|
|
|
|
// compute deterministic and pushed 2*3*-torsion bases on E1
|
|
|
|
|
ec_basis_t E1basis6, E1basis2, E1basis3;
|
|
|
|
|
ec_basis_t pushedbasis2, pushedbasis3;
|
|
|
|
|
ec_curve_to_basis_6(&E1basis6, E1);
|
|
|
|
|
{
|
|
|
|
|
digit_t scalar[NWORDS_FIELD];
|
|
|
|
|
ibz_to_digit_array(scalar, &TORSION_PLUS_3POWER);
|
|
|
|
|
ec_mul(&E1basis2.P, E1, scalar, &E1basis6.P);
|
|
|
|
|
ec_mul(&E1basis2.Q, E1, scalar, &E1basis6.Q);
|
|
|
|
|
ec_mul(&E1basis2.PmQ, E1, scalar, &E1basis6.PmQ);
|
|
|
|
|
ec_mul(&pushedbasis2.P, E1, scalar, &pushedbasis6->P);
|
|
|
|
|
ec_mul(&pushedbasis2.Q, E1, scalar, &pushedbasis6->Q);
|
|
|
|
|
ec_mul(&pushedbasis2.PmQ, E1, scalar, &pushedbasis6->PmQ);
|
|
|
|
|
ibz_to_digit_array(scalar, &TORSION_PLUS_2POWER);
|
|
|
|
|
ec_mul(&E1basis3.P, E1, scalar, &E1basis6.P);
|
|
|
|
|
ec_mul(&E1basis3.Q, E1, scalar, &E1basis6.Q);
|
|
|
|
|
ec_mul(&E1basis3.PmQ, E1, scalar, &E1basis6.PmQ);
|
|
|
|
|
ec_mul(&pushedbasis3.P, E1, scalar, &pushedbasis6->P);
|
|
|
|
|
ec_mul(&pushedbasis3.Q, E1, scalar, &pushedbasis6->Q);
|
|
|
|
|
ec_mul(&pushedbasis3.PmQ, E1, scalar, &pushedbasis6->PmQ);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// compute the kernel of the challenge isogeny
|
|
|
|
|
ec_point_t ker;
|
|
|
|
|
{
|
|
|
|
|
digit_t scalars[2][NWORDS_FIELD];
|
|
|
|
|
ibz_to_digit_array(scalars[0], &(*hash)[0]);
|
|
|
|
|
ibz_to_digit_array(scalars[1], &(*hash)[1]);
|
|
|
|
|
ec_biscalar_mul(&ker, E1, scalars[0], scalars[1], &E1basis6);
|
|
|
|
|
}
|
|
|
|
|
ec_point_t ker2, ker3;
|
|
|
|
|
{
|
|
|
|
|
digit_t scalar[NWORDS_FIELD];
|
|
|
|
|
ibz_to_digit_array(scalar, &TORSION_PLUS_3POWER);
|
|
|
|
|
ec_mul(&ker2, E1, scalar, &ker);
|
|
|
|
|
ibz_to_digit_array(scalar, &TORSION_PLUS_2POWER);
|
|
|
|
|
ec_mul(&ker3, E1, scalar, &ker);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// compute ideal corresponding to the challenge isogeny, pulled back to O0
|
|
|
|
|
{
|
|
|
|
|
// compute the logarithm of the kernel with respect to the pushed basis
|
|
|
|
|
ibz_vec_2_t vec2, vec3;
|
|
|
|
|
ibz_vec_2_init(&vec2);
|
|
|
|
|
ibz_vec_2_init(&vec3);
|
|
|
|
|
digit_t log[2][NWORDS_FIELD];
|
|
|
|
|
|
|
|
|
|
ec_dlog_2(log[0], log[1], &pushedbasis2, &ker2, E1);
|
|
|
|
|
|
|
|
|
|
ibz_copy_digit_array(&vec2[0], log[0]);
|
|
|
|
|
ibz_copy_digit_array(&vec2[1], log[1]);
|
|
|
|
|
|
|
|
|
|
ec_dlog_3(log[0], log[1], &pushedbasis3, &ker3, E1);
|
|
|
|
|
|
|
|
|
|
ibz_copy_digit_array(&vec3[0], log[0]);
|
|
|
|
|
ibz_copy_digit_array(&vec3[1], log[1]);
|
|
|
|
|
|
|
|
|
|
// now compute the ideal
|
|
|
|
|
id2iso_kernel_dlogs_to_ideal(ideal, &vec2, &vec3);
|
|
|
|
|
|
|
|
|
|
ibz_vec_2_finalize(&vec2);
|
|
|
|
|
ibz_vec_2_finalize(&vec3);
|
|
|
|
|
assert(!ibz_cmp(&ideal->norm, &DEGREE_CHALLENGE));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// compute the isogeny, evaluate at suitable point to find kernel of dual
|
|
|
|
|
ec_curve_t Emid, E2comp, E2;
|
|
|
|
|
ec_point_t pts[2];
|
|
|
|
|
ec_isom_t E2isom;
|
|
|
|
|
{
|
|
|
|
|
ec_isog_even_t isog2 = {.curve = *E1, .length = TORSION_PLUS_EVEN_POWER, .kernel = ker2};
|
|
|
|
|
|
|
|
|
|
// find a point independent to the kernel to push it through
|
|
|
|
|
{
|
|
|
|
|
bool const bit2 = !ibz_divides(&(*hash)[0], &ibz_const_two);
|
|
|
|
|
bool const bit3 = !ibz_divides(&(*hash)[0], &ibz_const_three);
|
|
|
|
|
if (bit2 == bit3) {
|
|
|
|
|
pts[0] = bit2 ? E1basis6.Q : E1basis6.P;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
digit_t scalars[2][NWORDS_FIELD];
|
|
|
|
|
ibz_to_digit_array(scalars[bit3], &TORSION_PLUS_2POWER);
|
|
|
|
|
ibz_to_digit_array(scalars[bit2], &TORSION_PLUS_3POWER);
|
|
|
|
|
ec_biscalar_mul(&pts[0], E1, scalars[0], scalars[1], &E1basis6);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pts[1] = ker;
|
|
|
|
|
|
|
|
|
|
ec_eval_even(&Emid, &isog2, pts, 2);
|
|
|
|
|
assert(!fp2_is_zero(&Emid.C));
|
|
|
|
|
|
|
|
|
|
assert(TORSION_ODD_PRIMES[0] == 3);
|
|
|
|
|
ec_isog_odd_t isog3 = {.curve = Emid, .degree = {TORSION_ODD_POWERS[0]}, .ker_plus = pts[1]};
|
|
|
|
|
|
|
|
|
|
ec_eval_odd(&E2comp, &isog3, pts, 1);
|
|
|
|
|
assert(!fp2_is_zero(&E2comp.C));
|
|
|
|
|
|
|
|
|
|
ec_curve_normalize(&E2, &E2isom, &E2comp);
|
|
|
|
|
if (out_E2) *out_E2 = E2;
|
|
|
|
|
|
|
|
|
|
ec_iso_eval(&pts[0], &E2isom);
|
|
|
|
|
}
|
|
|
|
|
// now the kernel of the dual is in pts[0]
|
|
|
|
|
|
|
|
|
|
// decompose kernel of dual over deterministic 2*3*-torsion basis on E2
|
|
|
|
|
ibz_vec_2_t vec2, vec3;
|
|
|
|
|
ibz_vec_2_init(&vec2);
|
|
|
|
|
ibz_vec_2_init(&vec3);
|
|
|
|
|
ec_basis_t E2basis6;
|
|
|
|
|
{
|
|
|
|
|
ec_basis_t E2basis2, E2basis3;
|
|
|
|
|
ec_curve_to_basis_6(&E2basis6, &E2);
|
|
|
|
|
|
|
|
|
|
// set up the 2-power and 3-power bases as images of the 2*3*-torsion one
|
|
|
|
|
{
|
|
|
|
|
digit_t scalar[NWORDS_FIELD];
|
|
|
|
|
ibz_to_digit_array(scalar, &TORSION_PLUS_3POWER);
|
|
|
|
|
ec_mul(&E2basis2.P, &E2, scalar, &E2basis6.P);
|
|
|
|
|
ec_mul(&E2basis2.Q, &E2, scalar, &E2basis6.Q);
|
|
|
|
|
ec_mul(&E2basis2.PmQ, &E2, scalar, &E2basis6.PmQ);
|
|
|
|
|
ibz_to_digit_array(scalar, &TORSION_PLUS_2POWER);
|
|
|
|
|
ec_mul(&E2basis3.P, &E2, scalar, &E2basis6.P);
|
|
|
|
|
ec_mul(&E2basis3.Q, &E2, scalar, &E2basis6.Q);
|
|
|
|
|
ec_mul(&E2basis3.PmQ, &E2, scalar, &E2basis6.PmQ);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// compute the 2-power and 3-power parts of the kernel of the dual
|
|
|
|
|
{
|
|
|
|
|
digit_t scalar[NWORDS_FIELD];
|
|
|
|
|
ibz_to_digit_array(scalar, &TORSION_PLUS_2POWER);
|
|
|
|
|
ec_mul(&pts[1], &E2, scalar, &pts[0]);
|
|
|
|
|
ibz_to_digit_array(scalar, &TORSION_PLUS_3POWER);
|
|
|
|
|
ec_mul(&pts[0], &E2, scalar, &pts[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// now compute the logarithms
|
|
|
|
|
{
|
|
|
|
|
digit_t scalars[2][NWORDS_FIELD];
|
|
|
|
|
|
|
|
|
|
ec_dlog_2(scalars[0], scalars[1], &E2basis2, &pts[0], &E2);
|
|
|
|
|
ibz_copy_digit_array(&vec2[0], scalars[0]);
|
|
|
|
|
ibz_copy_digit_array(&vec2[1], scalars[1]);
|
|
|
|
|
//ibz_vec_2_print(&vec2);
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
{
|
|
|
|
|
ec_point_t tmp;
|
|
|
|
|
ec_biscalar_mul(&tmp, &E2, scalars[0], scalars[1], &E2basis2);
|
|
|
|
|
assert(ec_is_equal(&tmp, &pts[0]));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
ec_dlog_3(scalars[0], scalars[1], &E2basis3, &pts[1], &E2);
|
|
|
|
|
ibz_copy_digit_array(&vec3[0], scalars[0]);
|
|
|
|
|
ibz_copy_digit_array(&vec3[1], scalars[1]);
|
|
|
|
|
//ibz_vec_2_print(&vec3);
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
{
|
|
|
|
|
ec_point_t tmp;
|
|
|
|
|
ec_biscalar_mul(&tmp, &E2, scalars[0], scalars[1], &E2basis3);
|
|
|
|
|
assert(ec_is_equal(&tmp, &pts[1]));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// encode this projective vector in the signature field s
|
|
|
|
|
bool const bit2 = !ibz_divides(&vec2[0], &ibz_const_two);
|
|
|
|
|
bool const bit3 = !ibz_divides(&vec3[0], &ibz_const_three);
|
|
|
|
|
{
|
|
|
|
|
assert(!ibz_divides(&vec2[!bit2], &ibz_const_two));
|
|
|
|
|
assert(!ibz_divides(&vec3[!bit3], &ibz_const_three));
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
ibz_t inv;
|
|
|
|
|
ibz_init(&inv);
|
|
|
|
|
|
|
|
|
|
ibz_invmod(&inv, &vec2[!bit2], &TORSION_PLUS_2POWER);
|
|
|
|
|
ibz_mul(&vec2[bit2], &vec2[bit2], &inv);
|
|
|
|
|
ibz_mod(&vec2[bit2], &vec2[bit2], &TORSION_PLUS_2POWER);
|
|
|
|
|
ibz_set(&vec2[!bit2], 1);
|
|
|
|
|
|
|
|
|
|
ibz_invmod(&inv, &vec3[!bit3], &TORSION_PLUS_3POWER);
|
|
|
|
|
ibz_mul(&vec3[bit3], &vec3[bit3], &inv);
|
|
|
|
|
ibz_mod(&vec3[bit3], &vec3[bit3], &TORSION_PLUS_3POWER);
|
|
|
|
|
ibz_set(&vec3[!bit3], 1);
|
|
|
|
|
|
|
|
|
|
ibz_finalize(&inv);
|
|
|
|
|
}
|
|
|
|
|
//printf("bit2=%u bit3=%u\n", (unsigned) bit2, (unsigned) bit3);
|
|
|
|
|
//ibz_vec_2_print(&vec2);
|
|
|
|
|
//ibz_vec_2_print(&vec3);
|
|
|
|
|
|
|
|
|
|
sig->s.select23 = bit2 | ((unsigned) bit3 << 1);
|
|
|
|
|
ibz_to_digit_array(sig->s.scalar2, &vec2[bit2]);
|
|
|
|
|
ibz_to_digit_array(sig->s.scalar3, &vec3[bit3]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// find another independent point R deterministically
|
|
|
|
|
ec_point_t R;
|
|
|
|
|
if (bit2 == bit3) {
|
|
|
|
|
R = bit2 ? E2basis6.Q : E2basis6.P;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
digit_t scalars[2][NWORDS_FIELD];
|
|
|
|
|
ibz_to_digit_array(scalars[bit3], &TORSION_PLUS_2POWER);
|
|
|
|
|
ibz_to_digit_array(scalars[bit2], &TORSION_PLUS_3POWER);
|
|
|
|
|
ec_biscalar_mul(&R, &E2, scalars[0], scalars[1], &E2basis6);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// evaluate the dual of the challenge isogeny
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
ec_isom_t E2isom_inv = E2isom;
|
|
|
|
|
ec_iso_inv(&E2isom_inv);
|
|
|
|
|
ec_iso_eval(&pts[0], &E2isom_inv);
|
|
|
|
|
ec_iso_eval(&pts[1], &E2isom_inv);
|
|
|
|
|
ec_iso_eval(&R, &E2isom_inv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(TORSION_ODD_PRIMES[0] == 3);
|
|
|
|
|
ec_isog_odd_t isog3dual = {.curve = E2comp, .degree = {TORSION_ODD_POWERS[0]}, .ker_plus = pts[1]};
|
|
|
|
|
ec_curve_t Emidcomp;
|
|
|
|
|
pts[1] = R;
|
|
|
|
|
ec_eval_odd(&Emidcomp, &isog3dual, pts, 2);
|
|
|
|
|
assert(!fp2_is_zero(&Emidcomp.C));
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
{
|
|
|
|
|
fp2_t j1, j2;
|
|
|
|
|
ec_j_inv(&j1, &Emid);
|
|
|
|
|
ec_j_inv(&j2, &Emidcomp);
|
|
|
|
|
assert(fp2_is_equal(&j1, &j2));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
R = pts[1];
|
|
|
|
|
|
|
|
|
|
ec_isog_even_t isog2dual = {.curve = Emidcomp, .length = TORSION_PLUS_EVEN_POWER, .kernel = pts[0]};
|
|
|
|
|
ec_curve_t E1comp;
|
|
|
|
|
ec_eval_even(&E1comp, &isog2dual, &R, 1);
|
|
|
|
|
assert(!fp2_is_zero(&E1comp.C));
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
{
|
|
|
|
|
fp2_t j1, j2;
|
|
|
|
|
ec_j_inv(&j1, E1);
|
|
|
|
|
ec_j_inv(&j2, &E1comp);
|
|
|
|
|
assert(fp2_is_equal(&j1, &j2));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
ec_isom_t E1isom;
|
|
|
|
|
ec_isomorphism(&E1isom, &E1comp, E1);
|
|
|
|
|
ec_iso_eval(&R, &E1isom);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ibz_t r;
|
|
|
|
|
ibz_init(&r);
|
|
|
|
|
//TODO this should just be a 1-dimensional logarithm in the 2*3*-torsion
|
|
|
|
|
{
|
|
|
|
|
ec_point_t R2, R3;
|
|
|
|
|
{
|
|
|
|
|
digit_t scalar[NWORDS_FIELD];
|
|
|
|
|
ibz_to_digit_array(scalar, &TORSION_PLUS_3POWER);
|
|
|
|
|
ec_mul(&R2, E1, scalar, &R);
|
|
|
|
|
ibz_to_digit_array(scalar, &TORSION_PLUS_2POWER);
|
|
|
|
|
ec_mul(&R3, E1, scalar, &R);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ibz_vec_2_t log2, log3;
|
|
|
|
|
ibz_vec_2_init(&log2);
|
|
|
|
|
ibz_vec_2_init(&log3);
|
|
|
|
|
{
|
|
|
|
|
digit_t scalars[2][NWORDS_FIELD] = {0};
|
|
|
|
|
ec_dlog_2(scalars[0], scalars[1], &E1basis2, &R2, E1);
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
{
|
|
|
|
|
ec_point_t tmp;
|
|
|
|
|
ec_biscalar_mul(&tmp, E1, scalars[0], scalars[1], &E1basis2);
|
|
|
|
|
assert(ec_is_equal(&tmp, &R2));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
ibz_copy_digit_array(&log2[0], scalars[0]);
|
|
|
|
|
ibz_copy_digit_array(&log2[1], scalars[1]);
|
|
|
|
|
memset(scalars, 0, sizeof(scalars));
|
|
|
|
|
ec_dlog_3(scalars[0], scalars[1], &E1basis3, &R3, E1);
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
{
|
|
|
|
|
ec_point_t tmp;
|
|
|
|
|
ec_biscalar_mul(&tmp, E1, scalars[0], scalars[1], &E1basis3);
|
|
|
|
|
assert(ec_is_equal(&tmp, &R3));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
ibz_copy_digit_array(&log3[0], scalars[0]);
|
|
|
|
|
ibz_copy_digit_array(&log3[1], scalars[1]);
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
{
|
|
|
|
|
ibz_t lhs, rhs;
|
|
|
|
|
ibz_init(&lhs);
|
|
|
|
|
ibz_init(&rhs);
|
|
|
|
|
// check log2 is a multiple of hash modulo 2*
|
|
|
|
|
ibz_mul(&lhs, &log2[0], &(*hash)[1]);
|
|
|
|
|
ibz_mul(&rhs, &log2[1], &(*hash)[0]);
|
|
|
|
|
ibz_mod(&lhs, &lhs, &TORSION_PLUS_2POWER);
|
|
|
|
|
ibz_mod(&rhs, &rhs, &TORSION_PLUS_2POWER);
|
|
|
|
|
assert(!ibz_cmp(&lhs, &rhs));
|
|
|
|
|
// check log3 is a multiple of hash modulo 3*
|
|
|
|
|
ibz_mul(&lhs, &log3[0], &(*hash)[1]);
|
|
|
|
|
ibz_mul(&rhs, &log3[1], &(*hash)[0]);
|
|
|
|
|
ibz_mod(&lhs, &lhs, &TORSION_PLUS_3POWER);
|
|
|
|
|
ibz_mod(&rhs, &rhs, &TORSION_PLUS_3POWER);
|
|
|
|
|
assert(!ibz_cmp(&lhs, &rhs));
|
|
|
|
|
ibz_finalize(&lhs);
|
|
|
|
|
ibz_finalize(&rhs);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
ibz_t r2, r3;
|
|
|
|
|
ibz_init(&r2);
|
|
|
|
|
ibz_init(&r3);
|
|
|
|
|
bool bit = ibz_divides(&log2[0], &ibz_const_two);
|
|
|
|
|
assert(!ibz_divides(&log2[bit], &ibz_const_two));
|
|
|
|
|
ibz_invmod(&r2, &log2[bit], &TORSION_PLUS_2POWER);
|
|
|
|
|
ibz_mul(&r2, &(*hash)[bit], &r2);
|
|
|
|
|
ibz_mod(&r2, &r2, &TORSION_PLUS_2POWER);
|
|
|
|
|
//ibz_printf("r2 = %#Zx\n", &r2);
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
{
|
|
|
|
|
digit_t scalar[NWORDS_FIELD];
|
|
|
|
|
ibz_to_digit_array(scalar, &r2);
|
|
|
|
|
ec_point_t T1, T2;
|
|
|
|
|
ec_mul(&T1, E1, scalar, &R);
|
|
|
|
|
ibz_to_digit_array(scalar, &TORSION_PLUS_3POWER);
|
|
|
|
|
ec_mul(&T1, E1, scalar, &T1);
|
|
|
|
|
ec_mul(&T2, E1, scalar, &ker);
|
|
|
|
|
assert(ec_is_equal(&T1, &T2));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
bit = ibz_divides(&log3[0], &ibz_const_three);
|
|
|
|
|
assert(!ibz_divides(&log3[bit], &ibz_const_three));
|
|
|
|
|
ibz_invmod(&r3, &log3[bit], &TORSION_PLUS_3POWER);
|
|
|
|
|
ibz_mul(&r3, &(*hash)[bit], &r3);
|
|
|
|
|
ibz_mod(&r3, &r3, &TORSION_PLUS_3POWER);
|
|
|
|
|
//ibz_printf("r3 = %#Zx\n", &r3);
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
{
|
|
|
|
|
digit_t scalar[NWORDS_FIELD];
|
|
|
|
|
ibz_to_digit_array(scalar, &r3);
|
|
|
|
|
ec_point_t T1, T2;
|
|
|
|
|
ec_mul(&T1, E1, scalar, &R);
|
|
|
|
|
ibz_to_digit_array(scalar, &TORSION_PLUS_2POWER);
|
|
|
|
|
ec_mul(&T1, E1, scalar, &T1);
|
|
|
|
|
ec_mul(&T2, E1, scalar, &ker);
|
|
|
|
|
assert(ec_is_equal(&T1, &T2));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
ibz_crt(&r, &r2, &r3, &TORSION_PLUS_2POWER, &TORSION_PLUS_3POWER);
|
|
|
|
|
// check if we mixed up the signs and correct it in that case
|
|
|
|
|
{
|
|
|
|
|
digit_t scalar[NWORDS_FIELD];
|
|
|
|
|
ibz_to_digit_array(scalar, &r);
|
|
|
|
|
ec_point_t T;
|
|
|
|
|
ec_mul(&T, E1, scalar, &R);
|
|
|
|
|
if (!ec_is_equal(&T, &ker)) {
|
|
|
|
|
ibz_sub(&r3, &TORSION_PLUS_3POWER, &r3);
|
|
|
|
|
ibz_crt(&r, &r2, &r3, &TORSION_PLUS_2POWER, &TORSION_PLUS_3POWER);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ibz_finalize(&r2);
|
|
|
|
|
ibz_finalize(&r3);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ibz_vec_2_finalize(&log2);
|
|
|
|
|
ibz_vec_2_finalize(&log3);
|
|
|
|
|
ibz_vec_2_finalize(&vec2);
|
|
|
|
|
ibz_vec_2_finalize(&vec3);
|
|
|
|
|
}
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
{
|
|
|
|
|
digit_t scalar[NWORDS_FIELD];
|
|
|
|
|
ibz_to_digit_array(scalar, &r);
|
|
|
|
|
ec_point_t T;
|
|
|
|
|
ec_mul(&T, E1, scalar, &R);
|
|
|
|
|
assert(ec_is_equal(&T, &ker));
|
|
|
|
|
assert(!ibz_divides(&r, &ibz_const_two));
|
|
|
|
|
assert(!ibz_divides(&r, &ibz_const_three));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
ibz_to_digit_array(sig->r, &r);
|
|
|
|
|
|
|
|
|
|
ibz_finalize(&r);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int protocols_sign(signature_t *sig,const public_key_t *pk, const secret_key_t *sk, const unsigned char* m, size_t l) {
|
|
|
|
|
|
|
|
|
|
// var dec
|
|
|
|
|
quat_order_t right_order_key;
|
|
|
|
|
quat_left_ideal_t ideal_commit,ideal_challenge;
|
|
|
|
|
quat_alg_elem_t gen,gen_small,gen_answer,delta;
|
|
|
|
|
ibq_t ibq_norm;
|
|
|
|
|
ibz_t norm,temp,remainder;
|
|
|
|
|
ibz_mat_4x4_t reduced,gram;
|
|
|
|
|
quat_alg_coord_t coeffs;
|
|
|
|
|
|
|
|
|
|
quat_left_ideal_t ideal_comchall,ideal_seccomchall;
|
|
|
|
|
quat_left_ideal_t ideal_eichler_rand;
|
|
|
|
|
quat_left_ideal_t ideal_pullback,ideal_input_klpt;
|
|
|
|
|
quat_alg_elem_t gen_challenge;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// var init
|
|
|
|
|
ibq_init(&ibq_norm);
|
|
|
|
|
ibz_init(&norm);ibz_init(&temp);
|
|
|
|
|
ibz_init(&remainder);
|
|
|
|
|
quat_order_init(&right_order_key);
|
|
|
|
|
quat_left_ideal_init(&ideal_commit);
|
|
|
|
|
quat_left_ideal_init(&ideal_challenge);
|
|
|
|
|
quat_alg_elem_init(&gen);
|
|
|
|
|
quat_alg_elem_init(&gen_small);
|
|
|
|
|
quat_alg_elem_init(&delta);
|
|
|
|
|
ibz_mat_4x4_init(&reduced);
|
|
|
|
|
ibz_mat_4x4_init(&gram);
|
|
|
|
|
quat_alg_coord_init(&coeffs);
|
|
|
|
|
quat_left_ideal_init(&ideal_comchall);
|
|
|
|
|
quat_left_ideal_init(&ideal_seccomchall);
|
|
|
|
|
quat_left_ideal_init(&ideal_eichler_rand);
|
|
|
|
|
quat_left_ideal_init(&ideal_pullback);
|
|
|
|
|
quat_left_ideal_init(&ideal_input_klpt);
|
|
|
|
|
quat_alg_elem_init(&gen_challenge);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ec_curve_t curve = sk->curve;
|
|
|
|
|
ec_basis_t basis_plus = sk->basis_plus;
|
|
|
|
|
ec_basis_t basis_minus = sk->basis_minus;
|
|
|
|
|
ec_point_t kernel_dual = sk->kernel_dual;
|
|
|
|
|
|
|
|
|
|
// Commitment (computes ideal_commit and pushes the 2*3*-torsion basis)
|
|
|
|
|
ec_curve_t E1;
|
|
|
|
|
ec_basis_t E1basis = BASIS_CHALLENGE;
|
|
|
|
|
{
|
|
|
|
|
protocols_commit(&ideal_commit, &E1, &E1basis);
|
|
|
|
|
|
|
|
|
|
assert(!fp2_is_zero(&E1.C));
|
|
|
|
|
assert(!fp2_is_zero(&E1basis.P.z) && !fp2_is_zero(&E1basis.Q.z) && !fp2_is_zero(&E1basis.PmQ.z));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Challenge (computes ideal_challenge and sig->r, sig->s)
|
|
|
|
|
ec_curve_t E2_for_testing; //XXX
|
|
|
|
|
{
|
|
|
|
|
ibz_vec_2_t vec;
|
|
|
|
|
ibz_vec_2_init(&vec);
|
|
|
|
|
|
|
|
|
|
hash_to_challenge(&vec, &E1, m, l);
|
|
|
|
|
|
|
|
|
|
protocols_challenge(&ideal_challenge, sig, &E1, &E1basis, &vec, &E2_for_testing);
|
|
|
|
|
|
|
|
|
|
ibz_vec_2_finalize(&vec);
|
|
|
|
|
}
|
|
|
|
|
assert(ibz_get(&ideal_commit.norm)%2!=0);
|
|
|
|
|
|
|
|
|
|
// ideal_comchall is the intersectin of ideal_commit and ideal_challenge
|
|
|
|
|
quat_lideal_inter(&ideal_comchall,&ideal_challenge,&ideal_commit,&QUATALG_PINFTY);
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
// debug the norm
|
|
|
|
|
ibz_mul(&temp,&ideal_commit.norm,&ideal_challenge.norm);
|
|
|
|
|
assert(0==ibz_cmp(&temp,&ideal_comchall.norm));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
int lideal_generator_ok = quat_lideal_generator(&gen,&ideal_comchall,&QUATALG_PINFTY,0);
|
|
|
|
|
assert(lideal_generator_ok);
|
|
|
|
|
// computing the generator of ideal seccomchall as gen = sk.gen_two * gen
|
|
|
|
|
quat_alg_elem_copy(&gen_challenge,&gen);
|
|
|
|
|
quat_alg_norm(&ibq_norm,&gen_challenge,&QUATALG_PINFTY);
|
|
|
|
|
ibq_to_ibz(&norm,&ibq_norm);
|
|
|
|
|
|
|
|
|
|
// computing a good norm element for sk.lideal_small
|
|
|
|
|
lideal_generator_ok = quat_lideal_generator_coprime(&gen_small,&sk->lideal_small,&norm,&QUATALG_PINFTY,0);
|
|
|
|
|
assert(lideal_generator_ok);
|
|
|
|
|
quat_alg_conj(&gen_small,&gen_small);
|
|
|
|
|
quat_alg_normalize(&gen_small);
|
|
|
|
|
|
|
|
|
|
// gen = gen_small * gen_challenge
|
|
|
|
|
quat_alg_mul(&gen,&gen_small,&gen_challenge,&QUATALG_PINFTY);
|
|
|
|
|
ibz_mul(&temp,&ideal_comchall.norm,&sk->lideal_small.norm);
|
|
|
|
|
quat_alg_normalize(&gen);
|
|
|
|
|
|
|
|
|
|
// computing of the right order of lideal_small
|
|
|
|
|
quat_lideal_right_order(&right_order_key,&sk->lideal_small,&QUATALG_PINFTY);
|
|
|
|
|
assert(quat_lattice_contains(&coeffs,&right_order_key,&gen,&QUATALG_PINFTY));
|
|
|
|
|
|
|
|
|
|
// creation of ideal_seccomchall
|
|
|
|
|
quat_lideal_make_primitive_then_create(&ideal_seccomchall,&gen,&temp,&right_order_key,&QUATALG_PINFTY);
|
|
|
|
|
|
|
|
|
|
// copying a generator for later
|
|
|
|
|
quat_alg_elem_copy(&gen_challenge,&gen);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
// debug the norm
|
|
|
|
|
ibz_mul(&temp,&ideal_comchall.norm,&sk->lideal_small.norm);
|
|
|
|
|
assert(0==ibz_cmp(&temp,&ideal_seccomchall.norm));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
int found = 0;
|
|
|
|
|
|
|
|
|
|
for (unsigned attempt = 0; !found && attempt < SQISIGN_response_attempts; ++attempt) {
|
|
|
|
|
// TODUPDATE add a random ideal of norm 2^SQISIGN_random_length (right now SQISIGN_random_length )
|
|
|
|
|
|
|
|
|
|
// now we are computing a small ideal equivalent to ideal_seccomchall
|
|
|
|
|
//TODUPDATE replace with another randomization to ensure a good distribution in the eichler order class set
|
|
|
|
|
quat_lideal_reduce_basis(&reduced,&gram,&ideal_seccomchall,&QUATALG_PINFTY);
|
|
|
|
|
found = klpt_lideal_equiv(&gen,&temp,&reduced,&gram,&ideal_seccomchall.norm,&ideal_seccomchall.lattice.denom,&QUATALG_PINFTY);
|
|
|
|
|
if (!found) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// quat_alg_elem_copy(&gen_challenge,&gen);
|
|
|
|
|
quat_alg_conj(&gen_challenge,&gen);
|
|
|
|
|
|
|
|
|
|
// computing ideal_eichler_rand = right_order_key < gen, temp >
|
|
|
|
|
quat_lideal_create_from_primitive(&ideal_eichler_rand,&gen,&temp,&right_order_key,&QUATALG_PINFTY);
|
|
|
|
|
|
|
|
|
|
assert(quat_lideal_isom(&delta,&ideal_eichler_rand,&ideal_seccomchall,&QUATALG_PINFTY));
|
|
|
|
|
|
|
|
|
|
// computing the pullback through sk->lideal_small
|
|
|
|
|
quat_alg_mul(&gen,&gen_small,&gen,&QUATALG_PINFTY);
|
|
|
|
|
quat_alg_normalize(&gen);
|
|
|
|
|
quat_lideal_create_from_primitive(&ideal_pullback,&gen,&ideal_eichler_rand.norm,&MAXORD_O0,&QUATALG_PINFTY);
|
|
|
|
|
|
|
|
|
|
// computing the final input ideal as equivalent to ideal_pullback
|
|
|
|
|
quat_lideal_reduce_basis(&reduced,&gram,&ideal_pullback,&QUATALG_PINFTY);
|
|
|
|
|
found = found && klpt_lideal_equiv(&gen,&temp,&reduced,&gram,&ideal_pullback.norm,&ideal_pullback.lattice.denom,&QUATALG_PINFTY);
|
|
|
|
|
// ruling out failure, or extreme values of gen
|
|
|
|
|
if (!found || 0==ibz_cmp(&gen.coord[0],&ibz_const_zero) || 0==ibz_cmp(&gen.coord[1],&ibz_const_zero)) {
|
|
|
|
|
found = 0;
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// creating this ideal
|
|
|
|
|
quat_lideal_create_from_primitive(&ideal_input_klpt,&gen,&temp,&MAXORD_O0,&QUATALG_PINFTY);
|
|
|
|
|
assert(quat_lideal_isom(&delta,&ideal_input_klpt,&ideal_pullback,&QUATALG_PINFTY));
|
|
|
|
|
|
|
|
|
|
// applying klpt
|
|
|
|
|
quat_alg_conj(&delta,&gen);
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
assert(quat_lattice_contains(&coeffs,&ideal_pullback.lattice,&delta,&QUATALG_PINFTY));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// applying signing klpt
|
|
|
|
|
found = klpt_signing_klpt(&gen,&ideal_input_klpt,&sk->lideal_small,&delta,&QUATALG_PINFTY);
|
|
|
|
|
if (!found) {
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
assert(quat_lattice_contains(&coeffs,&ideal_input_klpt.lattice,&gen,&QUATALG_PINFTY));
|
|
|
|
|
|
|
|
|
|
// gen = gen *delta /norm(ideal_input_klpt)
|
|
|
|
|
quat_alg_mul(&gen,&gen,&delta,&QUATALG_PINFTY);
|
|
|
|
|
ibz_mul(&gen.denom,&gen.denom,&ideal_input_klpt.norm);
|
|
|
|
|
quat_alg_normalize(&gen);
|
|
|
|
|
|
|
|
|
|
// for debug we check that gen is contained in the right order and ideal
|
|
|
|
|
assert(quat_lattice_contains(&coeffs,&ideal_pullback.lattice,&gen,&QUATALG_PINFTY));
|
|
|
|
|
assert(quat_lattice_contains(&coeffs,&right_order_key,&gen,&QUATALG_PINFTY));
|
|
|
|
|
|
|
|
|
|
// gen = conjugate(gen)
|
|
|
|
|
// gen should be the generator of the ideal to be translated
|
|
|
|
|
quat_alg_conj(&gen,&gen);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
quat_left_ideal_t ideal_signing_test;
|
|
|
|
|
quat_left_ideal_init(&ideal_signing_test);
|
|
|
|
|
ibz_pow(&temp,&ibz_const_two,KLPT_signing_klpt_length);
|
|
|
|
|
quat_lideal_create_from_primitive(&ideal_signing_test,&gen,&temp,&right_order_key,&QUATALG_PINFTY);
|
|
|
|
|
assert(quat_lideal_isom(&delta,&ideal_signing_test,&ideal_seccomchall,&QUATALG_PINFTY));
|
|
|
|
|
assert(quat_lideal_isom(&delta,&ideal_eichler_rand,&ideal_seccomchall,&QUATALG_PINFTY));
|
|
|
|
|
assert(quat_lideal_isom(&delta,&ideal_eichler_rand,&ideal_seccomchall,&QUATALG_PINFTY));
|
|
|
|
|
assert(0==ibz_cmp(&temp,&ideal_signing_test.norm));
|
|
|
|
|
quat_alg_conj(&delta,&gen);
|
|
|
|
|
quat_lideal_create_from_primitive(&ideal_signing_test,&delta,&ideal_eichler_rand.norm,&right_order_key,&QUATALG_PINFTY);
|
|
|
|
|
assert(quat_lideal_equals(&ideal_signing_test,&ideal_eichler_rand,&QUATALG_PINFTY));
|
2023-07-11 11:30:28 +02:00
|
|
|
quat_left_ideal_finalize(&ideal_signing_test);
|
2023-06-01 00:00:00 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// checking cyclicity
|
|
|
|
|
quat_alg_conj(&delta,&gen);
|
|
|
|
|
assert(quat_lattice_contains(&coeffs,&ideal_eichler_rand.lattice,&delta,&QUATALG_PINFTY));
|
|
|
|
|
// quat_alg_elem_copy(&delta,&gen);
|
|
|
|
|
quat_alg_mul(&delta,&delta,&gen_challenge,&QUATALG_PINFTY);
|
|
|
|
|
ibz_mul(&delta.denom,&delta.denom,&ideal_eichler_rand.norm);
|
|
|
|
|
quat_alg_normalize(&delta);
|
|
|
|
|
assert(quat_lattice_contains(&coeffs,&right_order_key,&delta,&QUATALG_PINFTY));
|
|
|
|
|
found = found && quat_alg_is_primitive(&delta,&right_order_key,&QUATALG_PINFTY);
|
|
|
|
|
if (!found) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(SQISIGN_signing_length == KLPT_signing_klpt_length/TORSION_PLUS_EVEN_POWER);
|
|
|
|
|
|
|
|
|
|
found = found && id2iso_ideal_to_isogeny_two_long_power_of_2(&sig->zip,&curve,&basis_minus,&basis_plus,&kernel_dual,&gen,SQISIGN_signing_length,&sk->lideal_small,&sk->lideal_two,&sk->gen_two,&QUATALG_PINFTY);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if (!found)
|
|
|
|
|
// return found;
|
|
|
|
|
|
|
|
|
|
// quick check to see if we got the correct curve in the end
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
if (found) {
|
|
|
|
|
fp2_t jchall, jresp;
|
|
|
|
|
ec_j_inv(&jchall, &E2_for_testing);
|
|
|
|
|
ec_j_inv(&jresp, &curve);
|
|
|
|
|
assert(fp2_is_equal(&jchall, &jresp));
|
|
|
|
|
} else {
|
|
|
|
|
printf("signature failed \n");
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// var finalize
|
|
|
|
|
ibq_finalize(&ibq_norm);
|
|
|
|
|
ibz_finalize(&norm);ibz_finalize(&temp);
|
|
|
|
|
ibz_finalize(&remainder);
|
|
|
|
|
quat_order_finalize(&right_order_key);
|
|
|
|
|
quat_left_ideal_finalize(&ideal_commit);
|
|
|
|
|
quat_left_ideal_finalize(&ideal_challenge);
|
|
|
|
|
quat_alg_elem_finalize(&gen);
|
|
|
|
|
quat_alg_elem_finalize(&gen_small);
|
|
|
|
|
quat_alg_elem_finalize(&delta);
|
|
|
|
|
ibz_mat_4x4_finalize(&reduced);
|
|
|
|
|
ibz_mat_4x4_finalize(&gram);
|
|
|
|
|
quat_alg_coord_finalize(&coeffs);
|
|
|
|
|
quat_left_ideal_finalize(&ideal_comchall);
|
|
|
|
|
quat_left_ideal_finalize(&ideal_seccomchall);
|
|
|
|
|
quat_left_ideal_finalize(&ideal_eichler_rand);
|
|
|
|
|
quat_left_ideal_finalize(&ideal_pullback);
|
|
|
|
|
quat_left_ideal_finalize(&ideal_input_klpt);
|
|
|
|
|
quat_alg_elem_finalize(&gen_challenge);
|
|
|
|
|
|
|
|
|
|
return found;
|
|
|
|
|
}
|
|
|
|
|
|