@Override
 public String toString() {
   String result = "";
   result += num.toString() + "\r\n";
   result += "---------\r\n";
   result += den.toString();
   return result;
 }
  /**
   * Return the contangent of a double.
   *
   * @param x The number whose cotangent is desired.
   * @return The cotangent.
   *     <p>This method is a modified version of the one in the Visual Numerics Sfun class.
   */
  public static double cot(double x) {
    double ans, ainty, ainty2, prodbg, y, yrem;
    double pi2rec = 0.011619772367581343075535053490057; //  2/PI - 0.625

    y = Math.abs(x);

    // 4.5036e+15 = 1.0/EPSILON_LARGE

    if (y > 4.5036e+15) {
      return Double.NaN;
    }

    // Carefully compute
    // Y * (2/PI) = (AINT(Y) + REM(Y)) * (.625 + PI2REC)
    //      = AINT(.625*Y) + REM(.625*Y) + Y*PI2REC  =  AINT(.625*Y) + Z
    //      = AINT(.625*Y) + AINT(Z) + REM(Z)

    ainty = (int) y;
    yrem = y - ainty;
    prodbg = 0.625D * ainty;
    ainty = (int) prodbg;
    y = (prodbg - ainty) + 0.625D * yrem + y * pi2rec;
    ainty2 = (int) y;
    ainty = ainty + ainty2;
    y = y - ainty2;

    int ifn = (int) (ainty % 2.0);

    if (ifn == 1) y = 1.0D - y;

    if (y == 0.0D) {
      ans = Double.POSITIVE_INFINITY;
    }
    // 1.82501e-08 = Math.sqrt(3.0*EPSILON_SMALL)

    else if (y <= 1.82501e-08) {
      ans = 1.0D / y;
    } else if (y <= 0.25D) {
      ans = (0.5D + Polynomial.evaluateChebyschev(COT_COEF, 32.0D * y * y - 1.0D)) / y;
    } else if (y <= 0.5D) {
      ans = (0.5D + Polynomial.evaluateChebyschev(COT_COEF, 8.0D * y * y - 1.0D)) / (0.5D * y);

      ans = (ans * ans - 1.0D) * 0.5D / ans;
    } else {
      ans = (0.5D + Polynomial.evaluateChebyschev(COT_COEF, 2.0D * y * y - 1.0D)) / (0.25D * y);

      // $$$PIB$$$ Is one of the following two lines bogus?

      ans = (ans * ans - 1.0D) * 0.5D / ans;
      ans = (ans * ans - 1.0D) * 0.5D / ans;
    }

    if (x != 0.0D) ans = sign(ans, x);

    if (ifn == 1) ans = -ans;

    return ans;
  }
Example #3
0
  public static void main(String[] args) {

    Polynomial vec = new Polynomial();
    vec.add(10, 0);
    vec.add(15, 1);
    vec.add(65, 8);
    System.out.println("vec1: " + vec);
    System.out.println();

    //		Polynomial vec2 = new Polynomial();
    //		vec2.add(16, 2);
    //		vec2.add(34, 5);
    //		System.out.println("vec2: " + vec2);
    //		System.out.println();
    //
    //		Polynomial vecTest = new Polynomial();
    //		vecTest.polySum(vec2);
    //		System.out.println("vec16: " + vecTest);
    //		System.out.println();
    //
    //		Polynomial vec3 = new Polynomial();
    //		vec3 = vec3.polySumBoth(vec, vec2);
    //		System.out.println("vec3: " + vec3);
    //		System.out.println();
    //
    //		Polynomial vec4 = new Polynomial();
    //		vec4 = vec4.polyMultiByConstant(vec, 5);
    //		System.out.println("vec4: " + vec4);
    //		System.out.println();
    //
    //		Polynomial vec5 = new Polynomial();
    //		vec5 = vec5.polyMultiplicate(vec, vec2);
    //		System.out.println("vec5: " + vec5);
    //		System.out.println();
    //
    //		Polynomial vec6 = new Polynomial();
    //		vec6 = vec6.polySubstract(vec, vec2);
    //		System.out.println("vec6: " + vec6);
    //		System.out.println();
    //
    //		Polynomial vec7 = new Polynomial(vec3);
    //		vec7 = vec7.firstDerivative();
    //		System.out.println("vec7 first derivative from vec3: " + vec7);
    //		System.out.println();
    //
    //		System.out.println("Evaluate vec1, x = 5 : " + vec.evaluate(5));
    //		System.out.println();
    //		System.out.println();
    //
    //		Polynomial vec8 = new Polynomial();
    //		vec8 = Polynomial.fromString("15x^2 + 18x^4 + 10 + 5x^2 + -2x^8");
    //		System.out.println(vec8);

  }
