@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; }
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); }
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; }
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); }
/** * 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; }
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; } } }
/** * 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; }
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); }
// 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); }
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(); }
/** * 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 }
/** * 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]}; }
/** * 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(); } }