コード例 #1
0
ファイル: poly.c プロジェクト: enascimento/supercop
poly_t * poly_syndrome_init(poly_t generator, gf_t *support, int n)
{
    int i,j,t;
    gf_t a;
    poly_t * F;

    F = malloc(n * sizeof (poly_t));
    t = poly_deg(generator);

    //g(z)=g_t+g_(t-1).z^(t-1)+......+g_1.z+g_0
    //f(z)=f_(t-1).z^(t-1)+......+f_1.z+f_0

    for(j=0; j<n; j++)
    {
        F[j] = poly_alloc(t-1);
        poly_set_coeff(F[j],t-1,gf_unit());
        for(i=t-2; i>=0; i--)
        {
            poly_set_coeff(F[j],i,gf_add(poly_coeff(generator,i+1),
                                         gf_mul(support[j],poly_coeff(F[j],i+1))));
        }
        a = gf_add(poly_coeff(generator,0),gf_mul(support[j],poly_coeff(F[j],0)));
        for(i=0; i<t; i++)
        {
            poly_set_coeff(F[j],i, gf_div(poly_coeff(F[j],i),a));
        }
    }

    return F;
}
コード例 #2
0
ファイル: poly.c プロジェクト: enascimento/supercop
// le corps est déjà défini
// retourne un polynôme unitaire de degré t irreductible dans le corps
poly_t poly_randgen_irred(int t, int (*u8rnd)()) {
    int i;
    poly_t g;

    g = poly_alloc(t);
    poly_set_deg(g, t);
    poly_set_coeff(g, t, gf_unit());

    i = 0;
    do
        for (i = 0; i < t; ++i)
            poly_set_coeff(g, i, gf_rand(u8rnd));
    while (poly_degppf(g) < t);

    return g;
}
コード例 #3
0
ファイル: poly.c プロジェクト: LZChuan/minimal_scene
/* Subtract two polynomials */
poly_t *poly_diff(poly_t *p, poly_t *q) {
    int n = MAX(p->n, q->n);
    poly_t *r = poly_new(n);
    int i;

    for (i = 0; i < n + 1; i++) {
	double c = poly_get_coeff(p, i) - poly_get_coeff(q, i);
	poly_set_coeff(r, i, c);
    }

    return r;
}
コード例 #4
0
ファイル: poly.c プロジェクト: enascimento/supercop
poly_t * poly_sqrtmod_init(poly_t g) {
    int i, t;
    poly_t * sqrt, aux, p, q, * sq_aux;

    t = poly_deg(g);

    sq_aux = malloc(t * sizeof (poly_t));
    for (i = 0; i < t; ++i)
        sq_aux[i] = poly_alloc(t - 1);
    poly_sqmod_init(g, sq_aux);

    q = poly_alloc(t - 1);
    p = poly_alloc(t - 1);
    poly_set_deg(p, 1);
    poly_set_coeff(p, 1, gf_unit());
    // q(z) = 0, p(z) = z
    for (i = 0; i < t * gf_extd() - 1; ++i) {
        // q(z) <- p(z)^2 mod g(z)
        poly_sqmod(q, p, sq_aux, t);
        // q(z) <-> p(z)
        aux = q;
        q = p;
        p = aux;
    }
    // p(z) = z^(2^(tm-1)) mod g(z) = sqrt(z) mod g(z)

    sqrt = malloc(t * sizeof (poly_t));
    for (i = 0; i < t; ++i)
        sqrt[i] = poly_alloc(t - 1);

    poly_set(sqrt[1], p);
    poly_calcule_deg(sqrt[1]);
    for(i = 3; i < t; i += 2) {
        poly_set(sqrt[i], sqrt[i - 2]);
        poly_shiftmod(sqrt[i], g);
        poly_calcule_deg(sqrt[i]);
    }

    for (i = 0; i < t; i += 2) {
        poly_set_to_zero(sqrt[i]);
        sqrt[i]->coeff[i / 2] = gf_unit();
        sqrt[i]->deg = i / 2;
    }

    for (i = 0; i < t; ++i)
        poly_free(sq_aux[i]);
    free(sq_aux);
    poly_free(p);
    poly_free(q);

    return sqrt;
}
コード例 #5
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;
}
コード例 #6
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;
}
コード例 #7
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;
}
コード例 #8
0
ファイル: poly.c プロジェクト: enascimento/supercop
void poly_sqmod_init(poly_t g, poly_t * sq) {
    int i, d;

    d = poly_deg(g);

    for (i = 0; i < d / 2; ++i) {
        // sq[i] = x^(2i) mod g = x^(2i)
        poly_set_to_zero(sq[i]);
        poly_set_deg(sq[i], 2 * i);
        poly_set_coeff(sq[i], 2 * i, gf_unit());
    }

    for (; i < d; ++i) {
        // sq[i] = x^(2i) mod g = (x^2 * sq[i-1]) mod g
        memset(sq[i]->coeff, 0, 2 * sizeof (gf_t));
        memcpy(sq[i]->coeff + 2, sq[i - 1]->coeff, d * sizeof (gf_t));
        poly_set_deg(sq[i], poly_deg(sq[i - 1]) + 2);
        poly_rem(sq[i], g);
    }
}
コード例 #9
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);
    }
}
コード例 #10
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);
}
コード例 #11
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);
}
コード例 #12
0
int main(void) {
  field_t fp, fx;
  mpz_t prime;
  darray_t list;
  int p = 7;

  // Exercise poly_is_irred() with a sieve of Erastosthenes for polynomials.
  darray_init(list);
  mpz_init(prime);
  mpz_set_ui(prime, p);
  field_init_fp(fp, prime);
  field_init_poly(fx, fp);
  element_t e;
  element_init(e, fp);
  // Enumerate polynomials in F_p[x] up to degree 2.
  int a[3], d;
  a[0] = a[1] = a[2] = 0;
  for(;;) {
    element_ptr f = pbc_malloc(sizeof(*f));
    element_init(f, fx);
    int j;
    for(j = 0; j < 3; j++) {
      element_set_si(e, a[j]);
      poly_set_coeff(f, e, j);
    }

    // Test poly_degree().
    for(j = 2; !a[j] && j >= 0; j--);
    EXPECT(poly_degree(f) == j);

    // Add monic polynomials to the list.
    if (j >= 0 && a[j] == 1) darray_append(list, f);
    else {
      element_clear(f);
      free(f);
    }

    // Next!
    d = 0;
    for(;;) {
      a[d]++;
      if (a[d] >= p) {
        a[d] = 0;
        d++;
        if (d > 2) goto break2;
      } else break;
    }
  }
break2: ;

  // Find all composite monic polynomials of degree 3 or less.
  darray_t prodlist;
  darray_init(prodlist);

  void outer(void *data) {
    element_ptr f = data;
    void inner(void *data2) {
      element_ptr g = data2;
      if (!poly_degree(f) || !poly_degree(g)) return;
      if (poly_degree(f) + poly_degree(g) > 3) return;
      element_ptr h = pbc_malloc(sizeof(*h));
      element_init(h, fx);
      element_mul(h, f, g);
      darray_append(prodlist, h);
      EXPECT(!poly_is_irred(h));
    }
コード例 #13
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);
}