Example #4
0
  public static void main(String[] args) {
    String datFile = args[0];
    String dstFile = args[1];
    String ansFile = args[2];

    String data = reader.getString(datFile);
    String[] lines = data.split("\n");
    int p = Integer.valueOf(lines[0]);
    int n = Integer.valueOf(lines[1]);
    int[] polynomial = new int[n + 1];
    String[] coefficients = lines[2].split(" ");
    for (int i = 0; i < coefficients.length; i++)
      polynomial[n - i] = Integer.valueOf(coefficients[i]);
    polynomial = Polynomial.clear(polynomial);

    String sigma = reader.getString(dstFile);
    int s = Integer.valueOf(sigma);

    int ml = 0;
    int[][] minimals = new int[2 * s][];

    for (int i = 1; i < s; i++) {
      int[] pol = Polynomial.field(MinimalPolynomial.findPolynomial(polynomial, i, p), p);
      int[] min = MinimalPolynomial.findMinimal(pol, polynomial, p);
      minimals[ml] = min;
      ml++;
    }

    Set<List<Integer>> clean = removeDuplicates(minimals, ml);
    int[] result = {1};
    for (List<Integer> a : clean) {
      int[] t = toArray(a);
      result = Polynomial.field(Polynomial.multiply(result, t), p);
    }

    StringBuilder res = new StringBuilder();
    res.append(p);
    res.append("\n");
    res.append(new Double(Math.pow(p, n)).intValue() - 1);
    res.append("\n");
    for (int i = result.length - 1; i >= -(Math.pow(p, n) - 1 - result.length); i--) {
      if (i < 0) res.append("0");
      else res.append(result[i]);
      res.append(" ");
    }

    res.append("\n");

    writer.writeString(ansFile, res.toString());
  }
  /**
   * * extracts hardened password from features and password
   *
   * @param features
   * @param password
   * @return hardened password
   */
  private static BigInteger extractHardenedPwd(long[] features, String password) {
    List<Point> points = new LinkedList<Point>();
    InstructionTable iTable = InstructionTable.loadTable(Constants.INSTRUCTION_TABLE_FILE_PATH);

    for (int i = 0; i < features.length; i++) {
      int index = iTable.get(i).getIndex();
      BigInteger x = null, y = null;

      switch (InstructionTable.getPosition(features[i], i)) {
        case ALPHA:
        case BOTH:
          x = p_function.execute(2 * index);
          y = iTable.get(i).getAlpha().subtract(g_function.execute(2 * index)).mod(Constants.Q);
          break;
        case BETA:
          x = p_function.execute(2 * index + 1);
          y = iTable.get(i).getBeta().subtract(g_function.execute(2 * index + 1)).mod(Constants.Q);
          break;
      }
      points.add(new Point(x, y));
    }

    BigInteger hpwd = Polynomial.generateZerothCoefficientFromPoints(points);
    return hpwd;
  }
  /**
   * Return the hyperbolic tangent of a double.
   *
   * @param x The value whose hyperbolic tangent is desired.
   * @return The hyperbolic tangent of x.
   *     <p>This method is a modified version of the one in the Visual Numerics Sfun class.
   */
  public static double tanh(double x) {
    double ans, y;

    y = Math.abs(x);

    if (Double.isNaN(x)) {
      ans = Double.NaN;
    }
    // 1.82501e-08 = Math.sqrt(3.0*EPSILON_SMALL)

    else if (y < 1.82501e-08) {
      ans = x;
    } else if (y <= 1.0D) {
      ans = x * (1.0D + Polynomial.evaluateChebyschev(TANH_COEF, 2.0D * x * x - 1.0D));
    }
    // 7.977294885 = -0.5*Math.log(EPSILON_SMALL)

    else if (y < 7.977294885) {
      y = Math.exp(y);
      ans = sign((y - 1.0D / y) / (y + 1.0D / y), x);
    } else {
      ans = sign(1.0D, x);
    }

    return ans;
  }
  /**
   * Compute hyperbolic sine of a double.
   *
   * @param x The number whose hyperbolic sine is desired.
   * @return The hyperbolic sine of x.
   *     <p>This method is a modified version of the one in the Visual Numerics Sfun class.
   */
  public static double sinh(double x) {
    double ans;

    double y = Math.abs(x);

    if (Double.isNaN(x)) {
      ans = Double.NaN;
    } else if (Double.isInfinite(y)) {
      return x;
    }
    // 2.58096e-08 = Math.sqrt( 6.0 * EPSILON_SMAL L)

    else if (y < 2.58096e-08) {
      ans = x;
    } else if (y <= 1.0D) {
      ans = x * (1.0D + Polynomial.evaluateChebyschev(SINH_COEF, 2.0D * x * x - 1.0D));
    } else {
      y = Math.exp(y);

      // 94906265.62 = 1.0/Math.sqrt(EPSILON_SMALL)

      if (y >= 94906265.62D) {
        ans = sign(0.5D * y, x);
      } else {
        ans = sign(0.5D * (y - 1.0D / y), x);
      }
    }

    return ans;
  }
Example #8
0
  public static void derivative(Polynomial poly, Polynomial deriv) {
    deriv.size = poly.size - 1;

    for (int i = 1; i < poly.size; i++) {
      deriv.c[i - 1] = poly.c[i] * i;
    }
  }
  /**
   * Return the inverse (arc) hyperbolic sine of a double.
   *
   * @param x The value whose inverse hyperbolic sine is desired.
   * @return The inverse hyperbolic sine of x.
   *     <p>If x is NaN, the result is NaN.
   *     <p>This method is a modified version of the one in the Visual Numerics Sfun class.
   */
  public static double asinh(double x) {
    double ans;

    double y = Math.abs(x);

    if (Double.isNaN(x)) {
      ans = Double.NaN;
    }
    // 1.05367e-08 = Math.sqrt(EPSILON_SMALL)

    else if (y <= 1.05367e-08) {
      ans = x;
    } else if (y <= 1.0D) {
      ans = x * (1.0D + Polynomial.evaluateChebyschev(ASINH_COEF, 2.0D * x * x - 1.0D));
    }
    // 94906265.62 = 1/Math.sqrt(EPSILON_SMALL)

    else if (y < 94906265.62D) {
      ans = safeLog(y + Math.sqrt(y * y + 1.0D));
    } else {
      ans = 0.69314718055994530941723212145818D + safeLog(y);
    }

    if (x < 0.0D) ans = -ans;

    return ans;
  }
 public boolean equals(Object obj) {
   if (this == obj) {
     return true;
   }
   if (!(obj instanceof GenericPolynomialExtensionField)) {
     return false;
   }
   GenericPolynomialExtensionField other = (GenericPolynomialExtensionField) obj;
   return subfield.equals(other.subfield) && minimalPolynomial.equals(other.minimalPolynomial);
 }
Example #11
0
  /**
   * Polynomial division. Computes both the quotient and the remainder.<br>
   * <br>
   * quotient = numerator/denominator<br>
   * remainder = numerator % denominator
   *
   * @param numerator Numerator in the division. Not modified.
   * @param denominator Denominator in the division. Not modified.
   * @param quotient Output quotient, Modified.
   * @param remainder Output remainder. Modified.
   */
  public static void divide(
      Polynomial numerator, Polynomial denominator, Polynomial quotient, Polynomial remainder) {
    int nn = numerator.size - 1;
    int nd = denominator.size - 1;

    while (nd >= 0 && denominator.c[nd] == 0) nd -= 1;

    quotient.size = nn - nd + 1;
    remainder.setTo(numerator);

    for (int k = nn - nd; k >= 0; k--) {
      double c = quotient.c[k] = remainder.c[nd + k] / denominator.c[nd];
      for (int j = k + nd; j >= k; j--) {
        remainder.c[j] -= c * denominator.c[j - k];
      }
    }

    // The remainder can't be larger than the denominator
    remainder.size = nd;
  }
Example #12
0
  public static void askUser() {
    Scanner input = new Scanner(System.in);

    System.out.println("Enter a value>");
    double value = input.nextDouble();
    System.out.println("The value is " + myPoly.evaluate(value));
    boolean cont = true;

    while (cont) {
      System.out.println("Continue?>");
      String valueYesNo = input.next();
      if (valueYesNo.equalsIgnoreCase("Yes") || valueYesNo.equals("y")) {
        input = new Scanner(System.in);
        System.out.println("Enter a value>");
        value = input.nextDouble();
        System.out.println("The value is " + myPoly.evaluate(value));
      } else {
        cont = false;
      }
    }
  }
Example #13
0
  /**
   * Multiplies the two polynomials together.
   *
   * @param a Polynomial
   * @param b Polynomial
   * @param result Optional storage parameter for the results. Must be have enough coefficients to
   *     store the results. If null a new instance is declared.
   * @return Results of the multiplication
   */
  public static Polynomial multiply(Polynomial a, Polynomial b, Polynomial result) {

    int N = Math.max(0, a.size() + b.size() - 1);

    if (result == null) {
      result = new Polynomial(N);
    } else {
      if (result.size < N) throw new IllegalArgumentException("Unexpected length of 'result'");
      result.zero();
    }

    for (int i = 0; i < a.size; i++) {
      double coef = a.c[i];

      int index = i;
      for (int j = 0; j < b.size; j++) {
        result.c[index++] += coef * b.c[j];
      }
    }

    return result;
  }
Example #14
0
  public static void main(String[] args) {
    int count = 0;
    myPoly = new Polynomial(Integer.parseInt(args[0]));
    for (int n = 1; n < args.length; n++) {
      if ((Integer.parseInt(args[n]) != 0)) {
        count++;
      }
    }
    for (int i = 1; i < args.length; i++) {
      myPoly.setCoefficients(count, Integer.parseInt(args[i]));
      count--;
    }

    askUser();
  }
  /**
   * * generate password scheme either a) during initialization or b) after successful login
   *
   * @param hpwd
   * @param positions
   * @param password
   */
  private static void generateScheme(BigInteger hpwd, Position[] positions, String password) {
    /* generate new random polynomial */
    Polynomial newPoly = Polynomial.getRandomPolynomial(Constants.M - 1, hpwd);

    /* generate new R value and persist */
    Generator.R = Generator.getRandomInteger(Generator.BIT_LENGTH);
    LoginHandler.getPreferences().put(Constants.PREF_R, Generator.R.toString());

    /* reinitialize P and G functions with new R value */
    initFunctions(password);

    /* generate new Instruction Table and write to file */
    InstructionTable iTable = InstructionTable.generateInstructionTable(positions, newPoly);
    iTable.writeToFile(Constants.INSTRUCTION_TABLE_FILE_PATH);
  }
