diff --git a/pir/src/main/java/dk/alexandra/fresco/framework/builder/numeric/field/BigIntegerFieldElement.java b/pir/src/main/java/dk/alexandra/fresco/framework/builder/numeric/field/BigIntegerFieldElement.java deleted file mode 100644 index 93b774e..0000000 --- a/pir/src/main/java/dk/alexandra/fresco/framework/builder/numeric/field/BigIntegerFieldElement.java +++ /dev/null @@ -1,86 +0,0 @@ -package dk.alexandra.fresco.framework.builder.numeric.field; - -import dk.alexandra.fresco.framework.util.MathUtils; -import java.math.BigInteger; - -/** - * An element in a field defined by a {@link BigIntegerModulus}. - */ -final public class BigIntegerFieldElement implements FieldElement { - - private static final long serialVersionUID = -6786266947587799652L; - - private final BigInteger value; - - private final BigIntegerModulus modulus; - private BigIntegerFieldElement(BigInteger value, BigIntegerModulus modulus) { - this.value = modulus.reduceModThis(value); - this.modulus = modulus; - } - - private FieldElement create(BigInteger value) { - return create(value, this.modulus); - } - - static FieldElement create(BigInteger value, BigIntegerModulus modulus) { - return new BigIntegerFieldElement(value, modulus); - } - - static FieldElement create(long value, BigIntegerModulus modulus) { - return create(BigInteger.valueOf(value), modulus); - } - - static FieldElement create(String string, BigIntegerModulus modulus) { - return create(new BigInteger(string), modulus); - } - - @Override - public FieldElement add(FieldElement operand) { - return create(value.add(extractValue(operand))); - } - - @Override - public FieldElement subtract(FieldElement operand) { - return create(value.subtract(extractValue(operand))); - } - - @Override - public FieldElement negate() { - return create(getModulus().subtract(value)); - } - - @Override - public FieldElement multiply(FieldElement operand) { - return create(value.multiply(extractValue(operand))); - } - - @Override - public FieldElement sqrt() { - return create(MathUtils.modularSqrt(value, getModulus())); - } - - @Override - public FieldElement modInverse() { - return create(value.modInverse(getModulus())); - } - - static BigInteger extractValue(FieldElement element) { - return ((BigIntegerFieldElement) element).value; - } - - public BigInteger getValue() { - return value; - } - - private BigInteger getModulus() { - return modulus.getBigInteger(); - } - - @Override - public String toString() { - return "BigIntegerFieldElement{" - + "value=" + value - + ", modulus=" + modulus - + '}'; - } -} diff --git a/pir/src/main/java/dk/au/pir/BigIntegerField.java b/pir/src/main/java/dk/au/pir/BigIntegerField.java new file mode 100644 index 0000000..a7b959e --- /dev/null +++ b/pir/src/main/java/dk/au/pir/BigIntegerField.java @@ -0,0 +1,38 @@ +package dk.au.pir; + +import java.math.BigInteger; +import java.security.SecureRandom; + +public class BigIntegerField { + + private final BigInteger groupOrder; + private final SecureRandom rand; + + private static final BigInteger TWO = BigInteger.valueOf(2); + private static final BigInteger THREE = BigInteger.valueOf(3); + + public BigIntegerField(){ + this.groupOrder = new BigInteger("65519"); + this.rand = new SecureRandom(); + } + + public BigInteger getElement(){ + // TODO: Consider how to make random BigIntegers + byte bytes[] = new byte[20]; + rand.nextBytes(bytes); + return new BigInteger(bytes).mod(groupOrder); + } + + public BigInteger multiply(BigInteger elem1, BigInteger elem2){ + return elem1.multiply(elem2).mod(groupOrder); + } + + public BigInteger add(BigInteger elem1, BigInteger elem2){ + return elem1.add(elem2).mod(groupOrder); + } + + public BigInteger getGroupOrder(){ + return groupOrder; + } + +} diff --git a/pir/src/main/java/dk/au/pir/Driver.java b/pir/src/main/java/dk/au/pir/Driver.java index 2d8f3f1..246274e 100644 --- a/pir/src/main/java/dk/au/pir/Driver.java +++ b/pir/src/main/java/dk/au/pir/Driver.java @@ -2,12 +2,31 @@ package dk.au.pir; import dk.alexandra.fresco.framework.builder.numeric.field.FieldElement; import dk.au.pir.protocols.interpoly.InterPolyClient; +import dk.au.pir.protocols.interpoly.InterPolyServer; +import dk.au.pir.settings.PIRSettings; + +import java.math.BigInteger; +import java.util.ArrayList; public class Driver { public static void main(String[] args) { - InterPolyClient client = new InterPolyClient(); - for (FieldElement elem: client.getSRandomFieldElements()) { - System.out.println(elem); + InterPolyClient client = new InterPolyClient(5); + InterPolyServer[] servers = new InterPolyServer[PIRSettings.MOD_BIT_LENGTH + 1]; + + client.generateSRandomFieldElements(); + // Perhaps randomize values + + BigInteger[] results = new BigInteger[PIRSettings.MOD_BIT_LENGTH + 1]; + + int[] database = new int[PIRSettings.DATABASE_SIZE]; + database[5] = 1; + + for (int z = 0; z < PIRSettings.MOD_BIT_LENGTH+1; z++) { + servers[z] = new InterPolyServer(database); + servers[z].receiveGs(client.sendGs(z)); + results[z] = servers[z].F(); } + BigInteger res = client.receiveResults(results); + System.out.println(res); } } diff --git a/pir/src/main/java/dk/au/pir/protocols/interpoly/InterPolyClient.java b/pir/src/main/java/dk/au/pir/protocols/interpoly/InterPolyClient.java index e1febd3..c66a557 100644 --- a/pir/src/main/java/dk/au/pir/protocols/interpoly/InterPolyClient.java +++ b/pir/src/main/java/dk/au/pir/protocols/interpoly/InterPolyClient.java @@ -1,35 +1,62 @@ package dk.au.pir.protocols.interpoly; -import dk.alexandra.fresco.framework.builder.numeric.field.BigIntegerFieldElement; -import dk.alexandra.fresco.framework.builder.numeric.field.FieldElement; +import dk.au.pir.BigIntegerField; import dk.au.pir.settings.PIRSettings; +import dk.au.pir.utils.BigIntegerLagrangeInterpolation; import java.math.BigInteger; +import java.util.ArrayList; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; public class InterPolyClient { + private final int i; private Random random = new Random(); - private BigIntegerFieldElement[] fieldElements = new BigIntegerFieldElement[PIRSettings.MOD_BIT_LENGTH]; + private BigIntegerField field; + + + private BigInteger[] fieldElements = new BigInteger[PIRSettings.MOD_BIT_LENGTH]; public InterPolyClient(int i) { this.i = i; + this.field = new BigIntegerField(); } public void generateSRandomFieldElements() { for (int i = 0; i < fieldElements.length; i++) { - this.fieldElements[i] = (BigIntegerFieldElement) PIRSettings.FIELD_DEFINITION.createElement(new BigInteger(PIRSettings.MAX_BIT_LENGTH, random)); + this.fieldElements[i] = field.getElement(); } } - public FieldElement g(int l, BigIntegerFieldElement z) { + public BigInteger g(int l, int z) { String iString = Integer.toBinaryString(i); + String pads = new String(new char[PIRSettings.MOD_BIT_LENGTH - iString.length()]).replace("\0", "0"); + iString = pads + iString; char lChar = iString.charAt(iString.length() - 1 - l); // lol - BigIntegerFieldElement il = (BigIntegerFieldElement) PIRSettings.FIELD_DEFINITION.createElement(Character.toString(lChar)); - return fieldElements[l].multiply(z).add(il); + String ilString = Character.toString(lChar); + BigInteger il = new BigInteger(ilString).mod(field.getGroupOrder()); + return field.add(field.multiply(fieldElements[l], (BigInteger.valueOf(z))), il); } - public FieldElement[] getFieldElements() { + public BigInteger[] sendGs(int z){ + BigInteger[] gs = new BigInteger[PIRSettings.MOD_BIT_LENGTH]; + for (int l = 0; l < PIRSettings.MOD_BIT_LENGTH; l++) { + gs[l] = g(l, z); + } + return gs; + } + + public BigInteger[] getFieldElements() { return fieldElements; } + + + public BigInteger receiveResults(BigInteger[] results) { + BigInteger[] fuckingXs = new BigInteger[PIRSettings.MOD_BIT_LENGTH + 1]; + for (int i = 0; i < PIRSettings.MOD_BIT_LENGTH + 1; i++) { + fuckingXs[i] = BigInteger.valueOf(i); + } + return BigIntegerLagrangeInterpolation.doIt(fuckingXs, results); + } } diff --git a/pir/src/main/java/dk/au/pir/protocols/interpoly/InterPolyServer.java b/pir/src/main/java/dk/au/pir/protocols/interpoly/InterPolyServer.java index fa2efa2..5e3ca8f 100644 --- a/pir/src/main/java/dk/au/pir/protocols/interpoly/InterPolyServer.java +++ b/pir/src/main/java/dk/au/pir/protocols/interpoly/InterPolyServer.java @@ -1,5 +1,45 @@ package dk.au.pir.protocols.interpoly; +import dk.au.pir.settings.PIRSettings; + +import java.math.BigInteger; + public class InterPolyServer { -} + private BigInteger[] gs; + private int[] database; + + public InterPolyServer(int[] database) { + this.database = database; + } + + public void receiveGs(BigInteger[] gs){ + this.gs = gs; + } + + public BigInteger f(int j){ + BigInteger product = BigInteger.ONE; + for (int l = 0; l < PIRSettings.MOD_BIT_LENGTH; l++) { + String iString = Integer.toBinaryString(j); + String pads = new String(new char[PIRSettings.MOD_BIT_LENGTH - iString.length()]).replace("\0", "0"); + iString = pads + iString; + char lChar = iString.charAt(iString.length() - 1 - l); // lol + String jlString = Character.toString(lChar); + + if (jlString.equals("1")){ + product = product.multiply(gs[l]); + } else { + product = product.multiply(BigInteger.ONE.subtract(gs[l])); + } + } + return product; + } + public BigInteger F() { + BigInteger sum = BigInteger.ZERO; + for (int j = 0; j < PIRSettings.DATABASE_SIZE; j++) { + // Database consist of 0's or 1' + sum = sum.add(f(j).multiply(BigInteger.valueOf(database[j]))); + } + return sum; + } +} \ No newline at end of file diff --git a/pir/src/main/java/dk/au/pir/utils/BigIntegerLagrangeInterpolation.java b/pir/src/main/java/dk/au/pir/utils/BigIntegerLagrangeInterpolation.java new file mode 100644 index 0000000..ac387d9 --- /dev/null +++ b/pir/src/main/java/dk/au/pir/utils/BigIntegerLagrangeInterpolation.java @@ -0,0 +1,24 @@ +package dk.au.pir.utils; + +import java.math.BigInteger; + +public class BigIntegerLagrangeInterpolation { + public static BigInteger doIt(BigInteger[] x, BigInteger[] y) { + // https://stackoverflow.com/questions/16375163/lagrange-interpolation-in-java + BigInteger xPoint = BigInteger.ZERO; // we want to find f(0), so xpoint=0 + BigInteger sum = BigInteger.ZERO; + BigInteger product = BigInteger.ONE; + for (int i = 0; i < x.length; i++) { + for (int j = 0; j < x.length; j++) { + if (j != i) { + BigInteger a = xPoint.subtract(x[j]); + BigInteger b = x[i].subtract(x[j]); + product = product.multiply(a.divide(b)); + } + } + sum = sum.add(product.multiply(y[i])); + product = BigInteger.ONE; + } + return sum; + } +}