/** * */ package de.henku.jpaillier; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Random; /** * @author sdemir * */ public class CSP { public int keySize; public KeyPair keypair; public PublicKey publicKey; public int LengthValue = 10; public int attributeNum; public BigInteger[] SSED_Value; public BigInteger[][] SSED_Bitwise; public BigInteger[] SSED_alpha; public BigInteger ServerData[][]; public BigInteger[] Emin; public String serverName; public CSP(int keySize, String dataFile, int attributesNumber) { KeyPairBuilder keygen = new KeyPairBuilder(); keygen.bits(keySize); keypair = keygen.generateKeyPair(); publicKey = keypair.getPublicKey(); attributeNum =attributesNumber; dataGen(dataFile); SSED_Value = new BigInteger[ServerData.length]; SSED_Bitwise = new BigInteger[ServerData.length][LengthValue]; // long stopTime = System.nanoTime(); // System.out.println(); // System.out.println("İşlem süresi (ms):"+((stopTime-startTime)/ 1000000)); } public void query(BigInteger[] queryData) { for (int i = 0; i < ServerData.length; i++) { SSED_Value[i] = secureEuclideanDistance(ServerData[i], queryData); //System.err.println(i+". SSED:"+keypair.decrypt(SSED_Value[i])); SSED_Bitwise[i] = SecureBitDecomposition(SSED_Value[i]); } } public void dataGen(String dataFile) { ServerData = readData(dataFile); } public BigInteger ConvertBitwiseToDecimal(BigInteger[] arr) { int len = arr.length; BigInteger value = arr[len - 1]; for (int i = len - 2; i >= 0; i--) value = value.multiply( arr[i].modPow(BigInteger.valueOf((long) Math.pow(2, len - i - 1)), publicKey.getnSquared())); return value; } // public BigInteger[] queryData(int a, int b, int c, int d) { // BigInteger[] data = new BigInteger[4]; // data[0] = publicKey.encrypt(BigInteger.valueOf(a)); // data[1] = publicKey.encrypt(BigInteger.valueOf(b)); // data[2] = publicKey.encrypt(BigInteger.valueOf(c)); // data[3] = publicKey.encrypt(BigInteger.valueOf(d)); // // return data; // } public BigInteger secureMultiply(BigInteger a, BigInteger b) { Random rnd = new Random(); int s1 = rnd.nextInt(30); int s2 = rnd.nextInt(30); BigInteger r1 = BigInteger.valueOf(s1); BigInteger r2 = BigInteger.valueOf(s2); BigInteger ar1 = a.multiply(publicKey.encrypt(r1)); BigInteger br2 = b.multiply(publicKey.encrypt(r2)); BigInteger r1xr2 = publicKey.encrypt(r1).modPow(r2, publicKey.getnSquared()); BigInteger axr2 = a.modPow(r2, publicKey.getnSquared()); BigInteger bxr1 = b.modPow(r1, publicKey.getnSquared()); BigInteger rest = r1xr2.multiply(axr2).multiply(bxr1); BigInteger Server2Result = PaillierSubtract(Server2Multiply(ar1, br2), rest); return Server2Result.mod(publicKey.getnSquared()); } public BigInteger PaillierSubtract(BigInteger operand1, BigInteger operand2) { BigInteger n = publicKey.getN().subtract(BigInteger.ONE); operand2 = operand2.modPow(n, publicKey.getnSquared()); return operand1.multiply(operand2); } public BigInteger PaillierSubtract(BigInteger operand1, BigInteger operand2, PublicKey otherPublicKey) { BigInteger n = otherPublicKey.getN().subtract(BigInteger.ONE); operand2 = operand2.modPow(n, otherPublicKey.getnSquared()); return operand1.multiply(operand2); } public BigInteger secureEuclideanDistance(BigInteger[] dataset, BigInteger[] query) { BigInteger sub = PaillierSubtract(dataset[0], query[0]); BigInteger result = secureMultiply(sub, sub); for (int i = 1; i = 0; i--) { Random rnd = new Random(); int r = rnd.nextInt(30)+1; BigInteger En_r = publicKey.encrypt(BigInteger.valueOf(r).mod(publicKey.getnSquared())); BigInteger alpha = EncryptedLSB(T.multiply(En_r)); BigInteger lastBit; BigInteger one = publicKey.encrypt(BigInteger.ONE.mod(publicKey.getnSquared())); BigInteger powl = BigInteger.valueOf(2).modPow(BigInteger.valueOf(-1), publicKey.getnSquared()); // 1/2 işlemi için if (r % 2 == 0) lastBit = alpha; else lastBit = PaillierSubtract(one, alpha); BigInteger Z = PaillierSubtract(T, lastBit); // Z= T - lsb T = Z.modPow(powl, publicKey.getnSquared()); arr[i] = lastBit; // cozYaz(i+"bit",lastBit); } return arr; } public BigInteger[] SecureMin(BigInteger[] u, BigInteger[] v) { Random rnd = new Random(); BigInteger Hi = publicKey.encrypt(BigInteger.ZERO); BigInteger[] L_array = new BigInteger[LengthValue]; BigInteger[] G_array = new BigInteger[LengthValue]; int _r = 13; BigInteger r = publicKey.encrypt(BigInteger.valueOf(_r)); for (int i = 0; i < LengthValue; i++)// LengthValue;i++) { BigInteger Wi = PaillierSubtract(v[i], secureMultiply(u[i], v[i])); BigInteger Gama_i = PaillierSubtract(u[i], v[i]).multiply(r); BigInteger Gi = PaillierSubtract(u[i].multiply(v[i]), secureMultiply(u[i], v[i]).modPow(BigInteger.valueOf(2), publicKey.getnSquared())); BigInteger r_i = BigInteger.valueOf(rnd.nextInt(30) + 1); if (i != 0) { Hi = Gi.multiply(Hi.modPow(r_i, publicKey.getnSquared())); } BigInteger Fi_i = PaillierSubtract(Hi, publicKey.encrypt(BigInteger.ONE)); BigInteger Li = Wi.multiply(Fi_i.modPow(BigInteger.valueOf(rnd.nextInt(30) + 1), publicKey.getnSquared())); // cozYaz("r ",r); // cozYaz(r_i); // cozYaz(u[i]); // cozYaz(v[i]); // cozYaz(Wi); // cozYaz("gama",Gama_i); // cozYaz(Gi); // cozYaz(Hi); // cozYaz("fi",Fi_i.multiply(publicKey.encrypt(BigInteger.valueOf(1)))); // cozYaz("Li // ",Li.multiply(publicKey.encrypt(BigInteger.valueOf(20)))); // System.out.println(); L_array[i] = Li; G_array[i] = Gama_i; } Server2MinResult result = Server2Min(pi_1(L_array), pi_1(G_array)); // Server2MinResult result = Server2Min((L_array), (G_array)); result.M = pi_1_reverse(result.M); BigInteger[] resultArray = new BigInteger[LengthValue]; for (int i = 0; i < LengthValue; i++) { BigInteger n = publicKey.getN().subtract(BigInteger.valueOf(_r)); BigInteger operand2 = publicKey.encrypt(result.alpha).modPow(n, publicKey.getnSquared()); resultArray[i] = v[i].multiply(result.M[i].multiply(operand2)); // cozYaz(v[i].multiply(result.M[i].multiply(operand2))); } return resultArray; } public BigInteger[] SMINn(BigInteger[][] d) { BigInteger[] min = new BigInteger[LengthValue]; min = SecureMin(d[0], d[1]); for (int i = 2; i < d.length; i++) min = SecureMin(min, d[i]); //System.err.println(serverName+" min"+keypair.decrypt(ConvertBitwiseToDecimal(min))); return (min); } public BigInteger SMINnOLD(BigInteger[][] d) { int n = d.length; double log2n = Math.ceil(Math.log(n) / Math.log(2)); // int d[] = { 6, 3, 2, 3, 4, -1, 8, -5 }; int a; int b; for (int i = 1; i <= log2n; i++) { for (int j = 1; j <= n / 2; j++) { if (i == 1) { a = 2 * j - 1 - 1; b = 2 * j - 1; // cozYaz(d[i]); d[a] = SecureMin(d[a], d[b]); // System.err.println("jjj"); // d[b] = // SecureBitDecomposition(publicKey.encrypt(BigInteger.ZERO)); } else { a = 2 * i * (j - 1) + 1 - 1; b = 2 * i * j - 1 - 1; d[a] = SecureMin(d[a], d[b]); // d[b] = // SecureBitDecomposition(publicKey.encrypt(BigInteger.ZERO)); } // System.out.println(i + "." + j + " a:" + (a+1) + " b:" + // (b+1)); } n = n / 2; } // for (int i = 0; i < LengthValue; i++) cozYaz(d[0]); return null; } public Server2MinResult Server2Min(BigInteger[] L_array, BigInteger[] Gm_array) { BigInteger[] M_array = new BigInteger[LengthValue]; BigInteger alpha = BigInteger.ZERO; for (int i = 0; i < LengthValue; i++) if (keypair.decrypt(L_array[i]).equals(BigInteger.ONE)) alpha = BigInteger.ONE; for (int i = 0; i < LengthValue; i++) M_array[i] = Gm_array[i].modPow(alpha, publicKey.getnSquared()); Server2MinResult result = new Server2MinResult(M_array, alpha); return result; } public BigInteger Server2Multiply(BigInteger ar1, BigInteger br2) { BigInteger op1 = keypair.decrypt(ar1.mod(publicKey.getnSquared())); BigInteger op2 = keypair.decrypt(br2.mod(publicKey.getnSquared())); BigInteger result = publicKey.encrypt(op1).modPow(op2, publicKey.getnSquared()); return result; } public BigInteger[] pi_1(BigInteger[] arr) { int per[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; BigInteger[] result = new BigInteger[LengthValue]; for (int i = 0; i < LengthValue; i++) result[i] = arr[per[i]]; return result; } public BigInteger[] pi_1_reverse(BigInteger[] arr) { int per[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; BigInteger[] result = new BigInteger[LengthValue]; for (int i = 0; i < LengthValue; i++) result[i] = arr[per[i]]; return result; } public void cozYaz(String mesaj, BigInteger x) { System.out.print(mesaj + ":" + keypair.decrypt(x.mod(publicKey.getnSquared()))); } public void cozYaz(BigInteger x) { System.out.print(keypair.decrypt(x.mod(publicKey.getnSquared())) + ""); } public void cozYaz(BigInteger[] x) { if (x == null) { System.err.println("boş geldi"); return; } for (int i = 0; i < x.length; i++) System.out.print(keypair.decrypt(x[i].mod(publicKey.getnSquared())) + "\t"); } public BigInteger[][] readData(String fileName) { try { File fileDir = new File(fileName); BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(fileDir), "UTF8")); int countOfLines = (int) Files.lines(Paths.get(new File(fileName).getPath())).count(); BigInteger[][] dataArray = new BigInteger[countOfLines][attributeNum]; String str; int counter = 0; while ((str = in.readLine()) != null) { String[] attributes = str.split(","); for(int i=0; i< attributeNum ;i++) dataArray[counter][i] = publicKey.encrypt(BigInteger.valueOf(Integer.parseInt(attributes[i]))); counter++; } in.close(); return dataArray; } catch (UnsupportedEncodingException e) { System.out.println(e.getMessage()); } catch (IOException e) { System.out.println(e.getMessage()); } catch (Exception e) { System.out.println(e.getMessage()); } return null; } public BigInteger SBAOR(BigInteger[] x, BigInteger[] y) { BigInteger R = SBOR(secureMultiply(x[0], y[0]), secureMultiply(x[1], y[1])); for (int i = 2; i < LengthValue; i++) { R = SBOR(R, secureMultiply(x[i], y[i])); } return PaillierSubtract(publicKey.encrypt(BigInteger.ONE), R); } public BigInteger Server2ST(BigInteger ar, PublicKey otherPublicKey) { BigInteger result = keypair.decrypt(ar); return otherPublicKey.encrypt(result); } public BigInteger ST(BigInteger a, PublicKey otherPublicKey) { Random rnd = new Random(); BigInteger r = BigInteger.valueOf(rnd.nextInt(30) + 1); BigInteger A = a.multiply(publicKey.encrypt(r)); BigInteger B = Server2ST(A, otherPublicKey); return PaillierSubtract(B, otherPublicKey.encrypt(r), otherPublicKey); } public BigInteger[] Index(BigInteger Emin) { //long startTime, endTime = System.nanoTime(); SSED_alpha = new BigInteger[ServerData.length]; BigInteger[] minAtrribute = new BigInteger[attributeNum]; for (int i = 0; i < ServerData.length; i++) { SSED_alpha[i] = PaillierSubtract(ConvertBitwiseToDecimal(SSED_Bitwise[i]), Emin); Random rnd = new Random(); BigInteger r = BigInteger.valueOf(rnd.nextInt(30) + 1); SSED_alpha[i] = SSED_alpha[i].modPow(r, publicKey.getnSquared()); // startTime = System.nanoTime(); // SSED_alpha[i]=SBAOR(SecureBitDecomposition(SSED_alpha[i]),SecureBitDecomposition(publicKey.encrypt(BigInteger.valueOf(1023)))); // endTime = System.nanoTime(); // System.err.println(i+".SBAOR zaman"+((endTime - startTime)/1000000)); } SSED_alpha = pi_2(SSED_alpha); for (int i = 0; i < ServerData.length; i++) { if (keypair.decrypt(SSED_alpha[i]).intValue() == 0) SSED_alpha[i] = publicKey.encrypt(BigInteger.ONE); else SSED_alpha[i] = publicKey.encrypt(BigInteger.ZERO); } SSED_alpha = pi_2(SSED_alpha); for (int i = 0; i < ServerData.length; i++) { for (int j = 0; j < attributeNum; j++) { if (i == 0) minAtrribute[j] = secureMultiply(SSED_alpha[i], ServerData[i][j]); else minAtrribute[j] = minAtrribute[j].multiply(secureMultiply(SSED_alpha[i], ServerData[i][j])); } SSED_Bitwise[i] = OR_SSED_alpha(SSED_Bitwise[i], SSED_alpha[i]); // System.err.println(i+". // bitwise:"+keypair.decrypt(ConvertBitwiseToDecimal(SSED_Bitwise[i]))); // cozYaz(ConvertBitwiseToDecimal(SSED_Bitwise[i]));System.err.println(); } return minAtrribute; } public BigInteger[] IndexSBAOR(BigInteger Emin) { //long startTime, endTime = System.nanoTime(); SSED_alpha = new BigInteger[ServerData.length]; BigInteger[] minAtrribute = new BigInteger[attributeNum]; for (int i = 0; i < ServerData.length; i++) { SSED_alpha[i] = PaillierSubtract(ConvertBitwiseToDecimal(SSED_Bitwise[i]), Emin); Random rnd = new Random(); BigInteger r = BigInteger.valueOf(rnd.nextInt(30) + 1); SSED_alpha[i] = SSED_alpha[i].modPow(r, publicKey.getnSquared()); SSED_alpha[i]=SBAOR(SecureBitDecomposition(SSED_alpha[i]),SecureBitDecomposition(publicKey.encrypt(BigInteger.valueOf(1023)))); for (int j = 0; j < attributeNum; j++) { if (i == 0) minAtrribute[j] = secureMultiply(SSED_alpha[i], ServerData[i][j]); else minAtrribute[j] = minAtrribute[j].multiply(secureMultiply(SSED_alpha[i], ServerData[i][j])); } SSED_Bitwise[i] = OR_SSED_alpha(SSED_Bitwise[i], SSED_alpha[i]); // System.err.println(i+". // bitwise:"+keypair.decrypt(ConvertBitwiseToDecimal(SSED_Bitwise[i]))); // cozYaz(ConvertBitwiseToDecimal(SSED_Bitwise[i]));System.err.println(); } return minAtrribute; } public BigInteger[] pi_2(BigInteger[] arr) { BigInteger[] temp = new BigInteger[arr.length]; for (int i = 0; i < temp.length; i++) temp[i] = arr[i]; return temp; } public BigInteger[] Index2(BigInteger Emin) { SSED_alpha = new BigInteger[ServerData.length]; BigInteger[] minAtrribute = new BigInteger[attributeNum]; for (int i = 0; i < ServerData.length; i++) { SSED_alpha[i] = PaillierSubtract(ConvertBitwiseToDecimal(SSED_Bitwise[i]), Emin); Random rnd = new Random(); BigInteger r = BigInteger.valueOf(rnd.nextInt(30) + 1); SSED_alpha[i] = SSED_alpha[i].modPow(r, publicKey.getnSquared()); } SSED_alpha = pi_2(SSED_alpha); for (int i = 0; i < ServerData.length; i++) { if (keypair.decrypt(SSED_alpha[i]).intValue() == 0) SSED_alpha[i] = publicKey.encrypt(BigInteger.ONE); else SSED_alpha[i] = publicKey.encrypt(BigInteger.ZERO); } SSED_alpha = pi_2(SSED_alpha); for (int i = 0; i < ServerData.length; i++) { for (int j = 0; j < attributeNum; j++) { if (i == 0) minAtrribute[j] = secureMultiply(SSED_alpha[i], ServerData[i][j]); else minAtrribute[j] = minAtrribute[j].multiply(secureMultiply(SSED_alpha[i], ServerData[i][j])); } SSED_Bitwise[i] = OR_SSED_alpha(SSED_Bitwise[i], SSED_alpha[i]); // System.err.println(i+". // bitwise:"+keypair.decrypt(ConvertBitwiseToDecimal(SSED_Bitwise[i]))); // cozYaz(ConvertBitwiseToDecimal(SSED_Bitwise[i]));System.err.println(); } return minAtrribute; } public BigInteger[] OR_SSED_alpha(BigInteger[] a, BigInteger alpha) { for (int i = 0; i < a.length; i++) a[i] = SBOR(a[i], alpha); return a; } }