Example #16
0
  // TODO try using a linear search alg here
  public static double refineRoot(Polynomial poly, double root, int maxIterations) {

    //		for( int i = 0; i < maxIterations; i++ ) {
    //
    //			double v = poly.c[poly.size-1];
    //			double d = v*(poly.size-1);
    //
    //			for( int j = poly.size-1; j > 0; j-- ) {
    //				v = poly.c[j] + v*root;
    //				d = poly.c[j]*j + d*root;
    //			}
    //			v = poly.c[0] + v*root;
    //
    //			if( d == 0 )
    //				return root;
    //
    //			root -= v/d;
    //		}
    //
    //		return root;

    Polynomial deriv = new Polynomial(poly.size());
    derivative(poly, deriv);

    for (int i = 0; i < maxIterations; i++) {

      double v = poly.evaluate(root);
      double d = deriv.evaluate(root);

      if (d == 0) return root;

      root -= v / d;
    }

    return root;
  }
  /**
   * Returns the inverse (arc) hyperbolic tangent of a double.
   *
   * @param x The value whose inverse hyperbolic tangent is desired.
   * @return The arc hyperbolic tangent of x.
   *     <p>If x is NaN or |x|>1, the result is NaN.
   *     <p>This method is a modified version of the one in the Visual Numerics Sfun class.
   */
  public static double atanh(double x) {
    double ans;

    double y = Math.abs(x);

    if (Double.isNaN(x)) {
      ans = Double.NaN;
    }
    // 1.82501e-08 = Math.sqrt(3.0*EPSILON_SMALL)

    else if (y < 1.82501e-08) {
      ans = x;
    } else if (y <= 0.5D) {
      ans = x * (1.0D + Polynomial.evaluateChebyschev(ATANH_COEF, 8.0D * x * x - 1.0D));
    } else if (y < 1.0D) {
      ans = 0.5D * safeLog((1.0D + x) / (1.0D - x));
    } else if (y == 1.0D) {
      ans = x * Double.POSITIVE_INFINITY;
    } else {
      ans = Double.NaN;
    }

    return ans;
  }
 public int hashCode() {
   return subfield.hashCode() ^ Integers.rotateLeft(minimalPolynomial.hashCode(), 16);
 }
Example #19
0
  private static byte[] createBytes(BitBuffer buffer, RSBlock[] rsBlocks) {

    int offset = 0;

    int maxDcCount = 0;
    int maxEcCount = 0;

    int[][] dcdata = new int[rsBlocks.length][];
    int[][] ecdata = new int[rsBlocks.length][];

    for (int r = 0; r < rsBlocks.length; r++) {

      int dcCount = rsBlocks[r].getDataCount();
      int ecCount = rsBlocks[r].getTotalCount() - dcCount;

      maxDcCount = Math.max(maxDcCount, dcCount);
      maxEcCount = Math.max(maxEcCount, ecCount);

      dcdata[r] = new int[dcCount];
      for (int i = 0; i < dcdata[r].length; i++) {
        dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];
      }
      offset += dcCount;

      Polynomial rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
      Polynomial rawPoly = new Polynomial(dcdata[r], rsPoly.getLength() - 1);

      Polynomial modPoly = rawPoly.mod(rsPoly);
      ecdata[r] = new int[rsPoly.getLength() - 1];
      for (int i = 0; i < ecdata[r].length; i++) {
        int modIndex = i + modPoly.getLength() - ecdata[r].length;
        ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0;
      }
    }

    int totalCodeCount = 0;
    for (int i = 0; i < rsBlocks.length; i++) {
      totalCodeCount += rsBlocks[i].getTotalCount();
    }

    byte[] data = new byte[totalCodeCount];

    int index = 0;

    for (int i = 0; i < maxDcCount; i++) {
      for (int r = 0; r < rsBlocks.length; r++) {
        if (i < dcdata[r].length) {
          data[index++] = (byte) dcdata[r][i];
        }
      }
    }

    for (int i = 0; i < maxEcCount; i++) {
      for (int r = 0; r < rsBlocks.length; r++) {
        if (i < ecdata[r].length) {
          data[index++] = (byte) ecdata[r][i];
        }
      }
    }

    return data;
  }
 public int getDimension() {
   return subfield.getDimension() * minimalPolynomial.getDegree();
 }
