ope
ope copied to clipboard
When the plaintext is a floating point number, the order of the ciphertext cannot be guaranteed.
- case1: When i use FastOPE, encrypt the plaintext to hex ciphertext, then i insert data to database. I select data order by ciphertext. the order is out of order.
- case2: When i use mope,encrypt short data, the same as case 1
@littleniannian Can you provide sample data?
@littleniannian Can you provide sample data? Change the
OpeTestlike this.
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* @author Ayman Madkour
*/
public abstract class OpeTest {
protected double[] plaintexts;
protected byte[][] ciphertexts;
protected Cipher cipher;
protected Key key;
protected abstract Cipher createCipher();
@Before
public void setUp() {
// Initialize cipher
cipher = createCipher();
key = cipher.generateKey();
// Initialize plaintexts
this.plaintexts = new double[] {
-30000.2,
-20000.3,
-10000.1,
-5000.6,
-2000.3,
-1500.7,
-1000.3,
-500.5,
-100,
-10.8,
-5.4,
-1.1,
0.5,
1.3,
5.7,
10.4,
100.2,
500.3,
1000,
1500.7,
2000.2,
5000.1,
10000.3,
20000.4,
30000.6
};
// Encrypt data
ciphertexts = new byte[plaintexts.length][];
for (int i = 0; i < plaintexts.length; i++) {
ciphertexts[i] = key.encryptDouble(plaintexts[i]);
}
// Print data set
System.out.println("Data set:");
System.out.println();
for (int i = 0; i < plaintexts.length; i++) {
System.out.println(String.format("%6f => %s", plaintexts[i], toString(ciphertexts[i])));
}
}
@Test
public void testRangeQuery() {
// Prepare range query
double minPlaintext = -100;
double maxPlaintext = 1000;
System.out.println();
System.out.println("================================================================================");
System.out.println("Searching for range:");
System.out.println();
System.out.println("Min Plaintext = " + minPlaintext);
System.out.println("Max Plaintext = " + maxPlaintext);
// Encrypt range
byte[] minCiphertext = key.encryptDouble(minPlaintext);
byte[] maxCiphertext = key.encryptDouble(maxPlaintext);
System.out.println("Min Ciphertext = " + toString(minCiphertext));
System.out.println("Max Ciphertext = " + toString(maxCiphertext));
new String(ciphertexts[0], Charset.defaultCharset());
// Search in ciphertexts
List<byte[]> results = new ArrayList<>();
for (int i = 0; i < ciphertexts.length; i++) {
if (inRange(ciphertexts[i], minCiphertext, maxCiphertext)) {
results.add(ciphertexts[i]);
}
}
// Print encrypted results
System.out.println();
System.out.println("================================================================================");
System.out.println("Ciphertext Results:");
System.out.println();
for (byte[] result : results) {
System.out.println(toString(result));
}
// Validate result set size
Assert.assertEquals(results.size(), 11);
// Print plaintext results
System.out.println();
System.out.println("================================================================================");
System.out.println("Plaintext Results:");
System.out.println();
for (byte[] result : results) {
System.out.println(String.format("%6d", key.decryptDouble(result)));
}
// Validate results
for (byte[] result : results) {
double value = key.decryptDouble(result);
Assert.assertTrue(value >= minPlaintext && value <= maxPlaintext);
}
}
protected static String toString(byte[] bytes) {
StringBuilder s = new StringBuilder();
for (byte b : bytes) { s.append(String.format("%02x", Byte.toUnsignedInt(b))); }
return s.toString();
}
protected static int compare(byte[] c1, byte[] c2) {
for (int i = 0; i < c1.length; i++) {
int b1 = Byte.toUnsignedInt(c1[i]);
int b2 = Byte.toUnsignedInt(c2[i]);
if (b1 < b2) { return -1; }
else if (b1 > b2) { return 1; }
}
return 0;
}
protected static boolean inRange(byte[] value, byte[] min, byte[] max) {
return compare(value, min) >= 0 && compare(value, max) <= 0;
}
}
@littleniannian You are right... Must be an issue in float encoding