コード例 #1
0
ファイル: poly.c プロジェクト: enascimento/supercop
// retourne le degré du plus petit facteur
int poly_degppf(poly_t g) {
    int i, d, res;
    poly_t *u, p, r, s;

    d = poly_deg(g);
    u = malloc(d * sizeof (poly_t *));
    for (i = 0; i < d; ++i)
        u[i] = poly_alloc(d + 1);
    poly_sqmod_init(g, u);

    p = poly_alloc(d - 1);
    poly_set_deg(p, 1);
    poly_set_coeff(p, 1, gf_unit());
    r = poly_alloc(d - 1);
    res = d;
    for (i = 1; i <= (d / 2) * gf_extd(); ++i) {
        poly_sqmod(r, p, u, d);
        // r = x^(2^i) mod g
        if ((i % gf_extd()) == 0) { // donc 2^i = (2^m)^j (m deg d'extension)
            poly_addto_coeff(r, 1, gf_unit());
            poly_calcule_deg(r); // le degré peut changer
            s = poly_gcd(g, r);
            if (poly_deg(s) > 0) {
                poly_free(s);
                res = i / gf_extd();
                break;
            }
            poly_free(s);
            poly_addto_coeff(r, 1, gf_unit());
            poly_calcule_deg(r); // le degré peut changer
        }
        // on se sert de s pour l'échange
        s = p;
        p = r;
        r = s;
    }

    poly_free(p);
    poly_free(r);
    for (i = 0; i < d; ++i) {
        poly_free(u[i]);
    }
    free(u);

    return res;
}
コード例 #2
0
ファイル: poly.c プロジェクト: robobenklein/gpg-pqcrypt
// Returns the degree of the smallest factor
int poly_degppf(poly_t g) {
  int i, d, res;
  poly_t *u, p, r, s;

  d = poly_deg(g);
  u = malloc(d * sizeof (poly_t *));
  for (i = 0; i < d; ++i)
    u[i] = poly_alloc(d + 1);
  poly_sqmod_init(g, u);

  p = poly_alloc(d - 1);
  poly_set_deg(p, 1);
  poly_set_coeff(p, 1, gf_unit());
  r = poly_alloc(d - 1);
  res = d;
  for (i = 1; i <= (d / 2) * gf_extd(); ++i) {
    poly_sqmod(r, p, u, d);
    // r = x^(2^i) mod g
    if ((i % gf_extd()) == 0) { // so 2^i = (2^m)^j (m ext. degree)
      poly_addto_coeff(r, 1, gf_unit());
      poly_calcule_deg(r); // The degree may change
      s = poly_gcd(g, r);
      if (poly_deg(s) > 0) {
	poly_free(s);
	res = i / gf_extd();
	break;
      }
      poly_free(s);
      poly_addto_coeff(r, 1, gf_unit());
      poly_calcule_deg(r); // The degree may change
    }
    // No need for the exchange s
    s = p;
    p = r;
    r = s;
  }

  poly_free(p);
  poly_free(r);
  for (i = 0; i < d; ++i) {
    poly_free(u[i]);
  }
  free(u);

  return res;
}
コード例 #3
0
ファイル: poly.c プロジェクト: enascimento/supercop
poly_t poly_mul(poly_t p, poly_t q) {
    int i,j,dp,dq;
    poly_t r;

    poly_calcule_deg(p);
    poly_calcule_deg(q);
    dp = poly_deg(p);
    dq = poly_deg(q);
    r=poly_alloc(dp+dq);
    for (i = 0; i <= dp; ++i)
        for (j = 0; j <= dq; ++j)
            poly_addto_coeff(r,i+j,gf_mul(poly_coeff(p,i),poly_coeff(q,j)));
    poly_calcule_deg(r);

    return(r);
}
コード例 #4
0
ファイル: poly.c プロジェクト: enascimento/supercop
// 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);
    }
}
コード例 #5
0
ファイル: poly.c プロジェクト: enascimento/supercop
// 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);
}
コード例 #6
0
ファイル: poly.c プロジェクト: robobenklein/gpg-pqcrypt
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;
}
コード例 #7
0
ファイル: poly.c プロジェクト: robobenklein/gpg-pqcrypt
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);
}
コード例 #8
0
ファイル: poly.c プロジェクト: enascimento/supercop
// 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);
}