Example #21
0
  /**
   * Verifies whether the polynomial q yields a lattice with the correct HNF and odd resultant,
   * computes the determinant (or resultant), root and inverse polynomial w(x)
   *
   * @param q the polynomial yielding the lattice
   * @param n the dimension
   * @return True if the polynomial suffices, false otherwise.
   */
  boolean invModFx(Polynomial q, int n) {
    int N = 1 << n;
    BigInteger res, wi = null;

    if (q.degree >= N) return false;

    // compute resultant and w0
    BigInteger w0, w1;
    BigInteger rw[] = gzModZ2(q, n);
    res = rw[0];
    w0 = rw[1];

    if (Functions.isEven(res)) { // Resultant must be odd
      return false;
    }

    // repeat for the polynomial x*q(x) mod x^N+1
    Polynomial qx = new Polynomial(N);
    for (int i = N - 1; i > 0; i--) {
      qx.setCoeff(i, q.coeffs[i - 1]); // copy 1st N-1 coeffs
    }
    qx.setCoeff(0, q.coeffs[N - 1].negate()); // negate last coeff
    qx.normalize();
    rw = gzModZ2(qx, n);
    res = rw[0];
    w1 = rw[1];

    // now that we have res, w0, w1, set root = w1/w0 mod res
    // make sure things are positive
    if (res.signum() == -1) {
      res = res.negate();
      w0 = w0.negate();
      w1 = w1.negate();
    }
    if (w0.signum() < 0) w0 = w0.add(res);
    if (w1.signum() < 0) w1 = w1.add(res);

    BigInteger inv =
        Functions.xgcd(w0, res); // returns a = w0^{-1} if w0 invertible, null otherwise
    if (inv == null) {
      return false; // verify that w0^{-1} exists
    }
    root = w1.multiply(inv).divideAndRemainder(res)[1]; // root= w1 * w0^{-1} mod res

    BigInteger tmp = root.modPow(new BigInteger(Integer.toString(N)), res);
    // it should hold that root^n = -1 mod res
    if (!tmp.add(new BigInteger("1")).equals(res)) {
      return false;
    }
    W = new BigInteger[N]; // get the entire polynomial w(x), for debug purposes
    W[0] = w0;
    W[1] = w1;
    for (int k = 2; k < N; k++) {
      W[k] = W[k - 1].multiply(root).mod(res);
    }
    // for decryption only a single odd coefficient of w(x) is necessary
    int i = 0;
    if (((w0.compareTo(res.shiftRight(1)) <= 0) && Functions.isOdd(w0))
        || ((w0.compareTo(res.shiftRight(1)) > 0) && Functions.isEven(w0))) {
      wi = w0;
    } else {
      if (((w1.compareTo(res.shiftRight(1)) <= 0) && Functions.isOdd(w1))
          || ((w1.compareTo(res.shiftRight(1)) > 0) && Functions.isEven(w1))) {
        wi = w1;
      } else {
        for (i = 2; i < N; i++) {
          w1 = w1.multiply(root).mod(res); // (w1.multiply(root)).divideAndRemainder(res)[1];
          if (((w1.compareTo(res.shiftRight(1)) <= 0) && Functions.isOdd(w1))
              || ((w1.compareTo(res.shiftRight(1)) > 0) && Functions.isEven(w1))) {
            wi = w1;
            break;
          }
        }
      }
    }

    det = res;
    w = wi;
    return ((i == N) ? false : true); // We get i==N only if all the wi's are even
  }
