コード例 #1
0
ファイル: GHKeyGen.java プロジェクト: B-Rich/crypto
  /**
   * Method based on FFT to find the determinant and the first coefficient of w(x) this suffices to
   * find w(x) completely
   *
   * @param q the polynomial
   * @param n the degree
   * @return The determinant and the first coefficient of w(x).
   */
  static BigInteger[] gzModZ2(Polynomial q, int n) {
    int i;
    int N = 1 << n;

    Polynomial V = new Polynomial(q.coeffs); // V = q
    Polynomial U = new Polynomial(1); // U = 1
    U.setCoeff(0, new BigInteger("1"));
    Polynomial F = new Polynomial(N); // F(x) = x^N +1
    F.setCoeff(0, new BigInteger("1"));
    F.setCoeff(N, new BigInteger("1"));
    Polynomial V2 = new Polynomial(N);

    while (N > 1) {
      V2 = new Polynomial(V.coeffs);
      for (i = 1; i <= V2.degree; i += 2) { // set V2(x) := V(-x)
        V2.coeffs[i] = V2.coeffs[i].negate(); // negate odd coefficients
      }
      V = Polynomial.mod(Polynomial.mult(V, V2), F); // V := V(x) * V(-x) mod f(x)
      U = Polynomial.mod(Polynomial.mult(U, V2), F); // U := U(x) * V(-x) mod f(x)

      // Sanity-check: verify that the odd coefficients in V are zero
      for (i = 1; i <= V.degree; i += 2)
        if (!V.coeffs[i].equals(new BigInteger("0"))) {
          return null;
        }

      // "Compress" the non-zero coefficients of V
      for (i = 1; i <= V.degree / 2; i++) V.coeffs[i] = V.coeffs[2 * i];
      for (; i <= V.degree; i++) V.coeffs[i] = new BigInteger("0");
      V.normalize();

      // Set U to the "compressed" ( U(x) + U(-x) ) /2
      for (i = 0; i <= U.degree / 2; i++) U.coeffs[i] = U.coeffs[2 * i];
      for (; i <= U.degree; i++) U.coeffs[i] = new BigInteger("0");
      U.normalize();

      // Set N := N/2 and update F accordingly
      F.coeffs[N] = new BigInteger("0");
      N >>= 1;
      F.coeffs[N] = new BigInteger("1");
      F.normalize();
    }

    return new BigInteger[] {V.coeffs[0], U.coeffs[0]};
  }