int poly_calcule_deg(poly_t p) { int d = p->size - 1; while ((d >= 0) && (p->coeff[d] == gf_zero())) --d; p->deg = d; return d; }
gf_t poly_eval_aux(gf_t * coeff, gf_t a, int d) { gf_t b; b = coeff[d--]; for (; d >= 0; --d) if (b != gf_zero()) b = gf_add(gf_mul(b, a), coeff[d]); else b = coeff[d]; return b; }
// p contiendra son reste modulo g void poly_rem(poly_t p, poly_t g) { int i, j, d; gf_t a, b; d = poly_deg(p) - poly_deg(g); if (d >= 0) { a = gf_inv(poly_tete(g)); for (i = poly_deg(p); d >= 0; --i, --d) { if (poly_coeff(p, i) != gf_zero()) { b = gf_mul_fast(a, poly_coeff(p, i)); for (j = 0; j < poly_deg(g); ++j) poly_addto_coeff(p, j + d, gf_mul_fast(b, poly_coeff(g, j))); poly_set_coeff(p, i, gf_zero()); } } poly_set_deg(p, poly_deg(g) - 1); while ((poly_deg(p) >= 0) && (poly_coeff(p, poly_deg(p)) == gf_zero())) poly_set_deg(p, poly_deg(p) - 1); } }
// carré de p modulo un certain polynôme g, sq[] contient les carrés // modulo g de la base canonique des polynômes de degré < d, où d est // le degré de g. La table sq[] sera calculée par poly_sqmod_init() void poly_sqmod(poly_t res, poly_t p, poly_t * sq, int d) { int i, j; gf_t a; poly_set_to_zero(res); // termes de bas degré for (i = 0; i < d / 2; ++i) poly_set_coeff(res, i * 2, gf_square(poly_coeff(p, i))); // termes de haut degré for (; i < d; ++i) { if (poly_coeff(p, i) != gf_zero()) { a = gf_square(poly_coeff(p, i)); for (j = 0; j < d; ++j) poly_addto_coeff(res, j, gf_mul_fast(a, poly_coeff(sq[i], j))); } } // mise à jour du degré poly_set_deg(res, d - 1); while ((poly_deg(res) >= 0) && (poly_coeff(res, poly_deg(res)) == gf_zero())) poly_set_deg(res, poly_deg(res) - 1); }
poly_t poly_quo(poly_t p, poly_t d) { int i, j, dd, dp; gf_t a, b; poly_t quo, rem; dd = poly_calcule_deg(d); dp = poly_calcule_deg(p); rem = poly_copy(p); quo = poly_alloc(dp - dd); poly_set_deg(quo, dp - dd); a = gf_inv(poly_coeff(d, dd)); for (i = dp; i >= dd; --i) { b = gf_mul_fast(a, poly_coeff(rem, i)); poly_set_coeff(quo, i - dd, b); if (b != gf_zero()) { poly_set_coeff(rem, i, gf_zero()); for (j = i - 1; j >= i - dd; --j) poly_addto_coeff(rem, j, gf_mul_fast(b, poly_coeff(d, dd - i + j))); } } poly_free(rem); return quo; }
void poly_sqmod(poly_t res, poly_t p, poly_t * sq, int d) { int i, j; gf_t a; poly_set_to_zero(res); // terms of low degree for (i = 0; i < d / 2; ++i) poly_set_coeff(res, i * 2, gf_square(poly_coeff(p, i))); // terms of high degree for (; i < d; ++i) { if (poly_coeff(p, i) != gf_zero()) { a = gf_square(poly_coeff(p, i)); for (j = 0; j < d; ++j) poly_addto_coeff(res, j, gf_mul_fast(a, poly_coeff(sq[i], j))); } } // Update degre poly_set_deg(res, d - 1); while ((poly_deg(res) >= 0) && (poly_coeff(res, poly_deg(res)) == gf_zero())) poly_set_deg(res, poly_deg(res) - 1); }
// On suppose deg(g) >= deg(p) void poly_eeaux(poly_t * u, poly_t * v, poly_t p, poly_t g, int t) { int i, j, dr, du, delta; gf_t a; poly_t aux, r0, r1, u0, u1; // initialisation des variables locales // r0 <- g, r1 <- p, u0 <- 0, u1 <- 1 dr = poly_deg(g); r0 = poly_alloc(dr); r1 = poly_alloc(dr - 1); u0 = poly_alloc(dr - 1); u1 = poly_alloc(dr - 1); poly_set(r0, g); poly_set(r1, p); poly_set_to_zero(u0); poly_set_to_zero(u1); poly_set_coeff(u1, 0, gf_unit()); poly_set_deg(u1, 0); // invariants: // r1 = u1 * p + v1 * g // r0 = u0 * p + v0 * g // et deg(u1) = deg(g) - deg(r0) // on s'arrête lorsque deg(r1) < t (et deg(r0) >= t) // et donc deg(u1) = deg(g) - deg(r0) < deg(g) - t du = 0; dr = poly_deg(r1); delta = poly_deg(r0) - dr; while (dr >= t) { for (j = delta; j >= 0; --j) { a = gf_div(poly_coeff(r0, dr + j), poly_coeff(r1, dr)); if (a != gf_zero()) { // u0(z) <- u0(z) + a * u1(z) * z^j for (i = 0; i <= du; ++i) { poly_addto_coeff(u0, i + j, gf_mul_fast(a, poly_coeff(u1, i))); } // r0(z) <- r0(z) + a * r1(z) * z^j for (i = 0; i <= dr; ++i) poly_addto_coeff(r0, i + j, gf_mul_fast(a, poly_coeff(r1, i))); } } // échanges aux = r0; r0 = r1; r1 = aux; aux = u0; u0 = u1; u1 = aux; du = du + delta; delta = 1; while (poly_coeff(r1, dr - delta) == gf_zero()) delta++; dr -= delta; } poly_set_deg(u1, du); poly_set_deg(r1, dr); //return u1 and r1; *u=u1; *v=r1; poly_free(r0); poly_free(u0); }