Example #22
0
  /**
   * 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]};
  }
Example #23
0
  /**
   * Generates a new key pair given the parameters in fheparams, stores the key locally and in the
   * keypair parameter
   *
   * @param fheparams the scheme parameters
   * @param keyPair holds the keypair
   */
  public GHKeyGen(FHEParams fheparams, GHKeyPair keyPair, IProgressMonitor monitor, int work) {
    t = fheparams.t;
    n = 1 << fheparams.logn;

    SubProgressMonitor sm = new SubProgressMonitor(monitor, work / 3);
    sm.beginTask("", work / 3);
    do { // try until HNF has the desired form, i.e. determinant is odd and lattice contains the
         // vector (-r,1,0,...,0)
      // generate random polynomial with coefficients uniformly random in [-2^t,2^t]
      v = Polynomial.randomPolynomial(n - 1, t);

      // verify whether the coefficient sum is odd, otherwise add 1
      int parity = 0;
      for (int i = 0; i < n; i++) {
        parity ^= (v.coeffs[i].testBit(0) ? 1 : 0);
      }
      if (parity == 0) v.coeffs[0].add(new BigInteger("1"));
      if (sm.isCanceled()) return;

    } while (!invModFx(v, fheparams.logn));
    sm.done();
    sm.beginTask("", work / 3);
    BigInteger sum = new BigInteger("0");
    BigInteger factor;
    // the public key blocks that squash the decryption scheme
    pkBlocksX = new BigInteger[fheparams.s];
    // the correct power such that \sum_pkBlocksX[i]*R^pkBlocksIdX[i] = w mod d
    int[] pkBlocksIdX = new int[fheparams.s];
    // make sure the sum is correct
    boolean sumtest = false;

    while (!sumtest) {
      sum = new BigInteger("0");
      // generate the first s-1 randomly
      for (int i = 0; i < fheparams.s - 1; i++) {
        byte[] temp = new byte[det.bitLength() / 8];
        r.nextBytes(temp);
        pkBlocksX[i] = (new BigInteger(temp)).abs().mod(det);
        pkBlocksIdX[i] = r.nextInt(fheparams.S);
        factor =
            (new BigInteger("2"))
                .modPow(
                    (new BigInteger(Integer.toString(pkBlocksIdX[i])))
                        .multiply(new BigInteger(Integer.toString(fheparams.logR))),
                    det);
        factor = (factor.multiply(pkBlocksX[i])).mod(det);
        sum = (sum.add(factor)).mod(det);
      }
      sum = w.subtract(sum).mod(det);
      // calculate the last x_i from the first s-1, try until the sum is invertible
      while (pkBlocksX[fheparams.s - 1] == null) {
        try {
          pkBlocksIdX[fheparams.s - 1] = r.nextInt(fheparams.S);
          factor =
              new BigInteger("2")
                  .modPow(
                      (new BigInteger(Integer.toString(pkBlocksIdX[fheparams.s - 1])))
                          .multiply(new BigInteger(Integer.toString(fheparams.logR))),
                      det);
          factor = factor.modInverse(det);
          pkBlocksX[fheparams.s - 1] = sum.multiply(factor).mod(det);
        } catch (ArithmeticException e) {

        }
        if (sm.isCanceled()) return;
      }
      // check whether \sum_pkBlocksX[i]*R^pkBlocksIdX[i] = w mod d
      sum = new BigInteger("0");
      for (int i = 0; i < fheparams.s; i++) {
        factor =
            new BigInteger("2")
                .modPow(
                    new BigInteger(Integer.toString(pkBlocksIdX[i]))
                        .multiply(new BigInteger(Integer.toString(fheparams.logR))),
                    det);
        factor = factor.multiply(pkBlocksX[i]).mod(det);
        sum = sum.add(factor).mod(det);
      }
      if (sum.compareTo(w) == 0) {
        sumtest = true;
      }
      if (sm.isCanceled()) return;
    }
    sm.done();
    // Compute the number of ciphertext for each progression,
    // i.e., an integer N such that N(N-1)/2 > S
    sm.beginTask("", work / 3);
    int nCtxts = (int) Math.ceil(2 * Math.sqrt(fheparams.S));
    int[] bits = new int[nCtxts * fheparams.s];
    for (int i = 0; i < fheparams.s; i++) {
      // let j1,j2 be the idx'th pair in {nCtxts choose 2}
      int j1, j2;
      int[] temp = encodeIndex(pkBlocksIdX[i], nCtxts);
      j1 = temp[0];
      j2 = temp[1];
      bits[i * nCtxts + j1] = bits[i * nCtxts + j2] = 1; // set these two bits to one
      if (sm.isCanceled()) return;
    }
    sm.done();
    ctxts = GHEncrypt.encrypt(fheparams, this, bits);
    keyPair.setKeyPair(det, root, w, ctxts, pkBlocksX);
  }
  // Update "shape" and "segments" from the current value of "points":
  void updateShape() {
    if (points.size() < 2) {
      shape = null;
      segments.clear();
      return;
    }
    // Pad out the control point list using wraparound,
    // to make a closed spline:

    ArrayList extraPoints = new ArrayList(points);
    extraPoints.add(0, points.get(points.size() - 2));
    extraPoints.add(1, points.get(points.size() - 1));
    extraPoints.add(points.get(0));
    extraPoints.add(points.get(1));

    // Rotate the padded points so generated segment indices will align
    // with indices in the points ArrayList:

    Object first = extraPoints.get(0);
    extraPoints.remove(0);
    extraPoints.add(first);

    GeneralPath path = new GeneralPath();

    int m = extraPoints.size();
    ensureBases(m);

    segments.clear();

    // Iterate over segments:
    for (int i = 3; i < m - 1; i++) {

      Polynomial xNum = new Polynomial(0);
      Polynomial yNum = new Polynomial(0);

      Polynomial xDen = new Polynomial(0);
      Polynomial yDen = new Polynomial(0);

      // Iterate over control points:
      for (int j = 0; j < m; j++) {

        Point2D p = (Point2D) extraPoints.get(j);

        BasisFunction basis = (BasisFunction) Bases.get(j);

        double px = p.getX();
        double py = p.getY();

        Polynomial xSegNum = basis.getSegment(i).multiply(px * Weight);
        Polynomial ySegNum = basis.getSegment(i).multiply(py * Weight);

        Polynomial xSegDen = basis.getSegment(i).multiply(Weight);
        Polynomial ySegDen = basis.getSegment(i).multiply(Weight);

        xNum = xNum.add(xSegNum);
        yNum = yNum.add(ySegNum);

        xDen = xDen.add(xSegDen);
        yDen = yDen.add(ySegDen);
      }
      Shape curve = Polynomial.createRationalShape(xNum, xDen, yNum, yDen, i, i + 1, .1);
      segments.add(curve);
      path.append(curve, true);
    }
    path.closePath();
    shape = path;
  }
  /* Split into several TFs with denominators of linear or quadratic order. NOTE, DENOMINATOR
  MUST START WITH COEFFICENT 1. NOTE, DOESN'T WORK IF MULTIPLE LINEAR VALUES */
  public TransferFunction[] partialFractions() {
    Polynomial[] factors = den.factorise();
    for (int i = 0; i < factors.length; i++) {
      System.out.println(factors[i]);
    }
    // Handle partial fractions based on denominator type
    int len = factors.length;
    if (len > 3) {
      System.out.println("can't do partial fractions, denominator is too big.");
    }
    // Three linear components
    if (len == 3) {
      // Check
      for (int i = 0; i < 3; i++) {
        if (factors[i].getDegree() > 1) {
          System.out.println("can't do partial fractions, denominator is too big.");
        }
      }
      // Get the linear coefficients a,b,c
      double a = factors[0].getCoefficients()[0];
      double b = factors[1].getCoefficients()[0];
      double c = factors[2].getCoefficients()[0];
      // Get the numerator coefficients A,B,C
      double[] coef_num = num.getCoefficients();
      double A = 0;
      double B = 0;
      double C = 0;
      if (coef_num.length >= 3) A = coef_num[2];
      if (coef_num.length >= 2) B = coef_num[1];
      if (coef_num.length >= 1) C = coef_num[0];
      double[] num2 = new double[1];
      double[] num1 = new double[1];
      double[] num0 = new double[1];

      num2[0] = C / ((a - c) * (c - b));
      num1[0] = (B - num2[0] * (a + c)) / (a + b);
      num0[0] = A - num1[0] - num0[0];
      TransferFunction tf0 = new TransferFunction(new Polynomial(num0), factors[0]);
      TransferFunction tf1 = new TransferFunction(new Polynomial(num1), factors[1]);
      TransferFunction tf2 = new TransferFunction(new Polynomial(num2), factors[2]);
      System.out.println(tf0);
      System.out.println(tf1);
      System.out.println(tf2);
      TransferFunction[] result = new TransferFunction[3];
      result[0] = tf0;
      result[1] = tf1;
      result[2] = tf2;
    }
    // Linear and quadratic, or linear and linear
    if (len == 2) {
      // Linear and quadratic
      if (factors[1].getDegree() == 2) {
        // Get the linear coefficients a,  and quadratic coefficients c,d (scaled by b)
        double a = factors[0].getCoefficients()[0];
        double b = factors[1].getCoefficients()[2];
        double c = factors[1].getCoefficients()[1] / b;
        double d = factors[1].getCoefficients()[0] / b;
        // Get the numerator coefficients A,B,C
        double[] coef_num = num.getCoefficients();
        double A = 0;
        double B = 0;
        double C = 0;
        if (coef_num.length >= 3) A = coef_num[2] / b;
        if (coef_num.length >= 2) B = coef_num[1] / b;
        if (coef_num.length >= 1) C = coef_num[0] / b;
        double[] num1 = new double[2];
        double[] num0 = new double[1];
        num1[0] = C / (d / (1 - c) + a);
        num1[1] = B - num1[0] / (1 - c);
        num0[0] = A - num1[1];
        TransferFunction tf0 = new TransferFunction(new Polynomial(num0), factors[0]);
        TransferFunction tf1 = new TransferFunction(new Polynomial(num1), factors[1].divide(b));
        System.out.println(tf0);
        System.out.println(tf1);
      }
    }

    return null;
  }
 /* Close the loop. */
 public TransferFunction closeLoop(double feedback) {
   Polynomial num_result = num.copy();
   Polynomial den_result = num.add(den.multiply(feedback));
   return new TransferFunction(num_result, den_result);
 }
 /* Combine TFs. */
 public TransferFunction multiply(TransferFunction tf) {
   Polynomial num_result = num.multiply(tf.getNumerator());
   Polynomial den_result = den.multiply(tf.getDenominator());
   return new TransferFunction(num_result, den_result);
 }
  /**
   * funkcja pozwalaj¹ca na automatyczne wykonywanie protoko³u ECDH. Przyjmuje parametry krzywej
   * eliptycznej z pliku i zapisuje do pliku o takiej samej nazwie z przyrostkiem <i>output<i>
   *
   * @param filename nazwa pliku, z którego maj¹ zostaæ pobrane parametry
   */
  private static void autoECDH(String filename) {
    try {
      FileInputStream fstream = new FileInputStream(filename + ".txt");
      DataInputStream in = new DataInputStream(fstream);
      BufferedReader br = new BufferedReader(new InputStreamReader(in));
      String strLine;
      String strOut = new String();
      int m = 0;
      int k = 0;
      BigInteger gx = BigInteger.ZERO;
      BigInteger gy = BigInteger.ZERO;
      BigInteger a2 = BigInteger.ZERO;
      BigInteger a6 = BigInteger.ZERO;
      Klient klientA;
      Klient klientB;
      ECPunkt punktG = null;
      while ((strLine = br.readLine()) != null) {
        try {
          if (strLine.startsWith("k: ")) {
            k = Integer.parseInt(strLine.substring(3));
            while (!(strLine = br.readLine()).equals("")) {
              if (strLine.startsWith("m: ")) {
                m = Integer.parseInt(strLine.substring(3));
                continue;
              } else if (strLine.startsWith("Gx: ")) {
                gx = new BigInteger(strLine.substring(4), 16);
                continue;
              } else if (strLine.startsWith("Gy: ")) {
                gy = new BigInteger(strLine.substring(4), 16);
                continue;
              } else if (strLine.startsWith("a2: ")) {
                a2 = new BigInteger(strLine.substring(4), 16);
                continue;
              } else if (strLine.startsWith("a6: ")) {
                a6 = new BigInteger(strLine.substring(4), 16);
                continue;
              }
            }
          }
          if (m == 0
              || k == 0
              || (gx.equals(BigInteger.ZERO))
              || (gy.equals(BigInteger.ZERO))
              || (a2.equals(BigInteger.ZERO))
              || (a6.equals(BigInteger.ZERO)))
            throw new IllegalArgumentException("Zmienne nie zosta³y zainicjalizowane");
          if (k >= m) throw new IllegalArgumentException("Wyk³adnik k nie mo¿e byæ wiêkszy ni¿ m");
          if (m <= 1) throw new IllegalArgumentException("Wyk³adnik k nie mo¿e byæ wiêkszy ni¿ m");
          if (gx.toString(2).length() > m
              || gy.toString(2).length() > m
              || a2.toString(2).length() > m
              || a6.toString(2).length() > m)
            throw new IllegalArgumentException("Wartoœci parametrów wykraczaj¹ poza zakres");
          System.out.println("k: " + k);
          System.out.println("m: " + m);
          System.out.println("Gx: " + gx.toString(16));
          System.out.println("Gy: " + gy.toString(16));
          System.out.println("a2: " + a2.toString(16));
          System.out.println("a6: " + a6.toString(16));
          punktG = new ECPunkt(m, k, a2, a6, gx, gy);
          if (!punktG.naEC())
            throw new IllegalArgumentException(
                "Generator nie nale¿y do zbioru punktów krzywej eliptycznej");
          ////////////////////////////// Sprawdzenie nieprzywiedlnoœci wielomianu modulo
          Polynomial p = new Polynomial();
          p = p.setDegree(new BigInteger(Integer.toString(m)));
          p = p.setDegree(new BigInteger(Integer.toString(k)));
          p = p.setDegree(BigInteger.ZERO);
          if (p.isReducible())
            throw new IllegalArgumentException("Wielomian modulo cia³a nie jest nieprzywiedlny");
          /////////////////////////////////////////////////////////////////////////////
          klientA = new Klient(punktG);
          klientA.genKluczaPrywatnego(m);
          System.out.println("A.Prywatny: " + klientA.kluczPrywatny.toString(16) + "\r\n");
          klientB = new Klient(punktG);
          klientB.genKluczaPrywatnego(m);
          System.out.println("B.Prywatny: " + klientB.kluczPrywatny.toString(16) + "\r\n");
          klientB.ustawKluczPublicznyB(klientA.oblKluczaPublicznego());
          System.out.println("APub.X: " + klientA.kluczPubliczny.X.b.toString(16) + "\r\n");
          System.out.println("APub.Y: " + klientA.kluczPubliczny.Y.b.toString(16) + "\r\n");
          klientA.ustawKluczPublicznyB(klientB.oblKluczaPublicznego());
          System.out.println("BPub.X: " + klientB.kluczPubliczny.X.b.toString(16) + "\r\n");
          System.out.println("BPub.Y: " + klientB.kluczPubliczny.Y.b.toString(16) + "\r\n");
          klientA.oblKluczaTajnego();
          System.out.println("ATajny.X: " + klientA.kluczTajny.X.b.toString(16) + "\r\n");
          System.out.println("ATajny.Y: " + klientA.kluczTajny.Y.b.toString(16) + "\r\n");
          klientB.oblKluczaTajnego();
          System.out.println("BTajny.X: " + klientB.kluczTajny.X.b.toString(16) + "\r\n");
          System.out.println("BTajny.Y: " + klientB.kluczTajny.Y.b.toString(16) + "\r\n");
          GF2Elem xCord = new GF2Elem(klientA.kluczTajny.X);
          if (xCord.dodaj(klientB.kluczTajny.X).b.equals(BigInteger.ZERO)) {
            /// Algorytm zadzia³a³ poprawnie
            strOut = strOut.concat("////////////////////////////////////////" + "\r\n");
            strOut = strOut.concat("k: " + k + "\r\n");
            strOut = strOut.concat("m: " + m + "\r\n");
            strOut = strOut.concat("Gx: " + gx.toString(16) + "\r\n");
            strOut = strOut.concat("Gy: " + gy.toString(16) + "\r\n");
            strOut = strOut.concat("a2: " + a2.toString(16) + "\r\n");
            strOut = strOut.concat("a6: " + a6.toString(16) + "\r\n");
            strOut = strOut.concat("\nWygenerowane parametry sesji:" + "\r\n");
            strOut = strOut.concat("APub.X: " + klientA.kluczPubliczny.X.b.toString(16) + "\r\n");
            strOut = strOut.concat("APub.Y: " + klientA.kluczPubliczny.Y.b.toString(16) + "\r\n");
            strOut = strOut.concat("BPub.X: " + klientB.kluczPubliczny.X.b.toString(16) + "\r\n");
            strOut = strOut.concat("BPub.Y: " + klientB.kluczPubliczny.Y.b.toString(16) + "\r\n");
            strOut = strOut.concat("Wspolny klucz sesji: " + klientA.genklucz01() + "\r\n");
            System.out.println("Wspolny klucz sesji: " + klientA.genklucz01() + "\r\n");
            strOut = strOut.concat("////////////////////////////////////////" + "\r\n");
          } else {
            /// Algorytm nie zadzia³a³ poprawnie
            strOut = strOut.concat("////////////////////////////////////////" + "\r\n");
            strOut = strOut.concat("k: " + k + "\r\n");
            strOut = strOut.concat("m: " + m + "\r\n");
            strOut = strOut.concat("Gx: " + gx.toString(16) + "\r\n");
            strOut = strOut.concat("Gy: " + gy.toString(16) + "\r\n");
            strOut = strOut.concat("a2: " + a2.toString(16) + "\r\n");
            strOut = strOut.concat("a6: " + a6.toString(16) + "\r\n");
            strOut = strOut.concat("\nAlgorytm nie zadzia³a³ poprawnie" + "\r\n");
            System.out.println("\nAlgorytm nie zadzia³a³ poprawnie" + "\r\n");
            strOut = strOut.concat("////////////////////////////////////////" + "\r\n");
          }
        } catch (NumberFormatException e) {
          System.out.println("Wprowadzone parametry nie s¹ w kodzie HEX");
        } catch (IllegalArgumentException e) {
          System.out.println("B³êdnie sformatowane dane w pliku");
        }
        FileOutputStream foutstream = new FileOutputStream(filename + "output.txt", true);
        DataOutputStream out = new DataOutputStream(foutstream);
        BufferedWriter boutr = new BufferedWriter(new OutputStreamWriter(out));
        boutr.write(strOut);
        m = 0;
        k = 0;
        gx = BigInteger.ZERO;
        gy = BigInteger.ZERO;
        a2 = BigInteger.ZERO;
        a6 = BigInteger.ZERO;
        strOut = null;
        boutr.close();
        out.close();
      }
      in.close();

    } catch (Exception e) {
      System.err.println("Error: " + e.getMessage());
      e.printStackTrace();
    }
  }