AlmostWorks.jpg
This commit is contained in:
parent
549419a105
commit
78572e3abc
|
@ -2,47 +2,30 @@ package dk.au.pir;
|
||||||
|
|
||||||
import dk.au.pir.utils.FieldElement;
|
import dk.au.pir.utils.FieldElement;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
public class BigIntegerField {
|
public class BigIntegerField {
|
||||||
|
|
||||||
private final BigInteger groupOrder;
|
private final BigInteger groupOrder;
|
||||||
private final SecureRandom rand;
|
private final SecureRandom rand;
|
||||||
|
|
||||||
private static final BigInteger TWO = BigInteger.valueOf(2);
|
public BigIntegerField() {
|
||||||
private static final BigInteger THREE = BigInteger.valueOf(3);
|
|
||||||
|
|
||||||
public BigIntegerField(){
|
|
||||||
this.groupOrder = new BigInteger("5");
|
this.groupOrder = new BigInteger("5");
|
||||||
this.rand = new SecureRandom(new byte[] {12});
|
this.rand = new SecureRandom(new byte[] {12}); // TODO: DOnt hardcode seed, lmao
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldElement getElement(){
|
public FieldElement getElement(){
|
||||||
// TODO: Consider how to make random BigIntegers
|
// TODO: Consider how to make random BigIntegers
|
||||||
byte bytes[] = new byte[20];
|
byte bytes[] = new byte[20];
|
||||||
rand.nextBytes(bytes);
|
rand.nextBytes(bytes);
|
||||||
return new FieldElement(new BigInteger(bytes).mod(groupOrder), groupOrder);
|
return new FieldElement(new BigInteger(bytes), 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 subtract(BigInteger elem1, BigInteger elem2){
|
|
||||||
return elem1.subtract(elem2).mod(groupOrder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigInteger getGroupOrder(){
|
public BigInteger getGroupOrder(){
|
||||||
|
|
||||||
return groupOrder;
|
return groupOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FieldElement valueOf(long val) {
|
||||||
|
return new FieldElement(BigInteger.valueOf(val), this.groupOrder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,83 +1,27 @@
|
||||||
package dk.au.pir;
|
package dk.au.pir;
|
||||||
|
|
||||||
import dk.alexandra.fresco.framework.builder.numeric.field.FieldElement;
|
|
||||||
import dk.au.pir.protocols.general.interpoly.GeneralInterPolyClient;
|
|
||||||
import dk.au.pir.protocols.general.interpoly.GeneralInterPolyServer;
|
|
||||||
import dk.au.pir.protocols.interpoly.InterPolyClient;
|
import dk.au.pir.protocols.interpoly.InterPolyClient;
|
||||||
|
import dk.au.pir.protocols.interpoly.InterPolyDatabase;
|
||||||
import dk.au.pir.protocols.interpoly.InterPolyServer;
|
import dk.au.pir.protocols.interpoly.InterPolyServer;
|
||||||
import dk.au.pir.settings.PIRSettings;
|
import dk.au.pir.settings.PIRSettings;
|
||||||
import dk.au.pir.utils.ComparableIntList;
|
|
||||||
import dk.au.pir.utils.IntegerUtils;
|
|
||||||
import dk.au.pir.utils.ProtocolUtils;
|
|
||||||
import org.w3c.dom.ls.LSOutput;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class Driver {
|
public class Driver {
|
||||||
public static void interPolyTest() {
|
|
||||||
InterPolyClient client = new InterPolyClient(1);
|
|
||||||
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[0] = 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int generalInterPolyTest(int ip) {
|
private static int generalInterPolyTest(int ip) {
|
||||||
ProtocolUtils utils = new ProtocolUtils();
|
PIRSettings settings = new PIRSettings(4, 2);
|
||||||
int s = utils.findSizeOfS(PIRSettings.NUM_SERVERS, PIRSettings.DATABASE_SIZE);
|
int s = settings.getS();
|
||||||
System.out.println("s: "+s);
|
System.out.println("s is: " + s);
|
||||||
|
|
||||||
GeneralInterPolyClient client = new GeneralInterPolyClient(1, s);
|
InterPolyDatabase database = new InterPolyDatabase(settings);
|
||||||
|
|
||||||
int[] database = new int[PIRSettings.DATABASE_SIZE];
|
InterPolyServer[] servers = new InterPolyServer[settings.getNumServers()];
|
||||||
System.out.println("db_size: " +PIRSettings.DATABASE_SIZE);
|
for (int i = 0; i < settings.getNumServers(); i++) {
|
||||||
|
servers[i] = new InterPolyServer(database, settings);
|
||||||
GeneralInterPolyServer[] servers = new GeneralInterPolyServer[PIRSettings.NUM_SERVERS];
|
|
||||||
client.generateSRandomFieldElements();
|
|
||||||
|
|
||||||
database[1] = 1;
|
|
||||||
|
|
||||||
int[][] sequences = new int[PIRSettings.DATABASE_SIZE][s];
|
|
||||||
|
|
||||||
Set<ComparableIntList> candidates = new HashSet<ComparableIntList>();
|
|
||||||
|
|
||||||
while (candidates.size() < PIRSettings.DATABASE_SIZE) {
|
|
||||||
ComparableIntList candidate = utils.insertOnes(new ComparableIntList(s), 2);
|
|
||||||
candidates.add(candidate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<ComparableIntList> listCandidates = new ArrayList<ComparableIntList>(candidates);
|
InterPolyClient client = new InterPolyClient(settings, servers);
|
||||||
Collections.sort(listCandidates);
|
int res = client.receive(0);
|
||||||
|
System.out.println("res: " + res);
|
||||||
for (int i = 0; i < sequences.length; i++) {
|
return res;
|
||||||
sequences[i] = listCandidates.get(i).getList();
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger[] results = new BigInteger[PIRSettings.NUM_SERVERS];
|
|
||||||
|
|
||||||
for (int z = 0; z < PIRSettings.NUM_SERVERS; z++) {
|
|
||||||
servers[z] = new GeneralInterPolyServer(database, sequences, s);
|
|
||||||
servers[z].receiveGs(client.sendGs(z));
|
|
||||||
results[z] = servers[z].F();
|
|
||||||
}
|
|
||||||
|
|
||||||
BigInteger res = client.receiveResults(results).mod(client.getFieldElements()[0].getModulus()); // lol
|
|
||||||
System.out.println(res);
|
|
||||||
return res.intValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
package dk.au.pir.protocols.general.interpoly;
|
|
||||||
|
|
||||||
import dk.au.pir.BigIntegerField;
|
|
||||||
import dk.au.pir.settings.PIRSettings;
|
|
||||||
import dk.au.pir.utils.BigIntegerLagrange;
|
|
||||||
import dk.au.pir.utils.FieldElement;
|
|
||||||
import dk.au.pir.utils.IntegerUtils;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class GeneralInterPolyClient {
|
|
||||||
|
|
||||||
private final int i;
|
|
||||||
private final int s;
|
|
||||||
private BigIntegerField field;
|
|
||||||
|
|
||||||
|
|
||||||
private FieldElement[] fieldElements;
|
|
||||||
|
|
||||||
public GeneralInterPolyClient(int i, int s) {
|
|
||||||
this.i = i;
|
|
||||||
fieldElements = new FieldElement[s];
|
|
||||||
this.s = s;
|
|
||||||
this.field = new BigIntegerField();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generateSRandomFieldElements() {
|
|
||||||
for (int j = 0; j < fieldElements.length; j++) {
|
|
||||||
this.fieldElements[j] = field.getElement();
|
|
||||||
}
|
|
||||||
System.out.println("randoms: "+Arrays.deepToString(fieldElements));
|
|
||||||
}
|
|
||||||
|
|
||||||
private BigInteger g(int l, int z) {
|
|
||||||
BigInteger il = BigInteger.valueOf(IntegerUtils.leastSignificantBit(this.i, l));
|
|
||||||
return field.add(field.multiply(fieldElements[l].getValue(), (BigInteger.valueOf(z+1))), il);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BigInteger[] sendGs(int z){
|
|
||||||
BigInteger[] gs = new BigInteger[this.s];
|
|
||||||
for (int l = 0; l < this.s; l++) {
|
|
||||||
gs[l] = g(l, z);
|
|
||||||
}
|
|
||||||
return gs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FieldElement[] getFieldElements() {
|
|
||||||
return fieldElements;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public BigInteger receiveResults(BigInteger[] results) {
|
|
||||||
BigInteger[] xs = new BigInteger[PIRSettings.NUM_SERVERS];
|
|
||||||
for (int j = 0; j < PIRSettings.NUM_SERVERS; j++) {
|
|
||||||
xs[j] = BigInteger.valueOf(j+1);
|
|
||||||
}
|
|
||||||
return BigIntegerLagrange.interpolate(xs, results);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
package dk.au.pir.protocols.general.interpoly;
|
|
||||||
|
|
||||||
import dk.au.pir.BigIntegerField;
|
|
||||||
import dk.au.pir.settings.PIRSettings;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public class GeneralInterPolyServer {
|
|
||||||
private final int sequenceLength;
|
|
||||||
private BigInteger[] gs;
|
|
||||||
private int[][] sequences;
|
|
||||||
private int[] database;
|
|
||||||
private BigIntegerField field;
|
|
||||||
|
|
||||||
public GeneralInterPolyServer(int[] database, int[][] sequences, int sequenceLength) {
|
|
||||||
this.sequences = sequences; this.database = database;; this.sequenceLength = sequenceLength;
|
|
||||||
this.field = new BigIntegerField();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void receiveGs(BigInteger[] gs){
|
|
||||||
this.gs = gs;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BigInteger f(int j){
|
|
||||||
|
|
||||||
BigInteger product = BigInteger.ONE;
|
|
||||||
|
|
||||||
boolean changed = false;
|
|
||||||
|
|
||||||
for (int l = 0; l < sequenceLength; l++) {
|
|
||||||
if (sequences[j][l] == 1) {
|
|
||||||
changed = true;
|
|
||||||
// j(l) * g_l(z) + ((1 - j(l)) * (1 - g_l(z)))
|
|
||||||
BigInteger a = BigInteger.valueOf(sequences[j][l]);
|
|
||||||
BigInteger b = gs[l];
|
|
||||||
BigInteger c = field.subtract(BigInteger.ONE, BigInteger.valueOf(sequences[j][l]));
|
|
||||||
BigInteger d = field.subtract(BigInteger.ONE, gs[l]);
|
|
||||||
|
|
||||||
BigInteger x = field.multiply(a, b);
|
|
||||||
BigInteger y = field.multiply(c, d);
|
|
||||||
BigInteger z = field.add(x, y);
|
|
||||||
|
|
||||||
//product = field.multiply(product, z);
|
|
||||||
product = field.multiply(product, b);
|
|
||||||
System.out.println("gs: "+gs[l]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (!changed)
|
|
||||||
return BigInteger.ZERO;
|
|
||||||
System.out.println("product: "+product);
|
|
||||||
return product;
|
|
||||||
}
|
|
||||||
public BigInteger F() {
|
|
||||||
BigInteger sum = BigInteger.ZERO;
|
|
||||||
for (int j = 0; j < PIRSettings.DATABASE_SIZE; j++) {
|
|
||||||
BigInteger plz = field.multiply(f(j), BigInteger.valueOf(this.database[j]));
|
|
||||||
sum = field.add(sum, plz);
|
|
||||||
//System.out.println(sum.longValue());
|
|
||||||
}
|
|
||||||
System.out.println("pls");
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,56 +2,52 @@ package dk.au.pir.protocols.interpoly;
|
||||||
|
|
||||||
import dk.au.pir.BigIntegerField;
|
import dk.au.pir.BigIntegerField;
|
||||||
import dk.au.pir.settings.PIRSettings;
|
import dk.au.pir.settings.PIRSettings;
|
||||||
import dk.au.pir.utils.BigIntegerLagrange;
|
|
||||||
import dk.au.pir.utils.FieldElement;
|
import dk.au.pir.utils.FieldElement;
|
||||||
import dk.au.pir.utils.IntegerUtils;
|
import dk.au.pir.utils.FieldElementLagrange;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class InterPolyClient {
|
public class InterPolyClient {
|
||||||
|
private PIRSettings settings;
|
||||||
|
private InterPolyServer[] servers;
|
||||||
|
private final int s;
|
||||||
|
private final BigIntegerField field;
|
||||||
|
private final int[][] sequences;
|
||||||
|
|
||||||
private final int i;
|
public InterPolyClient(PIRSettings settings, InterPolyServer[] servers) {
|
||||||
private Random random = new Random();
|
this.settings = settings;
|
||||||
private BigIntegerField field;
|
this.servers = servers;
|
||||||
|
|
||||||
|
this.s = settings.getS();
|
||||||
private FieldElement[] fieldElements = new FieldElement[PIRSettings.MOD_BIT_LENGTH];
|
this.field = settings.getField();
|
||||||
|
this.sequences = settings.getSequences();
|
||||||
public InterPolyClient(int i) {
|
|
||||||
this.i = i;
|
|
||||||
this.field = new BigIntegerField();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateSRandomFieldElements() {
|
private FieldElement[] getRandomFieldElements() {
|
||||||
for (int i = 0; i < fieldElements.length; i++) {
|
FieldElement[] fieldElements = new FieldElement[this.s];
|
||||||
this.fieldElements[i] = field.getElement();
|
for (int i = 0; i < this.s; i++) {
|
||||||
|
fieldElements[i] = this.field.getElement();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public BigInteger g(int l, int z) {
|
|
||||||
BigInteger il = BigInteger.valueOf(IntegerUtils.leastSignificantBit(i, l)).mod(field.getGroupOrder());
|
|
||||||
return field.add(field.multiply(fieldElements[l].getValue(), (BigInteger.valueOf(z))), il);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 FieldElement[] getFieldElements() {
|
|
||||||
return fieldElements;
|
return fieldElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private FieldElement[] getGs(int index, int serverNumber, FieldElement random) {
|
||||||
public BigInteger receiveResults(BigInteger[] results) {
|
FieldElement[] gs = new FieldElement[this.s];
|
||||||
BigInteger[] xs = new BigInteger[PIRSettings.MOD_BIT_LENGTH + 1];
|
int[] i = this.sequences[index];
|
||||||
for (int i = 0; i < PIRSettings.MOD_BIT_LENGTH + 1; i++) {
|
for (int l = 0; l < this.s; l++) {
|
||||||
xs[i] = BigInteger.valueOf(i);
|
gs[l] = random.multiply(this.field.valueOf(serverNumber)).add(this.field.valueOf(i[l]));
|
||||||
}
|
}
|
||||||
return BigIntegerLagrange.interpolate(xs, results);
|
return gs;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int receive(int index) {
|
||||||
|
FieldElement[] randoms = this.getRandomFieldElements();
|
||||||
|
FieldElement[] Fs = new FieldElement[this.servers.length];
|
||||||
|
for (int z = 0; z < this.servers.length; z++) {
|
||||||
|
Fs[z] = this.servers[z].F(this.getGs(index, z+1, randoms[z]));
|
||||||
|
}
|
||||||
|
FieldElement res = FieldElementLagrange.interpolate(this.field, Fs);
|
||||||
|
return res.getValue().intValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package dk.au.pir.protocols.interpoly;
|
||||||
|
|
||||||
|
import dk.au.pir.settings.PIRSettings;
|
||||||
|
|
||||||
|
public class InterPolyDatabase {
|
||||||
|
private final int[] x;
|
||||||
|
|
||||||
|
public InterPolyDatabase(PIRSettings settings) {
|
||||||
|
this.x = new int[settings.getDatabaseSize()];
|
||||||
|
this.x[1] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,39 +1,32 @@
|
||||||
package dk.au.pir.protocols.interpoly;
|
package dk.au.pir.protocols.interpoly;
|
||||||
|
|
||||||
|
import dk.au.pir.BigIntegerField;
|
||||||
import dk.au.pir.settings.PIRSettings;
|
import dk.au.pir.settings.PIRSettings;
|
||||||
import dk.au.pir.utils.IntegerUtils;
|
import dk.au.pir.utils.FieldElement;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public class InterPolyServer {
|
public class InterPolyServer {
|
||||||
|
private InterPolyDatabase database;
|
||||||
|
private PIRSettings settings;
|
||||||
|
private final BigIntegerField field;
|
||||||
|
|
||||||
private BigInteger[] gs;
|
public InterPolyServer(InterPolyDatabase database, PIRSettings settings) {
|
||||||
private int[] database;
|
|
||||||
|
|
||||||
public InterPolyServer(int[] database) {
|
|
||||||
this.database = database;
|
this.database = database;
|
||||||
|
this.settings = settings;
|
||||||
|
|
||||||
|
this.field = settings.getField();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receiveGs(BigInteger[] gs){
|
public FieldElement F(FieldElement[] gs) {
|
||||||
this.gs = gs;
|
FieldElement sum = this.field.valueOf(0);
|
||||||
}
|
for (int j = 0; j < this.settings.getDatabaseSize(); j++) {
|
||||||
|
FieldElement product = this.field.valueOf(1);
|
||||||
public BigInteger f(int j){
|
for (int l = 0; l < this.settings.getS(); l++) {
|
||||||
BigInteger product = BigInteger.ONE;
|
if (this.settings.getSequences()[j][l] == 1) {
|
||||||
for (int l = 0; l < PIRSettings.MOD_BIT_LENGTH; l++) {
|
|
||||||
if (IntegerUtils.leastSignificantBit(j, l) == 1){
|
|
||||||
product = product.multiply(gs[l]);
|
product = product.multiply(gs[l]);
|
||||||
} else {
|
System.out.println("gs: " + gs[l]);
|
||||||
product = product.multiply(BigInteger.ONE.subtract(gs[l]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return product;
|
sum = sum.add(product.multiply(this.field.valueOf(this.database.getX()[j])));
|
||||||
}
|
|
||||||
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;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,52 @@
|
||||||
package dk.au.pir.settings;
|
package dk.au.pir.settings;
|
||||||
|
|
||||||
import dk.alexandra.fresco.framework.builder.numeric.field.BigIntegerFieldDefinition;
|
import dk.au.pir.BigIntegerField;
|
||||||
import dk.alexandra.fresco.framework.builder.numeric.field.FieldDefinition;
|
import dk.au.pir.utils.MathUtils;
|
||||||
import dk.alexandra.fresco.framework.util.ModulusFinder;
|
import dk.au.pir.utils.ProtocolUtils;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
public class PIRSettings {
|
public class PIRSettings {
|
||||||
public static final int MOD_BIT_LENGTH = 2; // s
|
private final int databaseSize;
|
||||||
public static final int DATABASE_SIZE = (int) Math.pow(2, MOD_BIT_LENGTH); // n
|
private final int numServers;
|
||||||
public static final int MAX_BIT_LENGTH = 512;
|
private final int s;
|
||||||
public static final int NUM_SERVERS = 2;
|
|
||||||
|
|
||||||
//public static FieldDefinition FIELD_DEFINITION = new BigIntegerFieldDefinition(ModulusFinder.findSuitableModulus(MOD_BIT_LENGTH));
|
private final int[][] sequences;
|
||||||
|
private final BigIntegerField field;
|
||||||
|
|
||||||
|
public PIRSettings(int databaseSize, int numServers) {
|
||||||
|
this.databaseSize = databaseSize;
|
||||||
|
this.numServers = numServers;
|
||||||
|
this.s = calculateS(numServers, databaseSize);
|
||||||
|
|
||||||
|
this.sequences = ProtocolUtils.createSequences(s, numServers, databaseSize);
|
||||||
|
this.field = new BigIntegerField();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calculateS(int k, int n) {
|
||||||
|
for (int s = k-1; s <= n; s++) {
|
||||||
|
if (MathUtils.binomial(s, k-1) >= n) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDatabaseSize() {
|
||||||
|
return databaseSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumServers() {
|
||||||
|
return numServers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getS() {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[][] getSequences() {
|
||||||
|
return sequences;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigIntegerField getField() {
|
||||||
|
return field;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
package dk.au.pir.utils;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class BigIntegerLagrange {
|
|
||||||
public static BigInteger interpolate(BigInteger[] x, BigInteger[] y) {
|
|
||||||
System.out.println("x: " + Arrays.deepToString(x));
|
|
||||||
System.out.println("y: " + Arrays.deepToString(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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
package dk.au.pir.utils;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class ComparableIntList implements Comparable<ComparableIntList> {
|
|
||||||
|
|
||||||
private int[] list;
|
|
||||||
|
|
||||||
public ComparableIntList(int size) {
|
|
||||||
list = new int[size];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public int[] getList() {
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int length() {
|
|
||||||
return list.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder tmp = new StringBuilder();
|
|
||||||
for (int i : list) {
|
|
||||||
tmp.append(i);
|
|
||||||
}
|
|
||||||
return tmp.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
// TODO: Only works for k=1 atm
|
|
||||||
for (int i = 0; i < list.length; i++) {
|
|
||||||
if (list[i] == 1) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object other) {
|
|
||||||
ComparableIntList cit = (ComparableIntList) other;
|
|
||||||
for (int i = 0; i < list.length; i++) {
|
|
||||||
if (list[i] != cit.list[i]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public int compareTo(ComparableIntList o) {
|
|
||||||
for (int i = 0; i < list.length; i++) {
|
|
||||||
int diff = this.list[i] - o.list[i];
|
|
||||||
if (diff == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return diff;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,10 +7,25 @@ public class FieldElement {
|
||||||
private BigInteger modulus;
|
private BigInteger modulus;
|
||||||
|
|
||||||
public FieldElement(BigInteger value, BigInteger modulus) {
|
public FieldElement(BigInteger value, BigInteger modulus) {
|
||||||
this.value = value;
|
this.value = value.mod(modulus);
|
||||||
this.modulus = modulus;
|
this.modulus = modulus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FieldElement multiply(FieldElement other) {
|
||||||
|
return new FieldElement(this.value.multiply(other.value).mod(this.modulus), this.modulus);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldElement add(FieldElement other) {
|
||||||
|
return new FieldElement(this.value.add(other.value).mod(this.modulus), this.modulus);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldElement subtract(FieldElement other) {
|
||||||
|
return new FieldElement(this.value.subtract(other.value).mod(this.modulus), this.modulus);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldElement divide(FieldElement other) {
|
||||||
|
return new FieldElement(this.value.divide(other.value).mod(this.modulus), this.modulus);
|
||||||
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "" + value.intValue();
|
return "" + value.intValue();
|
||||||
|
|
27
pir/src/main/java/dk/au/pir/utils/FieldElementLagrange.java
Normal file
27
pir/src/main/java/dk/au/pir/utils/FieldElementLagrange.java
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package dk.au.pir.utils;
|
||||||
|
|
||||||
|
import dk.au.pir.BigIntegerField;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class FieldElementLagrange {
|
||||||
|
public static FieldElement interpolate(BigIntegerField field, FieldElement[] y) {
|
||||||
|
System.out.println("y: " + Arrays.deepToString(y));
|
||||||
|
// https://stackoverflow.com/questions/16375163/lagrange-interpolation-in-java
|
||||||
|
FieldElement xPoint = field.valueOf(0); // we want to find f(0), so xpoint=0
|
||||||
|
FieldElement sum = field.valueOf(0);
|
||||||
|
FieldElement product = field.valueOf(1);
|
||||||
|
for (int i = 0; i < y.length; i++) {
|
||||||
|
for (int j = 0; j < y.length; j++) {
|
||||||
|
if (j != i) {
|
||||||
|
FieldElement a = xPoint.subtract(field.valueOf(j+1));
|
||||||
|
FieldElement b = field.valueOf(i+1).subtract(field.valueOf(j+1));
|
||||||
|
product = product.multiply(a.divide(b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum = sum.add(product.multiply(y[i]));
|
||||||
|
product = field.valueOf(1);
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +0,0 @@
|
||||||
package dk.au.pir.utils;
|
|
||||||
|
|
||||||
import dk.au.pir.settings.PIRSettings;
|
|
||||||
|
|
||||||
public class IntegerUtils {
|
|
||||||
public static int leastSignificantBit(int integer, int index) {
|
|
||||||
return (integer >> index) & 1;
|
|
||||||
}
|
|
||||||
}
|
|
11
pir/src/main/java/dk/au/pir/utils/MathUtils.java
Normal file
11
pir/src/main/java/dk/au/pir/utils/MathUtils.java
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package dk.au.pir.utils;
|
||||||
|
|
||||||
|
public class MathUtils {
|
||||||
|
public static int binomial(int n, int k) {
|
||||||
|
if ((n == k) || (k == 0)) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return binomial(n - 1, k) + binomial(n - 1, k - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,63 +1,53 @@
|
||||||
package dk.au.pir.utils;
|
package dk.au.pir.utils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Random;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ProtocolUtils {
|
public class ProtocolUtils {
|
||||||
|
private static int[] createSequence(int s, int k) {
|
||||||
private Random rand;
|
Random rand = new Random();
|
||||||
|
int[] sequence = new int[s];
|
||||||
public ProtocolUtils() {
|
int kRemaining = k - 1;
|
||||||
this.rand = new Random();
|
while (kRemaining != 0) {
|
||||||
|
int rand_idx = rand.nextInt(s);
|
||||||
|
if (sequence[rand_idx] == 0) {
|
||||||
|
sequence[rand_idx] = 1;
|
||||||
|
kRemaining--;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int kronecker(int i, int j) {
|
|
||||||
if (i == j) {
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public int binop(int n, int k) {
|
|
||||||
if (k < 0 || k > n)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (k == 0 || k == n)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
k = Math.min(k, n-k);
|
|
||||||
int c = 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < k; i++)
|
|
||||||
c = c * (n-i) / (i+1);
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int findSizeOfS(int k, int n) {
|
|
||||||
int s = 0;
|
|
||||||
while ((binop(s, k-1))< n) {
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ComparableIntList insertOnes(ComparableIntList sequence, int k) {
|
|
||||||
|
|
||||||
ArrayList<Integer> picked = new ArrayList<Integer>();
|
|
||||||
int i = 0;
|
|
||||||
while (i < k-1) {
|
|
||||||
int randomI = rand.nextInt(sequence.length());
|
|
||||||
if (picked.contains(randomI)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
picked.add(randomI);
|
|
||||||
sequence.getList()[randomI] = 1;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sequence;
|
return sequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int[][] createSequences(int s, int k, int n) {
|
||||||
|
Set<List<Integer>> sequences = new HashSet<>();
|
||||||
|
while (sequences.size() < n) {
|
||||||
|
sequences.add(Arrays.stream(createSequence(s, k)).boxed().collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
List<List<Integer>> lists = new ArrayList<>(sequences);
|
||||||
|
lists.sort((l1, l2) -> {
|
||||||
|
for (int i = 0; i < l1.size(); i++) {
|
||||||
|
int equals = l1.get(i).compareTo(l2.get(i));
|
||||||
|
if (equals != 0) {
|
||||||
|
return equals;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
int[][] arrays = new int[n][s];
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
int[] array = lists.get(j).stream().mapToInt(i -> i).toArray();
|
||||||
|
arrays[j] = array;
|
||||||
|
}
|
||||||
|
return arrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printIntArrayArray(int[][] array) {
|
||||||
|
for (int[] a : array) {
|
||||||
|
for (int i : a) {
|
||||||
|
System.out.print(i);
|
||||||
|
}
|
||||||
|
System.out.println("");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue