3.6
This commit is contained in:
commit
40f771b724
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="lib" path="D:/MongoDB/mongo-java-driver-3.4.1.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
|
@ -0,0 +1 @@
|
|||
/bin/
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ORAM</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,11 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
|
@ -0,0 +1,344 @@
|
|||
package nankai.oram.client;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import nankai.oram.client.common.Position;
|
||||
import nankai.oram.client.common.SlotObject;
|
||||
import nankai.oram.client.mCloud.MCOSPartition;
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
import nankai.oram.client.mCloud.SubCloudNewORAM;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.ResponseType;
|
||||
import nankai.oram.common.SocketClientUtil;
|
||||
import nankai.oram.common.Util;
|
||||
import nankai.oram.interfaces.ORAM;
|
||||
|
||||
public class MCOSORAMClient implements ORAM{
|
||||
|
||||
|
||||
boolean initFlag;
|
||||
|
||||
int N;
|
||||
int n_partitions; //All the partitions, for each cloud, it would be divided
|
||||
//int n_partitions_cloud;//the number of partitions for a cloud
|
||||
int n_capacity;//the max capacity of a partition -- need the top level
|
||||
int n_levels;
|
||||
int n_blocks;
|
||||
int n_realBlocks_p;//the real number of blocks in a partition
|
||||
int top_level_len;//the number of blocks in the top level
|
||||
int counter=0;//for sequneceEvict
|
||||
|
||||
Position pos_map[];//position map
|
||||
|
||||
/*************************************************/
|
||||
Queue<SlotObject> slots[];
|
||||
|
||||
SocketClientUtil[] cli;
|
||||
|
||||
MCOSPartition[] partitions;
|
||||
|
||||
|
||||
public MCOSORAMClient()
|
||||
{
|
||||
initFlag=false;
|
||||
cli=new SocketClientUtil[MCloudCommInfo.cloudNumber];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize the parameters, storage space and so on
|
||||
* @param nN
|
||||
*/
|
||||
public boolean init(int nN)
|
||||
{
|
||||
if (initFlag==true)
|
||||
{
|
||||
System.out.println("have inited!");
|
||||
return false;
|
||||
}
|
||||
N=nN;
|
||||
n_partitions = (int) Math.ceil(Math.sqrt(nN));
|
||||
//n_partitions_cloud = (int) Math.ceil(n_partitions/MCloudCommInfo.cloudNumber) ;
|
||||
|
||||
n_realBlocks_p = (int) Math.ceil(((double) nN) / n_partitions);
|
||||
n_blocks = n_realBlocks_p * n_partitions;
|
||||
|
||||
n_levels = (int) (Math.log((double) n_realBlocks_p) / Math.log(2.0)) + 1;
|
||||
n_capacity = (int) Math.ceil(CommInfo.capacity_parameter * n_realBlocks_p);
|
||||
|
||||
pos_map=new Position[n_blocks];
|
||||
for (int i=0;i<n_blocks; i++)
|
||||
{
|
||||
pos_map[i]=new Position();
|
||||
}
|
||||
slots=new Queue[n_partitions];
|
||||
|
||||
partitions=new MCOSPartition[n_partitions];
|
||||
|
||||
//randomly generate the keys for each level of each partition
|
||||
for (int i = 0; i < MCloudCommInfo.cloudNumber; i++)
|
||||
{
|
||||
cli[i]=new SocketClientUtil(MCloudCommInfo.ip[i], MCloudCommInfo.port[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n_partitions; i++){
|
||||
slots[i]=new LinkedList<SlotObject>();
|
||||
partitions[i]=new MCOSPartition(n_realBlocks_p, n_levels, pos_map, cli, i);
|
||||
}
|
||||
|
||||
counter = 0;
|
||||
|
||||
initFlag=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void openConnection()
|
||||
{
|
||||
for (int i = 0; i < MCloudCommInfo.cloudNumber; i++)
|
||||
{
|
||||
cli[i].connect();
|
||||
}
|
||||
}
|
||||
public void closeConnection()
|
||||
{
|
||||
for (int i = 0; i < MCloudCommInfo.cloudNumber; i++)
|
||||
{
|
||||
cli[i].disConnect();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean initORAM()
|
||||
{
|
||||
boolean bRet = true;
|
||||
for (int i = 0; i < MCloudCommInfo.cloudNumber; i++)
|
||||
{
|
||||
byte cmd[]=new byte[14];
|
||||
cmd[0]=CommandType.initORAM;
|
||||
Util.intToByte(cmd, 1, n_partitions);
|
||||
Util.intToByte(cmd, 5, n_capacity);
|
||||
Util.intToByte(cmd, 9, n_levels);
|
||||
cmd[13] = (byte) i;
|
||||
|
||||
cli[i].send( cmd, 14, null , 0, null);
|
||||
if (cli[i].responseType!=ResponseType.wrong)
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Notice the ORAM server to open the database
|
||||
* @return
|
||||
*/
|
||||
public boolean openORAM()
|
||||
{
|
||||
boolean bRet = true;
|
||||
for (int i = 0; i < MCloudCommInfo.cloudNumber; i++) {
|
||||
byte cmd[] = new byte[2];
|
||||
cmd[0] = CommandType.openDB;
|
||||
cmd[1] = (byte)i;
|
||||
|
||||
cli[i].send(cmd, 2, null, 0, null);
|
||||
|
||||
if (cli[i].responseType != ResponseType.wrong)
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
byte[] access(char op, int block_id, byte[] value)
|
||||
{
|
||||
// try {
|
||||
// Thread.sleep(10);
|
||||
// } catch (InterruptedException e) {
|
||||
// // TODO ×Ô¶¯Éú³ÉµÄ catch ¿é
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
byte data[] = new byte[CommInfo.blockSize];
|
||||
|
||||
|
||||
int r = Util.rand_int(this.n_partitions);
|
||||
|
||||
//int c = pos_map[block_id].cloud;
|
||||
|
||||
int p = pos_map[block_id].partition;
|
||||
int level = pos_map[block_id].level;
|
||||
/****************
|
||||
* Read data from slots or the server
|
||||
* If it is in the slot
|
||||
* readAndDel from the slot
|
||||
* read a dummy block from server
|
||||
* Else
|
||||
* read the real block from the server
|
||||
* ******************/
|
||||
if (p >= 0) {
|
||||
boolean isInSlot = false;
|
||||
Iterator itr = slots[p].iterator();
|
||||
SlotObject targetObj = null;
|
||||
while (itr.hasNext())
|
||||
{
|
||||
targetObj = (SlotObject)itr.next();
|
||||
if (targetObj.id==block_id)
|
||||
{
|
||||
isInSlot=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isInSlot ) {
|
||||
// in the slot
|
||||
System.arraycopy(targetObj.value, 0, data, 0, CommInfo.blockSize);
|
||||
slots[p].remove(targetObj);
|
||||
//read a dummy block from clouds
|
||||
readData(p, CommInfo.dummyID);
|
||||
} else {
|
||||
/**************************
|
||||
* Here, should send a request to the cloud server to get the
|
||||
* data
|
||||
* **************************/
|
||||
byte[] ret = readData(p, block_id);
|
||||
if (ret!=null)
|
||||
System.arraycopy(ret, 0, data, 0, CommInfo.blockSize);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pos_map[block_id].partition = r;
|
||||
pos_map[block_id].level = -1;
|
||||
pos_map[block_id].offset = -1;
|
||||
|
||||
if (op == 'w')
|
||||
{
|
||||
System.arraycopy( value, 0, data, 0, CommInfo.blockSize);
|
||||
}
|
||||
writeCache(block_id, data, r);
|
||||
|
||||
randomEvict(CommInfo.v);
|
||||
return data;
|
||||
}
|
||||
|
||||
private byte[] readData(int p, int blockid) {
|
||||
return partitions[p].readPartition(blockid);
|
||||
}
|
||||
|
||||
/****
|
||||
* Write to the cache. With the first layer onion-encryption
|
||||
* @param block_id
|
||||
* @param data
|
||||
* @param r
|
||||
*/
|
||||
private void writeCache(int block_id, byte[] data, int p) {
|
||||
//should be first onion - encryption
|
||||
|
||||
SlotObject newObject = new SlotObject(block_id, data);
|
||||
|
||||
slots[p].add(newObject);
|
||||
}
|
||||
|
||||
|
||||
void sequentialEvict(int vNumber)
|
||||
{
|
||||
for (int i = 0; i < vNumber; i++) {
|
||||
counter = (counter + 1) % MCloudCommInfo.cloudNumber;
|
||||
evict(counter);
|
||||
}
|
||||
}
|
||||
void randomEvict(int vNumber)
|
||||
{
|
||||
Random rnd=new Random();
|
||||
for (int i = 0; i < vNumber; i++) {
|
||||
int r = rnd.nextInt(this.n_partitions);
|
||||
evict(r);
|
||||
}
|
||||
}
|
||||
void evict(int p) {
|
||||
|
||||
if (slots[p].size() >= 1)
|
||||
{
|
||||
//First to analysis which cloud to write
|
||||
int cloud=1;
|
||||
/***************************************
|
||||
* Judge which cloud should be written
|
||||
***************************************/
|
||||
|
||||
SlotObject targetObj = (SlotObject)slots[p].poll();
|
||||
partitions[p].writePartition(targetObj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int getCacheSlotSize()
|
||||
{
|
||||
int ret = 0;
|
||||
for (int i=0; i<slots.length; i++)
|
||||
{
|
||||
ret += slots[i].size();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void clearSlot()
|
||||
{
|
||||
for (int i=0; i<slots.length; i++)
|
||||
{
|
||||
/**************
|
||||
* Here, do not clear directly
|
||||
* Just remove from the slot, but the data should always stored in the database
|
||||
* So, we should update the position map
|
||||
*
|
||||
*/
|
||||
|
||||
if (slots[i].size()>0)
|
||||
;// subORAMs[i].writeCloud(slots[i]);
|
||||
slots[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
public int getIDinDB()
|
||||
{
|
||||
for (int i=0;i<n_blocks; i++)
|
||||
{
|
||||
if (pos_map[i].partition != -1 )
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(String idStr, byte[] value) {
|
||||
access('w', Integer.parseInt(idStr), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] read(String idStr) {
|
||||
return access('r', Integer.parseInt(idStr), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int id, byte[] value) {
|
||||
access('w', id, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] read(int id) {
|
||||
return access('r', id, null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,327 @@
|
|||
package nankai.oram.client;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import nankai.oram.client.common.Position;
|
||||
import nankai.oram.client.common.SlotObject;
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
import nankai.oram.client.mCloud.NewMCOSPartition;
|
||||
import nankai.oram.client.mCloud.SubCloudNewORAM;
|
||||
import nankai.oram.client.partition.Partition;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.SocketClientUtil;
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.ResponseType;
|
||||
import nankai.oram.common.SymmetricCypto;
|
||||
import nankai.oram.common.Util;
|
||||
import nankai.oram.interfaces.MultiCloudORAM;
|
||||
import nankai.oram.interfaces.ORAM;
|
||||
|
||||
public class NewMCOSORAMClient implements ORAM{
|
||||
|
||||
|
||||
boolean initFlag;
|
||||
SubCloudNewORAM[] subORAMs;
|
||||
|
||||
int N;
|
||||
int n_partitions; //All the partitions, for each cloud, it would be divided
|
||||
int n_partitions_cloud;//the number of partitions for a cloud
|
||||
int n_capacity;//the max capacity of a partition -- need the top level
|
||||
int n_levels;
|
||||
int n_blocks;
|
||||
int n_realBlocks_p;//the real number of blocks in a partition
|
||||
int top_level_len;//the number of blocks in the top level
|
||||
int counter=0;//for sequneceEvict
|
||||
|
||||
Position pos_map[];//position map
|
||||
|
||||
/*************************************************/
|
||||
Queue<SlotObject> slots[];
|
||||
|
||||
SocketClientUtil[] cli;
|
||||
|
||||
byte s_buffer[][];
|
||||
public NewMCOSORAMClient()
|
||||
{
|
||||
initFlag=false;
|
||||
cli=new SocketClientUtil[MCloudCommInfo.cloudNumber];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize the parameters, storage space and so on
|
||||
* @param nN
|
||||
*/
|
||||
public boolean init(int nN)
|
||||
{
|
||||
if (initFlag==true)
|
||||
{
|
||||
System.out.println("have inited!");
|
||||
return false;
|
||||
}
|
||||
N=nN;
|
||||
n_partitions = (int) Math.ceil(Math.sqrt(nN));
|
||||
n_partitions_cloud = (int) Math.ceil(n_partitions/MCloudCommInfo.cloudNumber) ;
|
||||
|
||||
n_realBlocks_p = (int) Math.ceil(((double) nN) / n_partitions);
|
||||
n_blocks = n_realBlocks_p * n_partitions;
|
||||
|
||||
n_levels = (int) (Math.log((double) n_realBlocks_p) / Math.log(2.0)) + 1;
|
||||
n_capacity = (int) Math.ceil(CommInfo.capacity_parameter * n_realBlocks_p);
|
||||
|
||||
pos_map=new Position[n_blocks];
|
||||
for (int i=0;i<n_blocks; i++)
|
||||
{
|
||||
pos_map[i]=new Position();
|
||||
}
|
||||
slots=new Queue[MCloudCommInfo.cloudNumber];
|
||||
subORAMs=new SubCloudNewORAM[MCloudCommInfo.cloudNumber];
|
||||
s_buffer=new byte[MCloudCommInfo.evictConditionSize*3][CommInfo.blockSize];//the real value is evicCondition*2
|
||||
|
||||
//randomly generate the keys for each level of each partition
|
||||
for (int i = 0; i < MCloudCommInfo.cloudNumber; i++)
|
||||
{
|
||||
slots[i]=new LinkedList<SlotObject>();
|
||||
cli[i]=new SocketClientUtil(MCloudCommInfo.ip[i], MCloudCommInfo.port[i]);
|
||||
subORAMs[i]=new SubCloudNewORAM(n_partitions_cloud, n_realBlocks_p, n_levels, n_capacity, i, pos_map, cli, s_buffer);
|
||||
}
|
||||
|
||||
counter = 0;
|
||||
|
||||
initFlag=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void openConnection()
|
||||
{
|
||||
for (int i = 0; i < MCloudCommInfo.cloudNumber; i++)
|
||||
{
|
||||
cli[i].connect();
|
||||
}
|
||||
}
|
||||
public void closeConnection()
|
||||
{
|
||||
for (int i = 0; i < MCloudCommInfo.cloudNumber; i++)
|
||||
{
|
||||
cli[i].disConnect();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean initORAM()
|
||||
{
|
||||
boolean bRet = true;
|
||||
for (int i = 0; i < MCloudCommInfo.cloudNumber; i++)
|
||||
{
|
||||
if (subORAMs[i].initORAM()==false)
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notice the ORAM server to open the database
|
||||
* @return
|
||||
*/
|
||||
public boolean openORAM()
|
||||
{
|
||||
boolean bRet = true;
|
||||
for (int i = 0; i < MCloudCommInfo.cloudNumber; i++)
|
||||
{
|
||||
if (subORAMs[i].openORAM()==false)
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
|
||||
byte[] access(char op, int block_id, byte[] value)
|
||||
{
|
||||
|
||||
// try {
|
||||
// Thread.sleep(10);
|
||||
// } catch (InterruptedException e) {
|
||||
// // TODO ×Ô¶¯Éú³ÉµÄ catch ¿é
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
try{
|
||||
|
||||
// System.out.println("access begin");
|
||||
|
||||
byte data[] = new byte[CommInfo.blockSize];
|
||||
|
||||
int r = Util.rand_int(MCloudCommInfo.cloudNumber);
|
||||
|
||||
int c = pos_map[block_id].cloud;
|
||||
int p = pos_map[block_id].partition;
|
||||
/****************
|
||||
* Read data from slots or the server If it is in the slot
|
||||
* readAndDel from the slot read a dummy block from server Else read
|
||||
* the real block from the server
|
||||
* ******************/
|
||||
if (c >= 0) {
|
||||
boolean isInSlot = false;
|
||||
Iterator itr = slots[c].iterator();
|
||||
SlotObject targetObj = null;
|
||||
while (itr.hasNext()) {
|
||||
targetObj = (SlotObject) itr.next();
|
||||
if (targetObj.id == block_id) {
|
||||
isInSlot = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isInSlot) {
|
||||
// in the slot
|
||||
System.arraycopy(targetObj.value, 0, data, 0,
|
||||
CommInfo.blockSize);
|
||||
slots[c].remove(targetObj);
|
||||
// System.out.println("readdummy block_id " + block_id + " c:"
|
||||
// + c + " p:" + p);
|
||||
subORAMs[c].readCloud(CommInfo.dummyID);
|
||||
// System.out.println("readdummy end block_id " + block_id
|
||||
// + " c:" + c + " p:" + p);
|
||||
} else {
|
||||
/**************************
|
||||
* Here, should send a request to the cloud server to get
|
||||
* the data
|
||||
* **************************/
|
||||
// System.out.println("readCloud block_id " + block_id + " c:"
|
||||
// + c + " p:" + p);
|
||||
System.arraycopy(subORAMs[c].readCloud(block_id), 0, data,
|
||||
0, CommInfo.blockSize);
|
||||
// System.out.println("read end");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pos_map[block_id].cloud = r;
|
||||
pos_map[block_id].partition = -1;
|
||||
pos_map[block_id].level = -1;
|
||||
pos_map[block_id].offset = -1;
|
||||
|
||||
if (op == 'w') {
|
||||
System.arraycopy(value, 0, data, 0, CommInfo.blockSize);
|
||||
}
|
||||
writeCache(block_id, data, r);
|
||||
|
||||
//System.out.println("sequentialEvict begin");
|
||||
sequentialEvict(CommInfo.v);
|
||||
//System.out.println("sequentialEvict end");
|
||||
|
||||
// System.out.println("access end");
|
||||
return data;
|
||||
}catch(Exception ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/****
|
||||
* Write to the cache. With the first layer onion-encryption
|
||||
* @param block_id
|
||||
* @param data
|
||||
* @param r
|
||||
*/
|
||||
private void writeCache(int block_id, byte[] data, int c) {
|
||||
//should be first onion - encryption
|
||||
|
||||
SlotObject newObject = new SlotObject(block_id, data);
|
||||
|
||||
slots[c].add(newObject);
|
||||
}
|
||||
|
||||
|
||||
void sequentialEvict(int vNumber)
|
||||
{
|
||||
for (int i = 0; i < vNumber; i++) {
|
||||
counter = (counter + 1) % MCloudCommInfo.cloudNumber;
|
||||
evict(counter);
|
||||
}
|
||||
}
|
||||
void randomEvict(int vNumber)
|
||||
{
|
||||
Random rnd=new Random();
|
||||
for (int i = 0; i < vNumber; i++) {
|
||||
int r = rnd.nextInt(MCloudCommInfo.cloudNumber);
|
||||
evict(r);
|
||||
}
|
||||
}
|
||||
void evict(int c) {
|
||||
|
||||
if (slots[c].size() >= MCloudCommInfo.evictConditionSize)
|
||||
{
|
||||
// System.out.println("evict c:"+c+" slot size:"+slots[c].size());
|
||||
subORAMs[c].writeCloud(slots[c]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int getCacheSlotSize()
|
||||
{
|
||||
int ret = 0;
|
||||
for (int i=0; i<slots.length; i++)
|
||||
{
|
||||
ret += slots[i].size();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void clearSlot()
|
||||
{
|
||||
for (int i=0; i<slots.length; i++)
|
||||
{
|
||||
/**************
|
||||
* Here, do not clear directly
|
||||
* Just remove from the slot, but the data should always stored in the database
|
||||
* So, we should update the position map
|
||||
*
|
||||
*/
|
||||
|
||||
if (slots[i].size()>0)
|
||||
subORAMs[i].writeCloud(slots[i]);
|
||||
slots[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
public int getIDinDB()
|
||||
{
|
||||
for (int i=0;i<n_blocks; i++)
|
||||
{
|
||||
if (pos_map[i].partition != -1 )
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(String idStr, byte[] value) {
|
||||
access('w', Integer.parseInt(idStr), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] read(String idStr) {
|
||||
return access('r', Integer.parseInt(idStr), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int id, byte[] value) {
|
||||
access('w', id, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] read(int id) {
|
||||
return access('r', id, null);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,280 @@
|
|||
package nankai.oram.client;
|
||||
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import nankai.oram.client.common.Position;
|
||||
import nankai.oram.client.common.SlotObject;
|
||||
import nankai.oram.client.partition.Partition;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.SocketClientUtil;
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.ResponseType;
|
||||
import nankai.oram.common.Util;
|
||||
import nankai.oram.interfaces.ORAM;
|
||||
|
||||
|
||||
public class PartitionClient implements ORAM{
|
||||
|
||||
boolean initFlag;
|
||||
int N;
|
||||
int n_partitions;
|
||||
int n_capacity;//the max capacity of a partition -- need the top level
|
||||
int n_levels;
|
||||
int n_blocks;
|
||||
int n_realBlocks_p;//the real number of blocks in a partition
|
||||
int counter=0;//for sequneceEvict
|
||||
|
||||
byte s_buffer[][];//shuffule buffer - a large memory
|
||||
Position pos_map[];//position map
|
||||
|
||||
/*************************************************/
|
||||
Queue<SlotObject> slots[];
|
||||
Partition partions[];
|
||||
|
||||
|
||||
SocketClientUtil cli;
|
||||
|
||||
|
||||
|
||||
public PartitionClient()
|
||||
{
|
||||
initFlag=false;
|
||||
cli=new SocketClientUtil("localhost",2121);
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize the parameters, storage space and so on
|
||||
* @param nN
|
||||
*/
|
||||
public boolean init(int nN)
|
||||
{
|
||||
if (initFlag==true)
|
||||
{
|
||||
System.out.println("have inited!");
|
||||
return false;
|
||||
}
|
||||
N=nN;
|
||||
n_partitions = (int) Math.ceil(Math.sqrt(nN));
|
||||
|
||||
n_realBlocks_p = (int) Math.ceil(((double) nN) / n_partitions);
|
||||
n_blocks = n_realBlocks_p * n_partitions;
|
||||
|
||||
n_levels = (int) (Math.log((double) n_realBlocks_p) / Math.log(2.0)) + 1;
|
||||
n_capacity = (int) Math.ceil(CommInfo.capacity_parameter * n_realBlocks_p);
|
||||
|
||||
partions=new Partition[n_partitions];
|
||||
|
||||
s_buffer=new byte[n_capacity][CommInfo.blockSize];
|
||||
pos_map=new Position[n_blocks];
|
||||
for (int i=0;i<n_blocks; i++)
|
||||
{
|
||||
pos_map[i]=new Position();
|
||||
}
|
||||
slots=new Queue[n_partitions];
|
||||
|
||||
//randomly generate the keys for each level of each partition
|
||||
for (int i = 0; i < n_partitions; i++)
|
||||
{
|
||||
slots[i]=new LinkedList<SlotObject>();
|
||||
partions[i]=new Partition(N, n_partitions, pos_map, s_buffer, cli);
|
||||
}
|
||||
|
||||
counter = 0;
|
||||
|
||||
initFlag=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void openConnection()
|
||||
{
|
||||
cli.connect();
|
||||
}
|
||||
public void closeConnection()
|
||||
{
|
||||
cli.disConnect();
|
||||
}
|
||||
|
||||
public boolean initORAM()
|
||||
{
|
||||
byte cmd[]=new byte[5];
|
||||
cmd[0]=CommandType.initORAM;
|
||||
Util.intToByte(cmd, 1, N);
|
||||
|
||||
cli.send( cmd, 5, null , 0, null);
|
||||
|
||||
return cli.responseType!=ResponseType.wrong;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notice the ORAM server to open the database, will use the created database
|
||||
* @return
|
||||
*/
|
||||
public boolean openORAM()
|
||||
{
|
||||
byte cmd[]=new byte[5];
|
||||
cmd[0]=CommandType.openDB;
|
||||
|
||||
cli.send( cmd, 1, null , 0, null);
|
||||
|
||||
return cli.responseType!=ResponseType.wrong;
|
||||
}
|
||||
|
||||
|
||||
byte[] access(char op, int block_id, byte[] value)
|
||||
{
|
||||
byte data[] = new byte[CommInfo.blockSize];
|
||||
|
||||
int r = 1;
|
||||
if (Util.debug==false){
|
||||
r = Util.rand_int(n_partitions);
|
||||
//not write to the partition with more than the pre-defined real blocks
|
||||
while ( partions[r].realDataNumber >= this.n_realBlocks_p )
|
||||
r = Util.rand_int(n_partitions);
|
||||
}
|
||||
|
||||
int p = pos_map[block_id].partition;
|
||||
/****************
|
||||
* Read data from slots or the server
|
||||
* If it is in the slot
|
||||
* readAndDel from the slot
|
||||
* read a dummy block from server
|
||||
* Else
|
||||
* read the real block from the server
|
||||
* ******************/
|
||||
if (p >= 0) {
|
||||
boolean isInSlot = false;
|
||||
Iterator itr = slots[p].iterator();
|
||||
SlotObject targetObj = null;
|
||||
while (itr.hasNext())
|
||||
{
|
||||
targetObj = (SlotObject)itr.next();
|
||||
if (targetObj.id==block_id)
|
||||
{
|
||||
isInSlot=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isInSlot ) {
|
||||
// in the slot
|
||||
System.arraycopy(targetObj.value, 0, data, 0, CommInfo.blockSize);
|
||||
slots[p].remove(targetObj);
|
||||
partions[p].readPartition(CommInfo.dummyID);
|
||||
} else {
|
||||
/**************************
|
||||
* Here, should send a request to the cloud server to get the
|
||||
* data
|
||||
* **************************/
|
||||
byte[] bReadData=partions[p].readPartition(block_id);
|
||||
System.arraycopy(bReadData, 0, data, 0, CommInfo.blockSize);
|
||||
}
|
||||
}
|
||||
|
||||
pos_map[block_id].partition = r;
|
||||
pos_map[block_id].level = -1;
|
||||
pos_map[block_id].offset = -1;
|
||||
|
||||
if (op == 'w')
|
||||
{
|
||||
data=value;
|
||||
}
|
||||
SlotObject newObject = new SlotObject(block_id, data);
|
||||
slots[r].add(newObject);
|
||||
|
||||
// if (p>=0)
|
||||
// evict(p);
|
||||
|
||||
randomEvict(CommInfo.v);
|
||||
return data;
|
||||
}
|
||||
|
||||
void sequentialEvict(int vNumber)
|
||||
{
|
||||
for (int i = 0; i < vNumber; i++) {
|
||||
counter = (counter + 1) % n_partitions;
|
||||
evict(counter);
|
||||
}
|
||||
}
|
||||
void randomEvict(int vNumber)
|
||||
{
|
||||
Random rnd=new Random();
|
||||
for (int i = 0; i < vNumber; i++) {
|
||||
int r = rnd.nextInt(n_partitions);
|
||||
evict(r);
|
||||
}
|
||||
}
|
||||
void evict(int p) {
|
||||
|
||||
if (slots[p].isEmpty()) {
|
||||
partions[p].writePartition(CommInfo.dummyID, null);
|
||||
} else {
|
||||
//pop a data in slots
|
||||
SlotObject obj=slots[p].poll();
|
||||
partions[p].writePartition( obj.id, obj.value);
|
||||
}
|
||||
}
|
||||
|
||||
public int getCacheSlotSize()
|
||||
{
|
||||
int ret = 0;
|
||||
for (int i=0; i<slots.length; i++)
|
||||
{
|
||||
ret += slots[i].size();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Suggest the client to call this, when it will be closed
|
||||
*/
|
||||
public void clearSlot()
|
||||
{
|
||||
for (int i=0; i<slots.length; i++)
|
||||
{
|
||||
/**************
|
||||
* Here, do not clear directly
|
||||
* Just remove from the slot, but the data should always stored in the database
|
||||
* So, we should update the position map
|
||||
*
|
||||
*/
|
||||
|
||||
while (slots[i].size()>0){
|
||||
SlotObject obj=slots[i].poll();
|
||||
partions[i].writePartition(obj.id, obj.value);
|
||||
}
|
||||
slots[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(String idStr, byte[] value) {
|
||||
access('w', Integer.parseInt(idStr), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] read(String idStr) {
|
||||
return access('r', Integer.parseInt(idStr), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int id, byte[] value) {
|
||||
access('w', id, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] read(int id) {
|
||||
return access('r', id, null);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package nankai.oram.client.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import nankai.oram.client.PartitionClient;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class PartitionClientJUnitTest {
|
||||
|
||||
PartitionClient cliORAM=new PartitionClient();
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
System.out.println("setUp");
|
||||
cliORAM.init(10240);
|
||||
cliORAM.openConnection();
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
System.out.println("tearDown");
|
||||
cliORAM.closeConnection();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitORAM() {
|
||||
if (!cliORAM.initORAM())
|
||||
fail("ÉÐδʵÏÖ");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package nankai.oram.client.Test;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.SymmetricCypto;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class TestENC {
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
KeyGenerator kg;
|
||||
SecretKey userKey = null;
|
||||
try {
|
||||
kg = KeyGenerator.getInstance("AES");
|
||||
kg.init(128);
|
||||
userKey = kg.generateKey();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
byte[] data=new byte[CommInfo.blockSize];
|
||||
for (int i=0;i<CommInfo.blockSize;i++)
|
||||
data[i]=1;
|
||||
|
||||
long testTime = -1;
|
||||
long testTime1 = -1;
|
||||
long testDoneTime = -1;
|
||||
long testDoneTime1 = -1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
//System.out.println(testTime);
|
||||
//testTime = new Date().getTime();//us
|
||||
testTime1 = System.nanoTime();//ns
|
||||
|
||||
/*//test aes
|
||||
for (int i = 0; i < 500000; i++) {
|
||||
SymmetricCypto scp = new SymmetricCypto(CommInfo.keySize);
|
||||
scp.initEnc(userKey, null);
|
||||
scp.enc_decData(data, CommInfo.blockSize);
|
||||
}*/
|
||||
|
||||
//test permution
|
||||
for (int i = 0; i < 500000; i++) {
|
||||
int j = Util.fpeForPermution(i, userKey, 500000);
|
||||
}
|
||||
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
testDoneTime1 = System.nanoTime();
|
||||
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
double totalElapsedTime1 = (testDoneTime1 - testTime1);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
System.out.println("totalElapsedTime1:"+totalElapsedTime1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package nankai.oram.client.Test;
|
||||
|
||||
import nankai.oram.client.MCOSORAMClient;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class TestMCOSFunction {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
MCOSORAMClient oram=new MCOSORAMClient();
|
||||
//initialize the client
|
||||
oram.init(65536);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
//oram.initORAM();
|
||||
oram.openORAM();
|
||||
//write some data
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < 5000; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) id;
|
||||
Util.intToByte(bData, 0, id);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
System.out.println("-----ready to read the block !-----------");
|
||||
bData=oram.read(19);
|
||||
|
||||
/******************
|
||||
* Should be the byte 0x08
|
||||
* *******************/
|
||||
System.out.println(bData[0]+" "+bData[10]);
|
||||
|
||||
oram.closeConnection();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package nankai.oram.client.Test;
|
||||
|
||||
import nankai.oram.client.NewMCOSORAMClient;
|
||||
import nankai.oram.client.PartitionClient;
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class TestNewMCOSFunction {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
NewMCOSORAMClient oram=new NewMCOSORAMClient();
|
||||
//initialize the client
|
||||
oram.init(65536);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.initORAM();
|
||||
//write some data
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < 5000; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) id;
|
||||
Util.intToByte(bData, 0, id);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
System.out.println("-----ready to read the block !-----------");
|
||||
bData=oram.read(19);
|
||||
|
||||
/******************
|
||||
* Should be the byte 0x08
|
||||
* *******************/
|
||||
System.out.println(bData[0]+" "+bData[10]);
|
||||
|
||||
oram.closeConnection();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package nankai.oram.client.Test;
|
||||
|
||||
import nankai.oram.client.PartitionClient;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.SocketClientUtil;
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
/**
|
||||
* Test whether it is work normally
|
||||
* @author Dell
|
||||
*
|
||||
*/
|
||||
|
||||
public class TestPartitionORAM {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// ClientUtil cli=new ClientUtil("127.0.0.1",2121);
|
||||
// cli.connect();
|
||||
//
|
||||
// byte[] bData=new byte[4];
|
||||
// Util.intToByte(bData, 0, 1024);
|
||||
// cli.send(CommandType.initORAM, null, 0, bData, 4, null);
|
||||
// cli.disConnect();
|
||||
|
||||
long testTime = -1;
|
||||
long testTime1 = -1;
|
||||
long testDoneTime = -1;
|
||||
long testDoneTime1 = -1;
|
||||
|
||||
|
||||
PartitionClient oram=new PartitionClient();
|
||||
|
||||
|
||||
//initialize the client
|
||||
oram.init(400);
|
||||
oram.openConnection();
|
||||
|
||||
|
||||
//initalize the server
|
||||
oram.initORAM();
|
||||
|
||||
|
||||
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
testTime1 = System.nanoTime();//ns
|
||||
//write some data
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < 33; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) id;
|
||||
Util.intToByte(bData, 0, id);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
testDoneTime1 = System.nanoTime();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
double totalElapsedTime1 = (testDoneTime1 - testTime1);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
System.out.println("totalElapsedTime1:"+totalElapsedTime1);
|
||||
|
||||
System.out.println("-----ready to read the block !-----------");
|
||||
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
testTime1 = System.nanoTime();//ns
|
||||
bData=oram.read(11);
|
||||
|
||||
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
testDoneTime1 = System.nanoTime();
|
||||
totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
totalElapsedTime1 = (testDoneTime1 - testTime1);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
System.out.println("totalElapsedTime1:"+totalElapsedTime1);
|
||||
/******************
|
||||
* Should be the byte 0x08
|
||||
* *******************/
|
||||
System.out.println(bData[0]+" "+bData[10]);
|
||||
|
||||
oram.closeConnection();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package nankai.oram.client.Test.TestReadWrite;
|
||||
|
||||
import nankai.oram.client.MCOSORAMClient;
|
||||
import nankai.oram.client.PartitionClient;
|
||||
|
||||
/**
|
||||
* This is the init oram program
|
||||
* Each test should after the initilization of ORAM
|
||||
* @author Dell
|
||||
*
|
||||
*/
|
||||
|
||||
public class MCOSInitOram {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
||||
MCOSORAMClient oram=new MCOSORAMClient();
|
||||
|
||||
//initialize the client
|
||||
oram.init(256);
|
||||
oram.openConnection();
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
//initalize the server
|
||||
oram.initORAM();
|
||||
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
|
||||
oram.closeConnection();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,409 @@
|
|||
package nankai.oram.client.Test.TestReadWrite;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import nankai.oram.client.MCOSORAMClient;
|
||||
import nankai.oram.client.NewMCOSORAMClient;
|
||||
import nankai.oram.client.PartitionClient;
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class MCOSReadAndWrite {
|
||||
|
||||
public static int N = 256;
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
||||
//testRead();
|
||||
|
||||
|
||||
//testMultiWrite();
|
||||
|
||||
//testSameAccess();
|
||||
testRandomAccess();
|
||||
}
|
||||
|
||||
private static void testMultiWrite() {
|
||||
//testWrite(5);
|
||||
testWrite(10);
|
||||
testWrite(25);
|
||||
testWrite(50);
|
||||
testWrite(75);
|
||||
testWrite(100);
|
||||
testWrite(150);
|
||||
testWrite(1000);
|
||||
}
|
||||
|
||||
private static void testRead() {
|
||||
MCOSORAMClient oram=new MCOSORAMClient();
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
|
||||
writeTheBlocksToApartition(oram, 1000);
|
||||
|
||||
|
||||
readABlock(oram, 10);
|
||||
readABlock(oram, 50);
|
||||
readABlock(oram, 100);
|
||||
readABlock(oram, 150);
|
||||
// readABlock(oram, 40);
|
||||
// readABlock(oram, 50);
|
||||
// readABlock(oram, 60);
|
||||
// readABlock(oram, 70);
|
||||
// readABlock(oram, 80);
|
||||
// readABlock(oram, 90);
|
||||
//readABlock(oram, 70);
|
||||
//readABlock(oram, 100);
|
||||
//readABlock(oram, 150);
|
||||
readABlock(oram, 250);
|
||||
readABlock(oram, 500);
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
|
||||
/************************
|
||||
* After the initOram
|
||||
* This test can be performed
|
||||
*
|
||||
* This test is used to test the execution time of random access, the number of shuffle between clouds and the write operation
|
||||
**********************/
|
||||
/************************
|
||||
* After the initOram
|
||||
* This test can be performed
|
||||
*
|
||||
* This test is used to test the execution time of random access, the number of shuffle between clouds and the write operation
|
||||
**********************/
|
||||
private static void testRandomAccess() {
|
||||
MCOSORAMClient oram=new MCOSORAMClient();
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
|
||||
Util.debug = false;
|
||||
|
||||
writeTheBlocks(oram, N);
|
||||
|
||||
|
||||
accessWithRandomStatus(oram, 50);
|
||||
accessWithRandomStatus(oram, 100);
|
||||
accessWithRandomStatus(oram, 250);
|
||||
accessWithRandomStatus(oram, 500);
|
||||
accessWithRandomStatus(oram, 1000);
|
||||
// accessWithRandomStatus(oram, 5000);
|
||||
// accessWithRandomStatus(oram, 10000);
|
||||
// accessWithRandomStatus(oram, 50000);
|
||||
// accessWithRandomStatus(oram, 100000);
|
||||
//
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
private static void testSameAccess() {
|
||||
MCOSORAMClient oram=new MCOSORAMClient();
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
|
||||
Util.debug = false;
|
||||
|
||||
writeTheBlocks(oram, 10000);
|
||||
|
||||
|
||||
// //accessWithSameStatus(oram, 5);
|
||||
// accessWithSameStatus(oram, 10);
|
||||
// //accessWithSameStatus(oram, 25);
|
||||
// accessWithSameStatus(oram, 50);
|
||||
// //accessWithSameStatus(oram, 75);
|
||||
accessWithSameStatus(oram, 100);
|
||||
// //accessWithSameStatus(oram, 150);
|
||||
// accessWithSameStatus(oram, 200);
|
||||
|
||||
accessWithSameStatus(oram, 500);
|
||||
//accessWithSameStatus(oram, 500);
|
||||
accessWithSameStatus(oram, 1000);
|
||||
//accessWithSameStatus(oram, 2500);
|
||||
accessWithSameStatus(oram, 5000);
|
||||
// accessWithSameStatus(oram, 7500);
|
||||
accessWithSameStatus(oram, 10000);
|
||||
|
||||
// writeTheBlocks(oram, 10000);
|
||||
//
|
||||
// accessWithSameStatus(oram, 5000);
|
||||
//
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
|
||||
private static void writeTheBlocks(MCOSORAMClient oram, int number) {
|
||||
//write some data
|
||||
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < number; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) (i % 128);
|
||||
//Util.intToByte(bData, 0, id);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
|
||||
bData = oram.read( 2 );
|
||||
System.out.println(" read 2:"+bData[2]);
|
||||
}
|
||||
|
||||
private static void accessWithRandomStatus(MCOSORAMClient oram, int number)
|
||||
{
|
||||
|
||||
|
||||
oram.clearSlot();
|
||||
|
||||
|
||||
Util.writeNumber = 0;
|
||||
Util.readbandwidth =0;
|
||||
Util.cloudcloudbandwidth =0;
|
||||
Util.readNumber =0;
|
||||
Util.bandwidth =0;
|
||||
Util.cloudtocloud=0;
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
Random rnd=new Random();
|
||||
for (int id = 0; id < number ; id++) {
|
||||
//System.out.println("read "+id);
|
||||
int _id= rnd.nextInt(N);
|
||||
oram.read(_id);
|
||||
_id= rnd.nextInt(N);
|
||||
oram.read(_id);
|
||||
_id= rnd.nextInt(N);
|
||||
//write to the cloud
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) ((_id) % 100);
|
||||
//System.out.println("write "+ (id+1) );
|
||||
oram.write(_id, bData);
|
||||
}
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("number is:"+number);
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
// System.out.println("-----Shuffle numeber-----!"+Util.writeNumber+" Util.cloudtocloud:"+ Util.cloudtocloud);
|
||||
// System.out.println("-----ORAM CACHE-----!"+ oram.getCacheSlotSize());
|
||||
System.out.println("-----writeNumber ---- "+Util.writeNumber );
|
||||
System.out.println("-----cloudtocloud ---- "+Util.cloudtocloud );
|
||||
System.out.println("-----readNumber ---- "+Util.readNumber );
|
||||
System.out.println("-----bandwidth ---- "+ Util.bandwidth );
|
||||
System.out.println("-----cloudcloudbandwidth ---- "+Util.cloudcloudbandwidth );
|
||||
System.out.println("-----readbandwidth ---- "+Util.readbandwidth );
|
||||
|
||||
|
||||
|
||||
|
||||
bData = oram.read( 2 );
|
||||
System.out.println(" read 2:"+bData[2]);
|
||||
bData = oram.read( 8 );
|
||||
System.out.println(" read 8:"+bData[2]);
|
||||
|
||||
}
|
||||
|
||||
private static void accessWithSameStatus(MCOSORAMClient oram, int number)
|
||||
{
|
||||
|
||||
|
||||
oram.clearSlot();
|
||||
|
||||
|
||||
Util.writeNumber = 0;
|
||||
Util.readbandwidth =0;
|
||||
Util.cloudcloudbandwidth =0;
|
||||
Util.readNumber =0;
|
||||
Util.bandwidth =0;
|
||||
Util.cloudtocloud=0;
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < number -10 ; id++) {
|
||||
//System.out.println("read "+id);
|
||||
oram.read(id);
|
||||
//write to the cloud
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) ((id+1) % 100);
|
||||
//System.out.println("write "+ (id+1) );
|
||||
oram.write(id+1, bData);
|
||||
}
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("number is:"+number);
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
// System.out.println("-----Shuffle numeber-----!"+Util.writeNumber+" Util.cloudtocloud:"+ Util.cloudtocloud);
|
||||
// System.out.println("-----ORAM CACHE-----!"+ oram.getCacheSlotSize());
|
||||
System.out.println("-----writeNumber ---- "+Util.writeNumber );
|
||||
System.out.println("-----cloudtocloud ---- "+Util.cloudtocloud );
|
||||
System.out.println("-----readNumber ---- "+Util.readNumber );
|
||||
System.out.println("-----bandwidth ---- "+ Util.bandwidth );
|
||||
System.out.println("-----cloudcloudbandwidth ---- "+Util.cloudcloudbandwidth );
|
||||
System.out.println("-----readbandwidth ---- "+Util.readbandwidth );
|
||||
|
||||
|
||||
|
||||
|
||||
bData = oram.read( 2 );
|
||||
System.out.println(" read 2:"+bData[2]);
|
||||
bData = oram.read( 8 );
|
||||
System.out.println(" read 8:"+bData[2]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void writeTheBlocksToApartition(MCOSORAMClient oram, int number) {
|
||||
|
||||
Util.debug = true; //debug is ture, to write into a fix partiton
|
||||
|
||||
Util.writeNumber = 0;
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < number; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) (i % 128);
|
||||
Util.intToByte(bData, 0, id);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
System.out.println("-----Shuffle numeber---- -"+Util.writeNumber+" cache size:"+oram.getCacheSlotSize());
|
||||
|
||||
byte[] bdata = oram.read(2);
|
||||
System.out.println(" data :"+bdata[8]);
|
||||
}
|
||||
private static void readABlock(MCOSORAMClient oram, int number) {
|
||||
|
||||
Util.debug = true;
|
||||
|
||||
Util.writeNumber = 0;
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
|
||||
for (int i=0; i<number;i++)
|
||||
{
|
||||
oram.read(oram.getIDinDB() );
|
||||
}
|
||||
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("number is:"+number);
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
System.out.println("-----Shuffle numeber---- -"+Util.writeNumber+" cache size:"+oram.getCacheSlotSize());
|
||||
|
||||
byte[] bdata = oram.read(2);
|
||||
System.out.println(" data :"+bdata[8]);
|
||||
}
|
||||
|
||||
|
||||
private static void access(int number)
|
||||
{
|
||||
MCOSORAMClient oram=new MCOSORAMClient();
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < number; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) (i % 128);
|
||||
oram.read(id);
|
||||
oram.write(id+1, bData);
|
||||
}
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
System.out.println("-----Shuffle numeber---- -"+Util.writeNumber+" cache size:"+oram.getCacheSlotSize());
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the special write to a fix partition
|
||||
*
|
||||
* if Util.debug set true, fix partition
|
||||
* For a fix partition, test the number less than 1100
|
||||
* but if false, random partition
|
||||
*/
|
||||
private static void testWrite(int number) {
|
||||
MCOSORAMClient oram=new MCOSORAMClient();
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
//write some data
|
||||
|
||||
Util.debug = true;
|
||||
Util.writeNumber = 0;
|
||||
Util.readbandwidth =0;
|
||||
Util.cloudcloudbandwidth =0;
|
||||
Util.readNumber =0;
|
||||
Util.bandwidth =0;
|
||||
Util.cloudtocloud=0;
|
||||
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
|
||||
System.out.println("number is:"+number);
|
||||
long testTime = -1;
|
||||
long testTime1 = -1;
|
||||
long testDoneTime = -1;
|
||||
long testDoneTime1 = -1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
testTime1 = System.nanoTime();//ns
|
||||
|
||||
for (int id = 0; id < number; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) (id % 100);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
testDoneTime1 = System.nanoTime();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
|
||||
double totalElapsedTime1 = (testDoneTime1 - testTime1);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
// System.out.println("totalElapsedTime222:"+totalElapsedTime1);
|
||||
|
||||
System.out.println("-----cloudtocloud ---- "+Util.cloudtocloud );
|
||||
System.out.println("-----writeNumber ---- "+Util.writeNumber );
|
||||
System.out.println("-----bandwidth ---- "+Util.bandwidth );
|
||||
System.out.println("-----cloudcloudbandwidth ---- "+Util.cloudcloudbandwidth );
|
||||
System.out.println("-----readNumber ---- "+Util.readNumber );
|
||||
System.out.println("-----readbandwidth ---- "+Util.readbandwidth );
|
||||
|
||||
byte[] data = oram.read(8);
|
||||
System.out.println("-----read 8--------- : " + data[8]);
|
||||
data = oram.read(9);
|
||||
System.out.println("-----read 9--------- : " + data[8]);
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package nankai.oram.client.Test.TestReadWrite;
|
||||
|
||||
import nankai.oram.client.NewMCOSORAMClient;
|
||||
import nankai.oram.client.PartitionClient;
|
||||
|
||||
/**
|
||||
* This is the init oram program
|
||||
* Each test should after the initilization of ORAM
|
||||
* @author Dell
|
||||
*
|
||||
*/
|
||||
|
||||
public class NewMCOSInitOram {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
||||
NewMCOSORAMClient oram=new NewMCOSORAMClient();
|
||||
|
||||
//initialize the client
|
||||
oram.init(102400);
|
||||
oram.openConnection();
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
//initalize the server
|
||||
oram.initORAM();
|
||||
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
|
||||
oram.closeConnection();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,400 @@
|
|||
package nankai.oram.client.Test.TestReadWrite;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import nankai.oram.client.NewMCOSORAMClient;
|
||||
import nankai.oram.client.PartitionClient;
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class NewMCOSReadAndWrite {
|
||||
|
||||
public static int N = 102400;
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
||||
//testRead();
|
||||
|
||||
|
||||
//testMultiWrite();
|
||||
|
||||
//testSameAccess();
|
||||
testRandomAccess();
|
||||
}
|
||||
|
||||
private static void testMultiWrite() {
|
||||
//testWrite(5);
|
||||
testWrite(10);
|
||||
testWrite(25);
|
||||
testWrite(50);
|
||||
testWrite(75);
|
||||
testWrite(100);
|
||||
testWrite(150);
|
||||
testWrite(1000);
|
||||
}
|
||||
|
||||
private static void testRead() {
|
||||
NewMCOSORAMClient oram=new NewMCOSORAMClient();
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
|
||||
writeTheBlocksToApartition(oram, 1000);
|
||||
|
||||
|
||||
readABlock(oram, 10);
|
||||
readABlock(oram, 50);
|
||||
readABlock(oram, 100);
|
||||
readABlock(oram, 150);
|
||||
// readABlock(oram, 40);
|
||||
// readABlock(oram, 50);
|
||||
// readABlock(oram, 60);
|
||||
// readABlock(oram, 70);
|
||||
// readABlock(oram, 80);
|
||||
// readABlock(oram, 90);
|
||||
//readABlock(oram, 70);
|
||||
//readABlock(oram, 100);
|
||||
//readABlock(oram, 150);
|
||||
readABlock(oram, 250);
|
||||
readABlock(oram, 500);
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
|
||||
/************************
|
||||
* After the initOram
|
||||
* This test can be performed
|
||||
*
|
||||
* This test is used to test the execution time of random access, the number of shuffle between clouds and the write operation
|
||||
**********************/
|
||||
private static void testRandomAccess() {
|
||||
NewMCOSORAMClient oram=new NewMCOSORAMClient();
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
|
||||
Util.debug = false;
|
||||
|
||||
|
||||
writeTheBlocks(oram, N);
|
||||
|
||||
|
||||
accessWithRandomStatus(oram, 500);
|
||||
accessWithRandomStatus(oram, 1000);
|
||||
accessWithRandomStatus(oram, 5000);
|
||||
accessWithRandomStatus(oram, 10000);
|
||||
accessWithRandomStatus(oram, 50000);
|
||||
accessWithRandomStatus(oram, 100000);
|
||||
//
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
private static void testSameAccess() {
|
||||
NewMCOSORAMClient oram=new NewMCOSORAMClient();
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
|
||||
Util.debug = false;
|
||||
|
||||
writeTheBlocks(oram, 10000);
|
||||
|
||||
|
||||
// //accessWithSameStatus(oram, 5);
|
||||
// accessWithSameStatus(oram, 10);
|
||||
// //accessWithSameStatus(oram, 25);
|
||||
// accessWithSameStatus(oram, 50);
|
||||
// //accessWithSameStatus(oram, 75);
|
||||
accessWithSameStatus(oram, 100);
|
||||
// //accessWithSameStatus(oram, 150);
|
||||
// accessWithSameStatus(oram, 200);
|
||||
|
||||
accessWithSameStatus(oram, 500);
|
||||
//accessWithSameStatus(oram, 500);
|
||||
accessWithSameStatus(oram, 1000);
|
||||
//accessWithSameStatus(oram, 2500);
|
||||
accessWithSameStatus(oram, 5000);
|
||||
// accessWithSameStatus(oram, 7500);
|
||||
accessWithSameStatus(oram, 10000);
|
||||
|
||||
// writeTheBlocks(oram, 10000);
|
||||
//
|
||||
// accessWithSameStatus(oram, 5000);
|
||||
//
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
|
||||
private static void writeTheBlocks(NewMCOSORAMClient oram, int number) {
|
||||
//write some data
|
||||
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < number; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) (i % 100);
|
||||
//Util.intToByte(bData, 0, id);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
|
||||
bData = oram.read( 2 );
|
||||
System.out.println(" read 2:"+bData[2]);
|
||||
}
|
||||
|
||||
|
||||
private static void accessWithRandomStatus(NewMCOSORAMClient oram, int number)
|
||||
{
|
||||
|
||||
|
||||
oram.clearSlot();
|
||||
|
||||
|
||||
Util.writeNumber = 0;
|
||||
Util.readbandwidth =0;
|
||||
Util.cloudcloudbandwidth =0;
|
||||
Util.readNumber =0;
|
||||
Util.bandwidth =0;
|
||||
Util.cloudtocloud=0;
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
Random rnd=new Random();
|
||||
for (int id = 0; id < number ; id++) {
|
||||
//System.out.println("read "+id);
|
||||
int _id= rnd.nextInt(N);
|
||||
oram.read(_id);
|
||||
_id= rnd.nextInt(N);
|
||||
oram.read(_id);
|
||||
_id= rnd.nextInt(N);
|
||||
//write to the cloud
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) ((_id) % 100);
|
||||
//System.out.println("write "+ (id+1) );
|
||||
oram.write(_id, bData);
|
||||
}
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("number is:"+number);
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
// System.out.println("-----Shuffle numeber-----!"+Util.writeNumber+" Util.cloudtocloud:"+ Util.cloudtocloud);
|
||||
// System.out.println("-----ORAM CACHE-----!"+ oram.getCacheSlotSize());
|
||||
System.out.println("-----writeNumber ---- "+Util.writeNumber );
|
||||
System.out.println("-----cloudtocloud ---- "+Util.cloudtocloud );
|
||||
System.out.println("-----readNumber ---- "+Util.readNumber );
|
||||
System.out.println("-----bandwidth ---- "+ Util.bandwidth );
|
||||
System.out.println("-----cloudcloudbandwidth ---- "+Util.cloudcloudbandwidth );
|
||||
System.out.println("-----readbandwidth ---- "+Util.readbandwidth );
|
||||
|
||||
|
||||
|
||||
|
||||
bData = oram.read( 2 );
|
||||
System.out.println(" read 2:"+bData[2]);
|
||||
bData = oram.read( 8 );
|
||||
System.out.println(" read 8:"+bData[2]);
|
||||
|
||||
}
|
||||
|
||||
private static void accessWithSameStatus(NewMCOSORAMClient oram, int number)
|
||||
{
|
||||
|
||||
|
||||
oram.clearSlot();
|
||||
|
||||
|
||||
Util.writeNumber = 0;
|
||||
Util.readbandwidth =0;
|
||||
Util.cloudcloudbandwidth =0;
|
||||
Util.readNumber =0;
|
||||
Util.bandwidth =0;
|
||||
Util.cloudtocloud=0;
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < number -10 ; id++) {
|
||||
//System.out.println("read "+id);
|
||||
oram.read(id);
|
||||
//write to the cloud
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) ((id+1) % 100);
|
||||
//System.out.println("write "+ (id+1) );
|
||||
oram.write(id+1, bData);
|
||||
}
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("number is:"+number);
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
// System.out.println("-----Shuffle numeber-----!"+Util.writeNumber+" Util.cloudtocloud:"+ Util.cloudtocloud);
|
||||
// System.out.println("-----ORAM CACHE-----!"+ oram.getCacheSlotSize());
|
||||
System.out.println("-----writeNumber ---- "+Util.writeNumber );
|
||||
System.out.println("-----cloudtocloud ---- "+Util.cloudtocloud );
|
||||
System.out.println("-----readNumber ---- "+Util.readNumber );
|
||||
System.out.println("-----bandwidth ---- "+ Util.bandwidth );
|
||||
System.out.println("-----cloudcloudbandwidth ---- "+Util.cloudcloudbandwidth );
|
||||
System.out.println("-----readbandwidth ---- "+Util.readbandwidth );
|
||||
|
||||
|
||||
|
||||
|
||||
bData = oram.read( 2 );
|
||||
System.out.println(" read 2:"+bData[2]);
|
||||
bData = oram.read( 8 );
|
||||
System.out.println(" read 8:"+bData[2]);
|
||||
|
||||
}
|
||||
|
||||
private static void writeTheBlocksToApartition(NewMCOSORAMClient oram, int number) {
|
||||
|
||||
Util.debug = true; //debug is ture, to write into a fix partiton
|
||||
|
||||
Util.writeNumber = 0;
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < number; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) (i % 128);
|
||||
Util.intToByte(bData, 0, id);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
System.out.println("-----Shuffle numeber---- -"+Util.writeNumber+" cache size:"+oram.getCacheSlotSize());
|
||||
|
||||
byte[] bdata = oram.read(2);
|
||||
System.out.println(" data :"+bdata[8]);
|
||||
}
|
||||
private static void readABlock(NewMCOSORAMClient oram, int number) {
|
||||
|
||||
Util.debug = true;
|
||||
|
||||
Util.writeNumber = 0;
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
|
||||
for (int i=0; i<number;i++)
|
||||
{
|
||||
oram.read(oram.getIDinDB() );
|
||||
}
|
||||
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("number is:"+number);
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
System.out.println("-----Shuffle numeber---- -"+Util.writeNumber+" cache size:"+oram.getCacheSlotSize());
|
||||
|
||||
byte[] bdata = oram.read(2);
|
||||
System.out.println(" data :"+bdata[8]);
|
||||
}
|
||||
|
||||
|
||||
private static void access(int number)
|
||||
{
|
||||
NewMCOSORAMClient oram=new NewMCOSORAMClient();
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < number; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) (i % 128);
|
||||
oram.read(id);
|
||||
oram.write(id+1, bData);
|
||||
}
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
System.out.println("-----Shuffle numeber---- -"+Util.writeNumber+" cache size:"+oram.getCacheSlotSize());
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the special write to a fix partition
|
||||
*
|
||||
* if Util.debug set true, fix partition
|
||||
* For a fix partition, test the number less than 1100
|
||||
* but if false, random partition
|
||||
*/
|
||||
private static void testWrite(int number) {
|
||||
NewMCOSORAMClient oram=new NewMCOSORAMClient();
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
//write some data
|
||||
|
||||
Util.debug = true;
|
||||
Util.writeNumber = 0;
|
||||
Util.readbandwidth =0;
|
||||
Util.cloudcloudbandwidth =0;
|
||||
Util.readNumber =0;
|
||||
Util.bandwidth =0;
|
||||
Util.cloudtocloud=0;
|
||||
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
|
||||
System.out.println("number is:"+number);
|
||||
long testTime = -1;
|
||||
long testTime1 = -1;
|
||||
long testDoneTime = -1;
|
||||
long testDoneTime1 = -1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
testTime1 = System.nanoTime();//ns
|
||||
|
||||
for (int id = 0; id < number; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) (id % 100);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
testDoneTime1 = System.nanoTime();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
|
||||
double totalElapsedTime1 = (testDoneTime1 - testTime1);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
// System.out.println("totalElapsedTime222:"+totalElapsedTime1);
|
||||
|
||||
System.out.println("-----cloudtocloud ---- "+Util.cloudtocloud );
|
||||
System.out.println("-----writeNumber ---- "+Util.writeNumber );
|
||||
System.out.println("-----bandwidth ---- "+Util.bandwidth );
|
||||
System.out.println("-----cloudcloudbandwidth ---- "+Util.cloudcloudbandwidth );
|
||||
System.out.println("-----readNumber ---- "+Util.readNumber );
|
||||
System.out.println("-----readbandwidth ---- "+Util.readbandwidth );
|
||||
|
||||
byte[] data = oram.read(8);
|
||||
System.out.println("-----read 8--------- : " + data[8]);
|
||||
data = oram.read(9);
|
||||
System.out.println("-----read 9--------- : " + data[8]);
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package nankai.oram.client.Test.TestReadWrite;
|
||||
|
||||
import nankai.oram.client.PartitionClient;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
|
||||
/**
|
||||
* This is the init oram program
|
||||
* Each test should after the initilization of ORAM
|
||||
* @author Dell
|
||||
*
|
||||
*/
|
||||
public class SSSInitOram {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
||||
PartitionClient oram=new PartitionClient();
|
||||
|
||||
|
||||
//initialize the client
|
||||
oram.init(1024000);
|
||||
oram.openConnection();
|
||||
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
//initalize the server
|
||||
oram.initORAM();
|
||||
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
|
||||
oram.closeConnection();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,282 @@
|
|||
package nankai.oram.client.Test.TestReadWrite;
|
||||
|
||||
import nankai.oram.client.NewMCOSORAMClient;
|
||||
import nankai.oram.client.PartitionClient;
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class SSSTestWriteAndRead {
|
||||
|
||||
public static int N = 1024000;
|
||||
public static void main(String[] args) {
|
||||
|
||||
//writeTheBlocksToApartition(1024);
|
||||
testRandomAccess();
|
||||
|
||||
}
|
||||
private static void testRandomAccess() {
|
||||
PartitionClient oram=new PartitionClient();
|
||||
|
||||
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
|
||||
Util.debug = false;
|
||||
|
||||
writeTheBlocks(oram, 50000);
|
||||
|
||||
accessWithSameStatus(oram, 100);
|
||||
accessWithSameStatus(oram, 500);
|
||||
accessWithSameStatus(oram, 1000);
|
||||
accessWithSameStatus(oram, 2500);
|
||||
accessWithSameStatus(oram, 5000);
|
||||
accessWithSameStatus(oram, 7500);
|
||||
accessWithSameStatus(oram, 10000);
|
||||
|
||||
|
||||
// writeTheBlocks(oram, 10000);
|
||||
//
|
||||
// accessWithSameStatus(oram, 5000);
|
||||
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
|
||||
private static void writeTheBlocks(PartitionClient oram, int number) {
|
||||
//write some data
|
||||
Util.debug = false;
|
||||
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < number; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) 2;
|
||||
Util.intToByte(bData, 0, id);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
}
|
||||
private static void accessWithSameStatus(PartitionClient oram, int number)
|
||||
{
|
||||
|
||||
|
||||
oram.clearSlot();
|
||||
|
||||
|
||||
Util.writeNumber = 0;
|
||||
Util.readbandwidth =0;
|
||||
Util.cloudcloudbandwidth =0;
|
||||
Util.readNumber =0;
|
||||
Util.bandwidth =0;
|
||||
Util.cloudtocloud=0;
|
||||
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < number -1 ; id++) {
|
||||
//System.out.println(id);
|
||||
oram.read(id);
|
||||
//write to the cloud
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) 2;
|
||||
Util.intToByte(bData, 0, id+1);
|
||||
oram.write(id+1, bData);
|
||||
}
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("number is:"+number);
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
// System.out.println("-----Shuffle numeber-----!"+Util.writeNumber+" Util.cloudtocloud:"+ Util.cloudtocloud);
|
||||
// System.out.println("-----ORAM CACHE-----!"+ oram.getCacheSlotSize());
|
||||
System.out.println("-----writeNumber ---- "+Util.writeNumber );
|
||||
System.out.println("-----cloudtocloud ---- "+Util.cloudtocloud );
|
||||
System.out.println("-----readNumber ---- "+Util.readNumber );
|
||||
System.out.println("-----bandwidth ---- "+ (Util.bandwidth) );
|
||||
System.out.println("-----cloudcloudbandwidth ---- "+Util.cloudcloudbandwidth );
|
||||
System.out.println("-----readbandwidth ---- "+Util.readbandwidth );
|
||||
|
||||
|
||||
|
||||
|
||||
bData = oram.read( 2 );
|
||||
System.out.println(" read 2:"+bData[8]);
|
||||
bData = oram.read( 8 );
|
||||
System.out.println(" read 8:"+bData[8]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test writing to a fix partition, until it is filled
|
||||
* Obtain the number of write and cache size
|
||||
* @param number
|
||||
*/
|
||||
private static void testWriteToAFixPartition(int number) {
|
||||
PartitionClient oram=new PartitionClient();
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
//write some data
|
||||
|
||||
Util.debug = true;
|
||||
Util.writeNumber = 0;
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < number; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) (i % 128);
|
||||
Util.intToByte(bData, 0, id);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
System.out.println("-----Shuffle numeber---- -"+Util.writeNumber+" cache size:"+oram.getCacheSlotSize());
|
||||
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
private static void writeTheBlocks(int number) {
|
||||
PartitionClient oram=new PartitionClient();
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
//write some data
|
||||
|
||||
Util.debug = false;
|
||||
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < number; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) (i % 128);
|
||||
Util.intToByte(bData, 0, id);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
|
||||
private static void access(int number)
|
||||
{
|
||||
PartitionClient oram=new PartitionClient();
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < number; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) (i % 128);
|
||||
oram.write(id, bData);
|
||||
oram.write( id+1, bData );
|
||||
}
|
||||
oram.closeConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the special write to a fix partition and a read
|
||||
* At the same time, to obtain the shuffle number
|
||||
*/
|
||||
private static void TestCase1() {
|
||||
long testTime = -1;
|
||||
long testDoneTime = -1;
|
||||
|
||||
|
||||
PartitionClient oram=new PartitionClient();
|
||||
|
||||
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
|
||||
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
|
||||
Util.debug = true;
|
||||
Util.writeNumber = 0;
|
||||
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
//write some data
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < 256; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) id;
|
||||
Util.intToByte(bData, 0, id);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
|
||||
System.out.println("-----ready to read the block !-----------");
|
||||
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
bData=oram.read(11);
|
||||
|
||||
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
/******************
|
||||
* Should be the byte 0x08
|
||||
* *******************/
|
||||
System.out.println(bData[0]+" "+bData[10]);
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
/**
|
||||
* Test the buffer size and shuffler number
|
||||
*/
|
||||
private static void TestCase2() {
|
||||
|
||||
|
||||
PartitionClient oram=new PartitionClient();
|
||||
|
||||
|
||||
//initialize the client
|
||||
oram.init(N);
|
||||
oram.openConnection();
|
||||
|
||||
|
||||
//initalize the server
|
||||
oram.openORAM();
|
||||
|
||||
Util.debug = false;
|
||||
Util.writeNumber = 0;
|
||||
|
||||
//write some data
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int id = 0; id < 51200; id++) {
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = (byte) id;
|
||||
Util.intToByte(bData, 0, id);
|
||||
oram.write(id, bData);
|
||||
}
|
||||
|
||||
//get the slot size
|
||||
System.out.println("-----Shuffle numeber---- -"+Util.writeNumber+" cache size:"+oram.getCacheSlotSize());
|
||||
|
||||
System.out.println("-----ready to read the block !-----------");
|
||||
|
||||
bData=oram.read(111);
|
||||
|
||||
/******************
|
||||
* Should be the byte 0x08
|
||||
* *******************/
|
||||
System.out.println(bData[0]+" "+bData[10]);
|
||||
|
||||
oram.closeConnection();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package nankai.oram.client.Test;
|
||||
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.SocketClientUtil;
|
||||
|
||||
public class TestSocket {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
SocketClientUtil cli=new SocketClientUtil("114.215.26.85",2121);
|
||||
long testTime = -1;
|
||||
long testTime1 = -1;
|
||||
long testDoneTime = -1;
|
||||
long testDoneTime1 = -1;
|
||||
|
||||
cli.connect();
|
||||
|
||||
byte[] bData=new byte[1024];
|
||||
for (int i=0;i<1024;i++)
|
||||
bData[i]=1;
|
||||
testTime = System.currentTimeMillis(); //ms
|
||||
testTime1 = System.nanoTime();//ns
|
||||
//bData[0]=CommandType.testTime;
|
||||
|
||||
for (int i=0;i<1024;i++)
|
||||
cli.send(bData, 1024);
|
||||
|
||||
|
||||
testDoneTime = System.currentTimeMillis();
|
||||
testDoneTime1 = System.nanoTime();
|
||||
|
||||
double totalElapsedTime = (testDoneTime - testTime);// / 1000.0;
|
||||
double totalElapsedTime1 = (testDoneTime1 - testTime1);// / 1000.0;
|
||||
System.out.println("totalElapsedTime:"+totalElapsedTime);
|
||||
System.out.println("totalElapsedTime1:"+totalElapsedTime1);
|
||||
cli.disConnect();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package nankai.oram.client.common;
|
||||
|
||||
public class Position{
|
||||
/**********************
|
||||
* BLockID is maintained by the client
|
||||
* But id is stored in the server, the record ID of the data u with ID of BLockID
|
||||
*
|
||||
* The same sequence in the client is denoted as the BLockIDs
|
||||
* but the real sequence in the server will be the different ids
|
||||
* ********************/
|
||||
public int partition;
|
||||
public int level;
|
||||
public int offset;
|
||||
public int rndNumber;//random value
|
||||
public int cloud;//random value
|
||||
public Position()
|
||||
{
|
||||
partition=-1;
|
||||
level=-1;
|
||||
offset=-1;
|
||||
rndNumber=0;
|
||||
cloud=-1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package nankai.oram.client.common;
|
||||
|
||||
import nankai.oram.common.CommInfo;
|
||||
|
||||
public class SlotObject{
|
||||
public int id;
|
||||
public byte[] value;
|
||||
public SlotObject()
|
||||
{
|
||||
id=0;
|
||||
value=new byte[CommInfo.blockSize];
|
||||
}
|
||||
public SlotObject(int _id, byte[] _value)
|
||||
{
|
||||
id=_id;
|
||||
value=new byte[CommInfo.blockSize];
|
||||
System.arraycopy(_value, 0, value, 0, CommInfo.blockSize);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,694 @@
|
|||
package nankai.oram.client.mCloud;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import nankai.oram.client.common.Position;
|
||||
import nankai.oram.client.common.SlotObject;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.SocketClientUtil;
|
||||
import nankai.oram.common.SymmetricCypto;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class MCOSPartition {
|
||||
int n_levels;
|
||||
|
||||
int n_realBlocks_p;//the real number of blocks in a partition
|
||||
int n_capacity;//the max capacity of a partition -- need the top level
|
||||
int top_level_len;//the number of blocks in the top level
|
||||
|
||||
public int partition = 0;
|
||||
int blockIDs[];//all the blockIDs. When re-shuffle, the dummyIDs will be re-filled
|
||||
int dummyNumbers[];//the dummy block numbers; When re-shuffle, the dummyIDs will be filled
|
||||
int nextDummy[];//the dummy block counter;
|
||||
boolean filled[];//filled level flag
|
||||
int clouds[];//filled level flag
|
||||
boolean readFlag[];//read flag
|
||||
SecretKey keys[];//level key for each partition
|
||||
|
||||
|
||||
Position pos_map[];//position map
|
||||
SocketClientUtil[] cli;
|
||||
|
||||
|
||||
KeyGenerator kg;
|
||||
|
||||
public int realDataNumber = 0;
|
||||
|
||||
public MCOSPartition(int realBlocks_p, int levels, Position posMap[], SocketClientUtil[] cLi, int p )
|
||||
{
|
||||
partition=p;
|
||||
pos_map=posMap;
|
||||
cli=cLi;
|
||||
|
||||
n_realBlocks_p = realBlocks_p;
|
||||
|
||||
n_levels = levels;
|
||||
n_capacity = (int) Math.ceil(CommInfo.capacity_parameter * n_realBlocks_p);
|
||||
top_level_len = n_capacity - (1 << n_levels) + 2;
|
||||
|
||||
readFlag=new boolean[n_capacity];
|
||||
keys=new SecretKey[n_levels];
|
||||
blockIDs=new int[n_capacity];
|
||||
nextDummy=new int[n_levels];
|
||||
dummyNumbers=new int[n_levels];
|
||||
filled=new boolean[n_levels];
|
||||
clouds=new int[n_levels];
|
||||
|
||||
for (int i=0;i<n_levels;i++)
|
||||
{
|
||||
dummyNumbers[i]=0;
|
||||
nextDummy[i]=0;
|
||||
filled[i]=false;
|
||||
clouds[i]=-1;
|
||||
}
|
||||
for (int i=0;i<n_capacity;i++)
|
||||
{
|
||||
readFlag[i]=true;
|
||||
blockIDs[i]=CommInfo.dummyID;
|
||||
}
|
||||
|
||||
initKeys();
|
||||
}
|
||||
|
||||
|
||||
private void initKeys()
|
||||
{
|
||||
try {
|
||||
kg = KeyGenerator.getInstance("AES");
|
||||
kg.init(128);
|
||||
for (int j = 0; j < n_levels; j++)
|
||||
keys[j] = kg.generateKey();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getKey(int pos)
|
||||
{
|
||||
return keys[pos].getEncoded();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void readForShuffle(int block_id, SocketClientUtil cli, byte[] bSessionID, byte[] bSfk, int levels ) {
|
||||
|
||||
/*******************************
|
||||
* Gnerate the OFFSETs
|
||||
* *****************************/
|
||||
byte[] ids = new byte[ n_levels * 4 ];
|
||||
int level = -1;
|
||||
if (block_id!=CommInfo.dummyID)
|
||||
level = pos_map[block_id].level;
|
||||
int length = 0;
|
||||
for (int i=0;i<n_levels;i++)
|
||||
{
|
||||
if (filled[i])
|
||||
{
|
||||
int _id = (1 << (i + 1)) - 2;
|
||||
|
||||
if (level==i && block_id!=CommInfo.dummyID)
|
||||
{
|
||||
_id += pos_map[block_id].offset;
|
||||
}else{
|
||||
// not in this level, to read a dummy block, get the dummy offset
|
||||
int dID=nextDummy(0, i);
|
||||
if (dID == -1) // There is no dummy block can be read
|
||||
continue;
|
||||
_id += dID;//nextDummy(i);
|
||||
}
|
||||
readFlag[_id]=true;
|
||||
Util.intToByte(ids, length*4, _id);
|
||||
length ++;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] cmd=new byte[37];
|
||||
cmd[0]=CommandType.noticeShuffle;
|
||||
System.arraycopy(bSessionID, 0, cmd, 1, 8);
|
||||
System.arraycopy(bSfk, 0, cmd, 9, 16);
|
||||
|
||||
Util.intToByte(cmd, 25, partition);
|
||||
Util.intToByte(cmd, 29, length);
|
||||
Util.intToByte(cmd, 33, levels);
|
||||
|
||||
if (length==0)
|
||||
{
|
||||
//should send a key to the cloud to shuffle
|
||||
cli.send(cmd, 37, null, 0, null);
|
||||
}else{
|
||||
cli.send(cmd, 37, ids, length*4, null);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized byte[] readPartition(int block_id ) {
|
||||
/***********************************************
|
||||
* Decide which cloud need to do shuffle or to read
|
||||
*********************************************/
|
||||
int realLevel = -1;
|
||||
int realCloud = -1;
|
||||
if (block_id!=CommInfo.dummyID){
|
||||
realLevel = this.pos_map[block_id].level;
|
||||
realCloud = this.pos_map[block_id].level;
|
||||
}
|
||||
int levelnumbers1=0;
|
||||
int levelnumbers2=0;
|
||||
for (int i=0;i<this.n_levels;i++)
|
||||
{
|
||||
if (this.filled[i]==true)
|
||||
{
|
||||
if (this.clouds[i]==0)
|
||||
levelnumbers1++;
|
||||
if (this.clouds[i]==1)
|
||||
levelnumbers2++;
|
||||
}
|
||||
}
|
||||
int shuffleCloud =0;
|
||||
if (levelnumbers1 == 0 && levelnumbers2 ==0 )
|
||||
return null;
|
||||
else{
|
||||
if (levelnumbers1 < levelnumbers2)
|
||||
shuffleCloud=1;
|
||||
}
|
||||
|
||||
int otherCloud=(shuffleCloud==0)?1:0;
|
||||
|
||||
// /***********************************************
|
||||
// * get the first unfilled level
|
||||
// *********************************************/
|
||||
// int level=-1;
|
||||
// for (int i=0;i<this.n_levels;i++)
|
||||
// {
|
||||
// if (this.filled[i]==false)
|
||||
// {
|
||||
// level=i;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
/********************************************
|
||||
* Session ID and shuffle key
|
||||
***************************************/
|
||||
byte[] bSessionID = Util.generateSessionData(8);
|
||||
byte[] bSfk=null;
|
||||
SecretKey sfk =null;
|
||||
KeyGenerator kg;
|
||||
try {
|
||||
kg = KeyGenerator.getInstance("AES");
|
||||
kg.init(128);
|
||||
sfk = kg.generateKey();
|
||||
bSfk= sfk.getEncoded();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* Get the real block position and compute its position after shuffle
|
||||
***************************************/
|
||||
//Get which level the real block is in
|
||||
int realPos = 0;
|
||||
if (realLevel == -1)
|
||||
{
|
||||
//if dummy block, random select
|
||||
Random rnd=new Random();
|
||||
realPos=rnd.nextInt(levelnumbers1 + levelnumbers2);
|
||||
}else{
|
||||
//first the shuffle cloud will read the levels in it, and then received the data from other clouds
|
||||
//the position in this sequence is the original real position of blockID
|
||||
boolean bFind=false;
|
||||
for (int i = 0; i < n_levels; i++) {
|
||||
if (filled[i] == true && clouds[i]==shuffleCloud)
|
||||
{
|
||||
realPos++;
|
||||
if (realLevel==i){
|
||||
bFind=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bFind==false)
|
||||
{
|
||||
for (int i = 0; i <= realLevel; i++) {
|
||||
if (filled[i] == true && clouds[i] == otherCloud)
|
||||
{
|
||||
realPos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//get the permute result
|
||||
if (realPos>0) realPos--;
|
||||
int targetPos = realPos;
|
||||
//psuedo_random_permute( levelnumbers1 + levelnumbers2, sfk, realPos);
|
||||
//Util.fpeForPermution(realPos, sfk, levelnumbers1 + levelnumbers2);
|
||||
|
||||
//System.out.println(" realPos: "+realPos+" targetPos: "+targetPos);
|
||||
/**********************************************************************************
|
||||
* read for shuffle
|
||||
*******************************************************************************/
|
||||
/*******************************
|
||||
* Generate the OFFSETs in shuffle cloud
|
||||
* And the ids read in other cloud
|
||||
* *****************************/
|
||||
byte[] ids = new byte[ n_levels * 4 ];
|
||||
byte[] idsOther = new byte[ n_levels * 4 ];
|
||||
int length = 0;
|
||||
int lengthOther = 0;
|
||||
for (int i=0;i<n_levels;i++)
|
||||
{
|
||||
if (filled[i])
|
||||
{
|
||||
int _id = (1 << (i + 1)) - 2;
|
||||
|
||||
if (realLevel==i)
|
||||
{
|
||||
_id += pos_map[block_id].offset;
|
||||
}else{
|
||||
// not in this level, to read a dummy block, get the dummy offset
|
||||
int dID=nextDummy(0, i);
|
||||
if (dID == -1) // There is no dummy block can be read
|
||||
continue;
|
||||
_id += dID;//nextDummy(i);
|
||||
}
|
||||
readFlag[_id]=true;
|
||||
if (clouds[i]==shuffleCloud){
|
||||
Util.intToByte(ids, length*4, _id);
|
||||
length ++;
|
||||
}
|
||||
if (clouds[i]==otherCloud){
|
||||
Util.intToByte(idsOther, lengthOther*4, _id);
|
||||
lengthOther ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte[] cmd=new byte[37];
|
||||
cmd[0]=CommandType.noticeShuffle;
|
||||
System.arraycopy(bSessionID, 0, cmd, 1, 8);
|
||||
System.arraycopy(bSfk, 0, cmd, 9, 16);
|
||||
|
||||
Util.intToByte(cmd, 25, partition);
|
||||
Util.intToByte(cmd, 29, length);
|
||||
Util.intToByte(cmd, 33, levelnumbers1 + levelnumbers2);
|
||||
|
||||
cli[shuffleCloud].send(cmd, 37);
|
||||
if (length > 0)
|
||||
{
|
||||
cli[shuffleCloud].send( ids, length*4 );
|
||||
}
|
||||
|
||||
byte[] cmd1=new byte[2];
|
||||
cmd1[0]=0;
|
||||
cmd1[1]=0;
|
||||
cli[shuffleCloud].sendAndReceive(cmd1, 2);
|
||||
|
||||
/**********************************************************************************
|
||||
* read for cloud
|
||||
*******************************************************************************/
|
||||
cmd[0]=CommandType.readCloud;
|
||||
System.arraycopy(bSessionID, 0, cmd, 1, 8);
|
||||
Util.intToByte(cmd, 9, partition);
|
||||
Util.intToByte(cmd, 13, targetPos);
|
||||
Util.intToByte(cmd, 17, lengthOther);
|
||||
Util.intToByte(cmd, 21, shuffleCloud);
|
||||
|
||||
byte[] bData=new byte[CommInfo.blockSize];
|
||||
if (lengthOther==0)
|
||||
{
|
||||
cli[otherCloud].send(cmd, 25, null, 0, bData);
|
||||
}else{
|
||||
// get the data
|
||||
|
||||
cli[otherCloud].send(cmd, 25, idsOther, lengthOther*4, bData);
|
||||
}
|
||||
|
||||
|
||||
//generate the information for analysis
|
||||
Util.readNumber ++;
|
||||
Util.readbandwidth += 37 + 25+ (length+lengthOther)*4 + CommInfo.blockSize;
|
||||
Util.cloudtocloud++;
|
||||
|
||||
Util.cloudcloudbandwidth += (lengthOther + length + lengthOther) * CommInfo.blockSize ;
|
||||
|
||||
|
||||
return bData;
|
||||
}
|
||||
|
||||
|
||||
public int psuedo_random_permute(int filledLevelLength, SecretKey sfk, int realPos) {
|
||||
int[] shffule = new int[filledLevelLength];
|
||||
|
||||
for (int i = 0; i <filledLevelLength; i++) {
|
||||
shffule[i]=i;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i <filledLevelLength; i++) {
|
||||
int j = Util.fpeForPermution(i, sfk, filledLevelLength);
|
||||
int t = shffule[i];
|
||||
shffule[i] = shffule[j];
|
||||
shffule[j] = shffule[i];
|
||||
}
|
||||
return shffule[realPos];
|
||||
}
|
||||
|
||||
|
||||
public byte[] generateXORBlock(int p, int _id, SecretKey userKey)
|
||||
{
|
||||
//Encrypt the 0x00 default value by the userkey
|
||||
byte[] data=new byte[CommInfo.blockSize];
|
||||
for (int i=0;i<CommInfo.blockSize;i++)
|
||||
{
|
||||
data[i] = 0;
|
||||
}
|
||||
/****************************
|
||||
* The first 4 bytes is the dummmyID and the random value, to make sure it is less than 0
|
||||
*
|
||||
* But now, to simplify the implementation, we ignore the random value for the same 0000000
|
||||
* ******************************/
|
||||
int dummyID = CommInfo.dummyID - Util.rand_int(n_capacity);
|
||||
blockIDs[_id]=dummyID;
|
||||
|
||||
// byte[] iv = Util.generateIV(dummyID);
|
||||
|
||||
//encrypt
|
||||
// SymmetricCypto scp=new SymmetricCypto(CommInfo.keySize);
|
||||
// scp.initEnc(userKey, iv);
|
||||
// scp.enc_decData(data, CommInfo.blockSize);
|
||||
return data;
|
||||
}
|
||||
|
||||
public synchronized void writePartition(SlotObject targetObj )
|
||||
{
|
||||
|
||||
/******************************
|
||||
* Select the cloud which contains the consecutive levels
|
||||
**********************************/
|
||||
//should tell the cloud unread block IDs, but we ignore here
|
||||
int unreadDataNumber = 0; // the un-read data number
|
||||
int filledLevel =-1;
|
||||
int cloud = 0;//the cloud to do merge
|
||||
|
||||
/*******************
|
||||
* 1. judge which cloud to be written
|
||||
* The algorithm is that cloud = Filled level - -1 +cloud % 2
|
||||
* This is which cloud should be written
|
||||
* **************************/
|
||||
for (int i=0; i<this.n_levels; i++)
|
||||
{
|
||||
if (filled[i]==true)
|
||||
{
|
||||
filledLevel=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (filledLevel ==-1 )
|
||||
cloud = 0;
|
||||
else
|
||||
if (filledLevel == 0 )
|
||||
cloud = clouds[0];
|
||||
else
|
||||
cloud = (filledLevel-1+clouds[filledLevel])%2;
|
||||
/**************************************
|
||||
* cloud is the target cloud to be written
|
||||
* The unfilled level is not 0, then written to other cloud
|
||||
*************************************/
|
||||
|
||||
/*******************
|
||||
* 2. get the unfilled level
|
||||
* **************************/
|
||||
int unfilledLevel=-1;
|
||||
for (int i=0; i<this.n_levels; i++)
|
||||
{
|
||||
if (filled[i]==false )
|
||||
{
|
||||
unfilledLevel=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int otherCloud = cloud ;
|
||||
if (unfilledLevel>0)
|
||||
otherCloud =(cloud==0)?1:0;
|
||||
/***************************************************
|
||||
* COMPUTE the range of the levels
|
||||
* ********************************************/
|
||||
int begin = 0;
|
||||
int end = (1 << (unfilledLevel + 1)) - 2;
|
||||
boolean bSpecialCase = false;
|
||||
if (unfilledLevel == -1){
|
||||
bSpecialCase = true;
|
||||
//All Filled levels, special treatment
|
||||
unfilledLevel = n_levels - 1;
|
||||
end = this.n_capacity;
|
||||
}
|
||||
|
||||
for (int i=begin; i<end; i++)
|
||||
if (readFlag[i] == false)
|
||||
{
|
||||
unreadDataNumber++;
|
||||
}
|
||||
|
||||
/**********************************************
|
||||
* GEI the maxinum number of blocks in this level
|
||||
* *****************************************/
|
||||
int filledLevelLength = 0;
|
||||
if (unfilledLevel != n_levels - 1) {
|
||||
filledLevelLength = 2 *(1 << unfilledLevel);
|
||||
} else filledLevelLength = top_level_len;
|
||||
|
||||
|
||||
/***********************
|
||||
* Special case, special treatment
|
||||
* **********************/
|
||||
|
||||
byte[] ids=new byte[unreadDataNumber*4];//id in partition , for reading
|
||||
|
||||
/*****************
|
||||
* Special case: un-read data number is bigger than filledlevel length
|
||||
* ********************/
|
||||
if (unreadDataNumber > filledLevelLength-2)
|
||||
{
|
||||
unreadDataNumber=filledLevelLength-2;
|
||||
//read the real block and then the dummy blocks
|
||||
int pos = 0;
|
||||
//first , real block
|
||||
for (int level = 0; level < this.n_levels; level++) {
|
||||
if (filled[level]) {
|
||||
|
||||
begin = (1 << (level + 1)) - 2;
|
||||
int datalen = 0;
|
||||
if (level != n_levels - 1) {
|
||||
datalen = 2 * (1 << level);
|
||||
} else
|
||||
datalen = top_level_len;
|
||||
|
||||
for (int _id = begin; _id < begin + datalen; _id++) {
|
||||
if (this.readFlag[_id] == false && this.blockIDs[_id]>=0) {
|
||||
Util.intToByte(ids, pos * 4, _id);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
//second , dummy block
|
||||
for (int level = 0; level < this.n_levels; level++) {
|
||||
if (filled[level]) {
|
||||
|
||||
begin = (1 << (level + 1)) - 2;
|
||||
int datalen = 0;
|
||||
if (level != n_levels - 1) {
|
||||
datalen = 2 * (1 << level);
|
||||
} else
|
||||
datalen = top_level_len;
|
||||
|
||||
for (int _id = begin; _id < begin + datalen; _id++) {
|
||||
if (pos>unreadDataNumber)
|
||||
break;
|
||||
if (this.readFlag[_id] == false && this.blockIDs[_id]<0) {
|
||||
Util.intToByte(ids, pos * 4, _id);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
int pos = 0;
|
||||
for (int level = 0; level < this.n_levels; level++) {
|
||||
if (filled[level]) {
|
||||
|
||||
begin = (1 << (level + 1)) - 2;
|
||||
int datalen = 0;
|
||||
if (level != n_levels - 1) {
|
||||
datalen = 2 * (1 << level);
|
||||
} else
|
||||
datalen = top_level_len;
|
||||
|
||||
for (int _id = begin; _id < begin + datalen; _id++) {
|
||||
if (this.readFlag[_id] == false) {
|
||||
Util.intToByte(ids, pos * 4, _id);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************
|
||||
* Send to server
|
||||
* *****************************************/
|
||||
byte[] cmd1=new byte[25];
|
||||
cmd1[0]=CommandType.noticeWriteCloud;
|
||||
Util.intToByte(cmd1, 1, partition);
|
||||
Util.intToByte(cmd1, 5, cloud);
|
||||
Util.intToByte(cmd1, 9, unfilledLevel);
|
||||
Util.intToByte(cmd1, 13, filledLevelLength);
|
||||
Util.intToByte(cmd1, 17, unreadDataNumber);
|
||||
Util.intToByte(cmd1, 21, otherCloud);
|
||||
|
||||
|
||||
|
||||
cli[cloud].send(cmd1, 25);
|
||||
|
||||
cli[cloud].send(targetObj.value, CommInfo.blockSize );
|
||||
|
||||
|
||||
if (unreadDataNumber>0)
|
||||
cli[cloud].send(ids, unreadDataNumber*4 );
|
||||
|
||||
//key? shuffle ?- for later
|
||||
keys[unfilledLevel]=kg.generateKey();
|
||||
filled[unfilledLevel]=false;
|
||||
|
||||
byte[] shufflekey = getKey(unfilledLevel);//Util.generateDummyData(MCloudCommInfo.keySize);
|
||||
cli[cloud].send(shufflekey, 16);
|
||||
|
||||
|
||||
|
||||
|
||||
//generate the information for analysis
|
||||
Util.writeNumber ++;
|
||||
Util.bandwidth += CommInfo.blockSize + 25 + unreadDataNumber*4 + CommInfo.keySize + 4*(filledLevelLength-unreadDataNumber-1);
|
||||
if (otherCloud != cloud) {
|
||||
Util.cloudtocloud++;
|
||||
Util.cloudcloudbandwidth += (filledLevelLength) * CommInfo.blockSize ;
|
||||
}
|
||||
|
||||
|
||||
int[] bIDS = new int[filledLevelLength];
|
||||
bIDS[0]=targetObj.id;
|
||||
for (int i=0;i<unreadDataNumber;i++)
|
||||
{
|
||||
int _id=Util.byteToInt(ids, i*4, 4);
|
||||
bIDS[i+1]=blockIDs[_id];
|
||||
}
|
||||
for (int i=unreadDataNumber;i<filledLevelLength-1;i++)
|
||||
{
|
||||
bIDS[i+1]=CommInfo.dummyID;
|
||||
}
|
||||
|
||||
|
||||
psuedo_random_permute( shufflekey, filledLevelLength, bIDS);
|
||||
//send over and receive
|
||||
cmd1[0]=0;
|
||||
cmd1[1]=0;
|
||||
cli[cloud].sendAndReceive(cmd1, 2);
|
||||
|
||||
/**********************************************
|
||||
* reset client status
|
||||
* *****************************************/
|
||||
//reset status. will be filled to another level
|
||||
for (int i=0; i<unfilledLevel;i++)
|
||||
{
|
||||
nextDummy[i]=0;
|
||||
filled[i]=false;
|
||||
clouds[i]=-1;
|
||||
}
|
||||
//set this cloud as null ,but the other unfilled level as true
|
||||
nextDummy[unfilledLevel]=0;
|
||||
filled[unfilledLevel]=true;
|
||||
clouds[unfilledLevel]=otherCloud;
|
||||
|
||||
int levelBegin = (1 << (unfilledLevel + 1)) - 2;
|
||||
for (int i=0; i<levelBegin; i++)
|
||||
{
|
||||
blockIDs[i] = CommInfo.dummyID;
|
||||
readFlag[i]=true;
|
||||
}
|
||||
for (int i=0;i<filledLevelLength;i++)
|
||||
{
|
||||
int bID=bIDS[i];
|
||||
int _id = i+levelBegin;
|
||||
blockIDs[_id] = CommInfo.dummyID;
|
||||
readFlag[_id] = false;
|
||||
if (bID>=0)
|
||||
{
|
||||
blockIDs[_id] = bID;
|
||||
//update the position map
|
||||
pos_map[bID].cloud = otherCloud; //store other cloud
|
||||
pos_map[bID].partition = this.partition;
|
||||
pos_map[bID].level = unfilledLevel;
|
||||
pos_map[bID].offset = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* Permute the blockIDs in the client based on the key
|
||||
* @param shufflekey
|
||||
*/
|
||||
private void psuedo_random_permute(byte[] shufflekey, int filledLevelLength, int[] bIDS) {
|
||||
Util.writeNumber = Util.writeNumber+1;
|
||||
|
||||
|
||||
// for (int i = 0; i < filledLevelLength; i++) {
|
||||
// System.out.println("i: "+i+" "+blockIDs[i]);
|
||||
// }
|
||||
|
||||
SecretKey sfk = new SecretKeySpec(shufflekey, "AES");
|
||||
|
||||
for (int i = 0; i < filledLevelLength; i++) {
|
||||
int j = Util.fpeForPermution(i, sfk, filledLevelLength);
|
||||
int t = bIDS[i];
|
||||
bIDS[i] = bIDS[j];
|
||||
bIDS[j] = t;
|
||||
|
||||
// System.out.println("permute: "+i+" "+j);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int nextDummy(int type, int level)
|
||||
{
|
||||
int begin = (1 << (level + 1)) - 2;
|
||||
int end=0;
|
||||
if (level != n_levels - 1) {
|
||||
end = 2 *(1 << level);
|
||||
} else end = top_level_len;
|
||||
//compute the position in the position map
|
||||
for (int i=nextDummy[level];i<end;i++)
|
||||
if (blockIDs[begin+i]<= CommInfo.dummyID)
|
||||
{
|
||||
nextDummy[level]=i+1;
|
||||
return i;
|
||||
}
|
||||
|
||||
//Notice that, there is no dummy blocks
|
||||
//System.out.println("No dummy !!!!!! return 0!!!!!p:"+this.partition+" !!!type:"+type+" level:"+level+" nextDummy[level]"+nextDummy[level]);
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package nankai.oram.client.mCloud;
|
||||
|
||||
public interface MCloudCommInfo {
|
||||
|
||||
|
||||
// public static int severBeginLevel = 3;//the default level of each partition in the server
|
||||
// public static int clientEndLevel = 2;//the default level of each partition in the client cache
|
||||
// public static int evictConditionSize = 8;//1+2+4+8+16=31
|
||||
// public static int cloudNumber = 2; //the cloud number
|
||||
|
||||
// public static int severBeginLevel = 4;//the default level of each partition in the server
|
||||
// public static int clientEndLevel =3;//the default level of each partition in the client cache
|
||||
// public static int evictConditionSize = 16;//1+2+4=6
|
||||
// public static int cloudNumber = 2; //the cloud number
|
||||
|
||||
// public static int severBeginLevel = 2;//the default level of each partition in the server
|
||||
// public static int clientEndLevel =1;//the default level of each partition in the client cache
|
||||
// public static int evictConditionSize = 3;//1+2+4=6
|
||||
// public static int cloudNumber = 2; //the cloud number
|
||||
|
||||
public static int severBeginLevel = 5;//the default level of each partition in the server
|
||||
public static int clientEndLevel = 4;//the default level of each partition in the client cache
|
||||
public static int evictConditionSize = 32;//1+2+4+8=15
|
||||
public static int cloudNumber = 2; //the cloud number
|
||||
|
||||
public static String[] ip={ "114.215.26.85", "114.215.26.85"};
|
||||
//public static String[] ip={ "localhost", "localhost"};
|
||||
public static int[] port={ 2121, 2122};
|
||||
}
|
|
@ -0,0 +1,702 @@
|
|||
package nankai.oram.client.mCloud;
|
||||
|
||||
/*************
|
||||
* The data in a level of a partition is encrypted by the key for level
|
||||
*
|
||||
* Each data is included by BID+DATA
|
||||
* BID = REALBLOCK? BLOCKID : - OFFSET
|
||||
*/
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import nankai.oram.client.common.Position;
|
||||
import nankai.oram.client.common.SlotObject;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.SocketClientUtil;
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.SymmetricCypto;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class NewMCOSPartition{
|
||||
public static int part=0;
|
||||
int n_levels;
|
||||
|
||||
int n_realBlocks_p;//the real number of blocks in a partition
|
||||
int n_capacity;//the max capacity of a partition -- need the top level
|
||||
int top_level_len;//the number of blocks in the top level
|
||||
|
||||
int partition = 0;
|
||||
int blockIDs[];//all the blockIDs. When re-shuffle, the dummyIDs will be re-filled
|
||||
int dummyNumbers[];//the dummy block numbers; When re-shuffle, the dummyIDs will be filled
|
||||
int nextDummy[];//the dummy block counter;
|
||||
boolean filled[];//filled level flag
|
||||
boolean readFlag[];//read flag
|
||||
SecretKey keys[];//level key for each partition
|
||||
|
||||
byte s_buffer[][];
|
||||
|
||||
Position pos_map[];//position map
|
||||
SocketClientUtil cli;
|
||||
|
||||
SubCloudNewORAM subOram;
|
||||
|
||||
KeyGenerator kg;
|
||||
|
||||
public int realDataNumber = 0;
|
||||
|
||||
public NewMCOSPartition(int realBlocks_p, int levels, Position posMap[], SocketClientUtil cLi, SubCloudNewORAM soram,byte sBuffer[][])
|
||||
{
|
||||
subOram=soram;
|
||||
pos_map=posMap;
|
||||
cli=cLi;
|
||||
s_buffer = sBuffer;
|
||||
n_realBlocks_p = realBlocks_p;
|
||||
|
||||
n_levels = levels;
|
||||
n_capacity = (int) Math.ceil(CommInfo.capacity_parameter * n_realBlocks_p);
|
||||
top_level_len = n_capacity - (1 << n_levels) + 2;
|
||||
|
||||
readFlag=new boolean[n_capacity];
|
||||
keys=new SecretKey[n_levels];
|
||||
blockIDs=new int[n_capacity];
|
||||
nextDummy=new int[n_levels];
|
||||
dummyNumbers=new int[n_levels];
|
||||
filled=new boolean[n_levels];
|
||||
|
||||
for (int i=0;i<n_levels;i++)
|
||||
{
|
||||
dummyNumbers[i]=0;
|
||||
nextDummy[i]=0;
|
||||
filled[i]=false;
|
||||
}
|
||||
for (int i=0;i<n_capacity;i++)
|
||||
{
|
||||
readFlag[i]=true;
|
||||
blockIDs[i]=CommInfo.dummyID;
|
||||
}
|
||||
|
||||
initKeys();
|
||||
}
|
||||
|
||||
|
||||
private void initKeys()
|
||||
{
|
||||
try {
|
||||
kg = KeyGenerator.getInstance("AES");
|
||||
kg.init(128);
|
||||
for (int j = 0; j < n_levels; j++)
|
||||
keys[j] = kg.generateKey();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getKey(int pos)
|
||||
{
|
||||
return keys[pos].getEncoded();
|
||||
}
|
||||
|
||||
public byte[] readPartition(int block_id, SecretKey userKey) {
|
||||
|
||||
/*******************************
|
||||
* Gnerate the OFFSETs
|
||||
*
|
||||
* Length + ID1 ...... + ID2......
|
||||
* *****************************/
|
||||
byte[] data = new byte[CommInfo.blockSize];
|
||||
byte[] xorZero = new byte[CommInfo.blockSize];
|
||||
byte[] ids = new byte[ n_levels * 4 ];
|
||||
int[] levels = new int[n_levels];
|
||||
int level = -1;
|
||||
if (block_id!=CommInfo.dummyID)
|
||||
level = pos_map[block_id].level;
|
||||
int length = 0;
|
||||
int realDataID = -1;
|
||||
for (int i=MCloudCommInfo.severBeginLevel;i<n_levels;i++)
|
||||
{
|
||||
if (filled[i])
|
||||
{
|
||||
int _id = (1 << (i + 1)) - 2;
|
||||
|
||||
if (level==i && block_id!=CommInfo.dummyID)
|
||||
{
|
||||
_id += pos_map[block_id].offset;
|
||||
realDataID = _id;
|
||||
}else{
|
||||
// not in this level, to read a dummy block, get the dummy offset
|
||||
int dID=nextDummy(0, i);
|
||||
if (dID == -1) // There is no dummy block can be read
|
||||
continue;
|
||||
_id += dID;//nextDummy(i);
|
||||
}
|
||||
readFlag[_id]=true;
|
||||
Util.intToByte(ids, length*4, _id);
|
||||
levels[length] = i;
|
||||
length ++;
|
||||
}
|
||||
}
|
||||
if (length==0)
|
||||
return null;
|
||||
|
||||
/*************************
|
||||
* Send to the cloud
|
||||
*
|
||||
* Command: readCloud
|
||||
* content: partition + length
|
||||
* offsets
|
||||
* **************************/
|
||||
//System.out.println("read partition length:"+length);
|
||||
byte[] cmd=new byte[9];
|
||||
cmd[0]=CommandType.readCloud;
|
||||
Util.intToByte(cmd, 1, partition);
|
||||
Util.intToByte(cmd, 5, length);
|
||||
|
||||
cli.send(cmd, 9, ids, length*4, data);
|
||||
|
||||
|
||||
|
||||
Util.readbandwidth += 9+length*4+CommInfo.blockSize; //
|
||||
Util.readNumber ++ ; //
|
||||
/*************************************
|
||||
* Decrypt Data based on XOR technique
|
||||
*
|
||||
* Enc-level-key and Enc-enc-key
|
||||
* **********************************/
|
||||
if (block_id != CommInfo.dummyID) {
|
||||
SymmetricCypto scp = new SymmetricCypto(CommInfo.keySize);
|
||||
for (int i = 0; i < length; i++) {
|
||||
// XOR the data 000000
|
||||
int _id = Util.byteToInt(ids, i * 4, 4);
|
||||
if (_id >= 0)
|
||||
continue;
|
||||
byte[] iv = Util.generateIV(_id);
|
||||
for (int j = 0; j < CommInfo.blockSize; j++)
|
||||
xorZero[j] = 0;
|
||||
|
||||
// // first onion encrypt userkey
|
||||
// scp.initEnc(userKey, iv);
|
||||
// scp.enc_decData(xorZero, CommInfo.blockSize);
|
||||
// // second onion encrypt level key
|
||||
// scp.initEnc(keys[levels[i]], null);
|
||||
// scp.enc_decData(xorZero, CommInfo.blockSize);
|
||||
|
||||
// XOR
|
||||
for (int j = 0; j < CommInfo.blockSize; j++)
|
||||
data[j] ^= xorZero[j];
|
||||
|
||||
}
|
||||
|
||||
// // First onion decrypt by level key
|
||||
// scp.initDec(keys[level], null);
|
||||
// scp.enc_decData(data, CommInfo.blockSize);
|
||||
|
||||
// Second, onion decrypt by the user key
|
||||
subOram.decryptData(data);
|
||||
}
|
||||
return data ;
|
||||
}
|
||||
|
||||
public byte[] generateXORBlock(int p, int _id, SecretKey userKey)
|
||||
{
|
||||
//Encrypt the 0x00 default value by the userkey
|
||||
byte[] data=new byte[CommInfo.blockSize];
|
||||
for (int i=0;i<CommInfo.blockSize;i++)
|
||||
{
|
||||
data[i] = 0;
|
||||
}
|
||||
/****************************
|
||||
* The first 4 bytes is the dummmyID and the random value, to make sure it is less than 0
|
||||
*
|
||||
* But now, to simplify the implementation, we ignore the random value for the same 0000000
|
||||
* ******************************/
|
||||
int dummyID = CommInfo.dummyID - Util.rand_int(n_capacity);
|
||||
blockIDs[_id]=dummyID;
|
||||
|
||||
// byte[] iv = Util.generateIV(dummyID);
|
||||
|
||||
//encrypt
|
||||
// SymmetricCypto scp=new SymmetricCypto(CommInfo.keySize);
|
||||
// scp.initEnc(userKey, iv);
|
||||
// scp.enc_decData(data, CommInfo.blockSize);
|
||||
return data;
|
||||
}
|
||||
|
||||
public void writePartition(Queue slot, SocketClientUtil cli, int otherCloud, SocketClientUtil cliOtherCloud, SecretKey userKey, int cloud)
|
||||
{
|
||||
//System.out.println("write begin!!");
|
||||
int evictSize = MCloudCommInfo.evictConditionSize;
|
||||
if (slot.size()<evictSize) {
|
||||
evictSize = slot.size();
|
||||
}
|
||||
|
||||
|
||||
int unfilledLevel = -1;
|
||||
for (int i = MCloudCommInfo.severBeginLevel; i < this.n_levels; i++) {
|
||||
if (!filled[i]) {
|
||||
unfilledLevel = i ;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (unfilledLevel == MCloudCommInfo.severBeginLevel){
|
||||
//CASE 2
|
||||
writeCase1(slot, userKey, cloud, evictSize, unfilledLevel);
|
||||
}else{
|
||||
|
||||
|
||||
try {
|
||||
writeCase2(slot, cli, otherCloud, cliOtherCloud, userKey,
|
||||
cloud, evictSize, unfilledLevel);
|
||||
} catch (Exception e) {
|
||||
System.out.println("error!!");
|
||||
}
|
||||
}
|
||||
|
||||
//System.out.println("write ok!!");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void writeCase2(Queue slot, SocketClientUtil cli, int otherCloud,
|
||||
SocketClientUtil cliOtherCloud, SecretKey userKey, int cloud,
|
||||
int evictSize, int unfilledLevel) {
|
||||
// System.out.println(" writeCase2 ");
|
||||
|
||||
byte[] bSessionID = Util.generateSessionData(8);
|
||||
int unreadRealDataNumber = 0;
|
||||
/***************************************************
|
||||
* COMPUTE the range of the levels
|
||||
* ********************************************/
|
||||
int begin = (1 << (MCloudCommInfo.severBeginLevel + 1)) - 2;
|
||||
int end = (1 << (unfilledLevel + 1)) - 2;
|
||||
boolean bSpecialCase = false;
|
||||
if (unfilledLevel == -1){
|
||||
bSpecialCase = true;
|
||||
//All Filled levels, special treatment
|
||||
unfilledLevel = n_levels - 1;
|
||||
end = this.n_capacity;
|
||||
}
|
||||
|
||||
for (int i=begin; i<end; i++)
|
||||
if (readFlag[i] == false)
|
||||
{
|
||||
if (blockIDs[i]>=0)
|
||||
unreadRealDataNumber++;
|
||||
}
|
||||
|
||||
/**********************************************
|
||||
* GEI the maxinum number of blocks in this level
|
||||
* *****************************************/
|
||||
int filledLevelLength = 0;
|
||||
if (unfilledLevel != n_levels - 1) {
|
||||
filledLevelLength = 2 *(1 << unfilledLevel);
|
||||
} else filledLevelLength = top_level_len;
|
||||
|
||||
int dataNumber=unreadRealDataNumber;
|
||||
|
||||
byte[] ids=new byte[dataNumber*4];//id in partition , for reading
|
||||
int[] intIDs=new int[dataNumber];//id
|
||||
byte[] levels=new byte[dataNumber];//store each id's level, for onion decryption
|
||||
|
||||
int pos = 0;
|
||||
for (int level = MCloudCommInfo.severBeginLevel; level < this.n_levels; level++) {
|
||||
if (filled[level]) {
|
||||
|
||||
begin = (1 << (level + 1)) - 2;
|
||||
int datalen = 0;
|
||||
if (level != n_levels - 1) {
|
||||
datalen = 2 * (1 << level);
|
||||
} else
|
||||
datalen = top_level_len;
|
||||
|
||||
for (int _id = begin; _id < begin + datalen; _id++) {
|
||||
if (this.readFlag[_id] == false && blockIDs[_id]>=0 ) {
|
||||
Util.intToByte(ids, pos * 4, _id);
|
||||
levels[pos] = (byte) level;
|
||||
intIDs[pos++] = blockIDs[_id];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos!=unreadRealDataNumber)
|
||||
System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
|
||||
/****************************************
|
||||
* (1)Notice Shuffle , Send All the data, onionkeys in slots to the otherCloud
|
||||
*
|
||||
* CommandType: noticeShuffle
|
||||
* Content: session ID | unfilled levels number |
|
||||
* onion keys and slots data
|
||||
*
|
||||
* (2)Notice this cloud to send the data to the otherCloud for shuffling
|
||||
* CommandType: writeCloud
|
||||
* content: session ID | unfilled - partition | other cloud for shuffling | length of ids
|
||||
*
|
||||
*
|
||||
* (3)Send back the shuffled Data -- cloud to cloud, but not the client
|
||||
* CommandType: backData
|
||||
* ************************************/
|
||||
|
||||
//System.out.println("write partition filledLevelLength:"+filledLevelLength+" dataNumber:"+dataNumber+" unreadRealDataNumber:"+unreadRealDataNumber+" bSessionID:"+bSessionID[0]);
|
||||
|
||||
|
||||
int rndLength = filledLevelLength - dataNumber - 2*evictSize;
|
||||
if (rndLength<0){
|
||||
System.out.println(" rndLength "+ rndLength +" filledLevelLength "+filledLevelLength+" dataNumber "+dataNumber+" evictSize "+evictSize );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*********************** First command: noticeShuffle ***************************/
|
||||
byte[] cmd=new byte[29];
|
||||
cmd[0]=CommandType.noticeShuffle;
|
||||
System.arraycopy(bSessionID, 0, cmd, 1, 8);
|
||||
Util.intToByte(cmd, 9, partition);
|
||||
Util.intToByte(cmd, 13, unfilledLevel);
|
||||
Util.intToByte(cmd, 17, filledLevelLength);
|
||||
Util.intToByte(cmd, 21, dataNumber);
|
||||
Util.intToByte(cmd, 25, evictSize);
|
||||
|
||||
|
||||
|
||||
cliOtherCloud.send(cmd, 29);
|
||||
|
||||
|
||||
//send the ids to notice how to onion decryption and encryption
|
||||
cliOtherCloud.send( levels, dataNumber );
|
||||
|
||||
// if (dataNumber*4>512)
|
||||
// System.out.println("----512-----");
|
||||
/****************************************************
|
||||
* Send the data blocks to the shuffled cloud
|
||||
* We sends them directly here, in fact, we can permute them before sending them
|
||||
*********************************************/
|
||||
//send the slots data, the number is filled
|
||||
for (int _id=0;_id<evictSize;_id++)
|
||||
{
|
||||
SlotObject targetObj = (SlotObject)slot.poll();
|
||||
blockIDs[_id]=targetObj.id;
|
||||
subOram.encryptData(targetObj.value);
|
||||
cliOtherCloud.send( targetObj.value, CommInfo.blockSize );
|
||||
//System.out.println(" _id:"+_id+" value:"+targetObj.value[0]);
|
||||
}
|
||||
|
||||
for (int _id = evictSize; _id < 2*evictSize; _id++) {
|
||||
byte[] bDummyData = generateXORBlock(partition, _id, userKey);
|
||||
cliOtherCloud.send( bDummyData, CommInfo.blockSize );
|
||||
}
|
||||
|
||||
|
||||
/****************************
|
||||
* generate random value for dummy blocks
|
||||
* **************************************/
|
||||
//generate random value
|
||||
Random rnd=new Random();
|
||||
|
||||
int[] rnds=new int[rndLength];
|
||||
byte[] rndBytes=new byte[rndLength*4];
|
||||
for (int i=0; i<rndLength; i++)
|
||||
{
|
||||
rnds[i]= - rnd.nextInt( this.n_capacity ); //
|
||||
blockIDs[ i+2*evictSize ] = rnds[i];
|
||||
Util.intToByte(rndBytes, i*4, rnds[i]);
|
||||
}
|
||||
for (int _id=0;_id<dataNumber;_id++)
|
||||
{
|
||||
blockIDs[_id+2*evictSize+rndLength]=intIDs[_id];
|
||||
}
|
||||
|
||||
|
||||
cliOtherCloud.send(rndBytes, rndLength*4);
|
||||
|
||||
//send the onion keys
|
||||
/********************************************************************
|
||||
* Notice that: must send the unfilledlevel key to the server,
|
||||
* because the special case, the unfilled level is the top level, the onion decryption will be used
|
||||
****************************************************************/
|
||||
|
||||
Util.bandwidth += rndLength*4 + MCloudCommInfo.evictConditionSize*CommInfo.blockSize + (unfilledLevel-MCloudCommInfo.severBeginLevel+1)*CommInfo.keySize;
|
||||
|
||||
Util.writeNumber ++;
|
||||
|
||||
Util.cloudtocloud++;
|
||||
Util.cloudcloudbandwidth += (filledLevelLength) * CommInfo.blockSize + dataNumber*CommInfo.blockSize;
|
||||
|
||||
|
||||
|
||||
for (int i=MCloudCommInfo.severBeginLevel; i<=unfilledLevel; i++)
|
||||
{
|
||||
byte[] bkeyData = getKey(i);
|
||||
cliOtherCloud.send( bkeyData, CommInfo.keySize );
|
||||
}
|
||||
|
||||
//send the shuffle key and wait for the response
|
||||
/******************************
|
||||
* Here, the client can receive the shffule key
|
||||
* But, in our implmenetation, we generate the key in the client
|
||||
* it is also OK
|
||||
* ************************************
|
||||
*
|
||||
* The client must wait for the response of the cloud
|
||||
* and cloud should finish the shuffle operation
|
||||
*
|
||||
* Notice, we use the onion key as the shuffle key, it is also OK
|
||||
* *********************************/
|
||||
|
||||
//reset some status in the unfilled level
|
||||
keys[unfilledLevel]=kg.generateKey();
|
||||
nextDummy[unfilledLevel]=0;
|
||||
filled[unfilledLevel]=true;
|
||||
|
||||
byte[] shufflekey = getKey(unfilledLevel);//Util.generateDummyData(MCloudCommInfo.keySize);
|
||||
cliOtherCloud.sendAndReceive(shufflekey, 16);
|
||||
|
||||
//System.out.println("noticeshufule ok cloud: "+cloud+" session "+ bSessionID[0]+" dataNumber "+dataNumber+" filledLevelLength:"+filledLevelLength);
|
||||
|
||||
|
||||
/*********************** Second command: noticeWriteCloud ***************************/
|
||||
/////////////////////////First, command and keys
|
||||
byte[] cmd1=new byte[22];
|
||||
cmd1[0]=CommandType.noticeWriteCloud;
|
||||
System.arraycopy(bSessionID, 0, cmd1, 1, 8);
|
||||
Util.intToByte(cmd1, 9, partition);
|
||||
Util.intToByte(cmd1, 13, unfilledLevel);
|
||||
cmd1[17] = (byte) otherCloud;
|
||||
Util.intToByte(cmd1, 18, dataNumber);
|
||||
|
||||
cli.send(cmd1, 22, ids, dataNumber*4, null);
|
||||
|
||||
|
||||
/***************************
|
||||
* Final, reset the status in the client
|
||||
* (1) shuffle the blockIDs
|
||||
* (2) reset the filled and read flag
|
||||
* *******************************/
|
||||
psuedo_random_permute( shufflekey, filledLevelLength);
|
||||
|
||||
for (int i=MCloudCommInfo.severBeginLevel;i<unfilledLevel; i++)
|
||||
{
|
||||
nextDummy[i]=0;
|
||||
filled[i]=false;
|
||||
}
|
||||
//update the status in the un-filled level
|
||||
/******************
|
||||
* Save to a temp int array
|
||||
* For the worst case
|
||||
* ******************/
|
||||
int[] bIDS = new int[filledLevelLength];
|
||||
for (int i=0; i<filledLevelLength; i++)
|
||||
{
|
||||
bIDS[i]=blockIDs[i];
|
||||
}
|
||||
int levelBegin = (1 << (unfilledLevel + 1)) - 2;
|
||||
for (int i=0;i<filledLevelLength;i++)
|
||||
{
|
||||
int bID=bIDS[i];
|
||||
int _id = i+levelBegin;
|
||||
blockIDs[_id] = bID;
|
||||
readFlag[_id]=false;
|
||||
if (bID>=0)
|
||||
{
|
||||
//update the position map
|
||||
pos_map[bID].cloud = cloud;
|
||||
pos_map[bID].partition = this.partition;
|
||||
pos_map[bID].level = unfilledLevel;
|
||||
pos_map[bID].offset = i;
|
||||
}
|
||||
}
|
||||
/*for (int i=filledLevelLength-1;i>=0;i--)
|
||||
{
|
||||
int bID=blockIDs[i];
|
||||
int _id = i+levelBegin;
|
||||
if (bID>=0)
|
||||
{
|
||||
//update the position map
|
||||
pos_map[bID].cloud = cloud;
|
||||
pos_map[bID].partition = this.partition;
|
||||
pos_map[bID].level = unfilledLevel;
|
||||
pos_map[bID].offset = i;
|
||||
}
|
||||
blockIDs[_id] = bID;
|
||||
readFlag[_id]=false;
|
||||
}*/
|
||||
//update the status of consecutive levels
|
||||
for (int i=0; i<levelBegin; i++)
|
||||
{
|
||||
blockIDs[i] = CommInfo.dummyID;
|
||||
readFlag[i]=true;
|
||||
}
|
||||
//update all the real numbers
|
||||
realDataNumber=0;
|
||||
for (int i=levelBegin; i<this.n_capacity; i++)
|
||||
{
|
||||
if (blockIDs[i]>0)
|
||||
realDataNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void writeCase1(Queue slot, SecretKey userKey, int cloud,
|
||||
int evictSize, int unfilledLevel) {
|
||||
|
||||
|
||||
int filledLevelLength = 2 * (1 << unfilledLevel);
|
||||
|
||||
// System.out.println(" writeCase1 ");
|
||||
if (evictSize > filledLevelLength )
|
||||
System.out.println(" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ");
|
||||
// shuffle in client and then write to cloud rightly
|
||||
for (int _id = 0; _id < evictSize; _id++) {
|
||||
SlotObject targetObj = (SlotObject) slot.poll();
|
||||
blockIDs[_id] = targetObj.id;
|
||||
subOram.encryptData(targetObj.value);
|
||||
System.arraycopy(targetObj.value, 0, s_buffer[_id], 0,
|
||||
CommInfo.blockSize);
|
||||
// System.out.println(" _id:"+_id+" value:"+targetObj.value[0]);
|
||||
}
|
||||
for (int _id = evictSize; _id < filledLevelLength; _id++) {
|
||||
byte[] bDummyData = generateXORBlock(partition, _id, userKey);
|
||||
System.arraycopy(bDummyData, 0, s_buffer[_id], 0,
|
||||
CommInfo.blockSize);
|
||||
// System.out.println(" _id:"+_id+" value:"+bDummyData[0]);
|
||||
}
|
||||
// shuffle first and then send them to the clouds
|
||||
psuedo_random_permute(s_buffer, filledLevelLength);
|
||||
|
||||
keys[unfilledLevel] = kg.generateKey();
|
||||
nextDummy[unfilledLevel] = 0;
|
||||
filled[unfilledLevel] = true;
|
||||
|
||||
// onion encrypt them using the level key
|
||||
|
||||
int[] bIDS = new int[filledLevelLength];
|
||||
for (int i=0; i<filledLevelLength; i++)
|
||||
{
|
||||
bIDS[i]=blockIDs[i];
|
||||
}
|
||||
// reset the status
|
||||
int levelBegin = (1 << (unfilledLevel + 1)) - 2;
|
||||
for (int i = 0; i< filledLevelLength; i++ ) {
|
||||
int bID = bIDS[i];
|
||||
int _id = i + levelBegin;
|
||||
if (bID >= 0) {
|
||||
// update the position map
|
||||
pos_map[bID].cloud = cloud;
|
||||
pos_map[bID].partition = this.partition;
|
||||
pos_map[bID].level = unfilledLevel;
|
||||
pos_map[bID].offset = i;
|
||||
}
|
||||
blockIDs[_id] = bID;
|
||||
readFlag[_id] = false;
|
||||
}
|
||||
|
||||
// update the status of consecutive levels
|
||||
for (int i = 0; i < levelBegin; i++) {
|
||||
blockIDs[i] = CommInfo.dummyID;
|
||||
readFlag[i] = true;
|
||||
}
|
||||
|
||||
Util.writeNumber ++;
|
||||
Util.bandwidth += filledLevelLength*CommInfo.blockSize ;
|
||||
|
||||
//write to cloud
|
||||
byte[] cmd1=new byte[13];
|
||||
cmd1[0]=CommandType.directWriteCloud;
|
||||
Util.intToByte(cmd1, 1, partition);
|
||||
Util.intToByte(cmd1, 5, unfilledLevel);
|
||||
Util.intToByte(cmd1, 9, filledLevelLength);
|
||||
|
||||
cli.send(cmd1, 13);
|
||||
|
||||
|
||||
for (int _id = 0; _id < filledLevelLength; _id++) {
|
||||
cli.send( s_buffer[_id], CommInfo.blockSize );
|
||||
}
|
||||
//send over and receive
|
||||
cmd1[0]=0;
|
||||
cmd1[1]=0;
|
||||
cli.sendAndReceive(cmd1, 2);
|
||||
|
||||
//update all the real numbers
|
||||
realDataNumber=0;
|
||||
for (int i=levelBegin; i<this.n_capacity; i++)
|
||||
{
|
||||
if (blockIDs[i]>0)
|
||||
realDataNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void psuedo_random_permute(byte[][] sBuffer, int len) {
|
||||
Random rnd=new Random();
|
||||
int id =0;
|
||||
byte[] bData=new byte[CommInfo.blockSize];
|
||||
for (int i = len- 1; i > 0; --i) {
|
||||
int j = rnd.nextInt(i);
|
||||
|
||||
System.arraycopy(sBuffer[i], 0, bData, 0, CommInfo.blockSize);
|
||||
id=blockIDs[i];
|
||||
System.arraycopy(sBuffer[j], 0, sBuffer[i], 0, CommInfo.blockSize);
|
||||
blockIDs[i] =blockIDs[j];
|
||||
System.arraycopy(bData, 0, sBuffer[j], 0, CommInfo.blockSize);
|
||||
blockIDs[j]=id;
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Permute the blockIDs in the client based on the key
|
||||
* @param shufflekey
|
||||
*/
|
||||
private void psuedo_random_permute(byte[] shufflekey, int filledLevelLength) {
|
||||
Util.writeNumber = Util.writeNumber+1;
|
||||
|
||||
|
||||
// for (int i = 0; i < filledLevelLength; i++) {
|
||||
// System.out.println("i: "+i+" "+blockIDs[i]);
|
||||
// }
|
||||
|
||||
SecretKey sfk = new SecretKeySpec(shufflekey, "AES");
|
||||
|
||||
for (int i = 0; i < filledLevelLength; i++) {
|
||||
int j = Util.fpeForPermution(i, sfk, filledLevelLength);
|
||||
int t = blockIDs[i];
|
||||
blockIDs[i] = blockIDs[j];
|
||||
blockIDs[j] = t;
|
||||
|
||||
// System.out.println("permute: "+i+" "+j);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int nextDummy(int type, int level)
|
||||
{
|
||||
int begin = (1 << (level + 1)) - 2;
|
||||
int end=0;
|
||||
if (level != n_levels - 1) {
|
||||
end = 2 *(1 << level);
|
||||
} else end = top_level_len;
|
||||
//compute the position in the position map
|
||||
for (int i=nextDummy[level];i<end;i++)
|
||||
if (blockIDs[begin+i]<= CommInfo.dummyID)
|
||||
{
|
||||
nextDummy[level]=i+1;
|
||||
return i;
|
||||
}
|
||||
|
||||
//Notice that, there is no dummy blocks
|
||||
//System.out.println("No dummy !!!!!! return 0!!!!!p:"+this.partition+" !!!type:"+type+" level:"+level+" nextDummy[level]"+nextDummy[level]);
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
package nankai.oram.client.mCloud;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import nankai.oram.client.NewMCOSORAMClient;
|
||||
import nankai.oram.client.common.Position;
|
||||
import nankai.oram.client.common.SlotObject;
|
||||
import nankai.oram.client.partition.Partition;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.SocketClientUtil;
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.ResponseType;
|
||||
import nankai.oram.common.SymmetricCypto;
|
||||
import nankai.oram.common.Util;
|
||||
import nankai.oram.interfaces.MultiCloudORAM;
|
||||
import nankai.oram.interfaces.ORAM;
|
||||
|
||||
public class SubCloudNewORAM implements MultiCloudORAM {
|
||||
|
||||
int cloud;
|
||||
int n_partitions;
|
||||
int n_capacity;//the max capacity of a partition -- need the top level
|
||||
int n_levels;
|
||||
int n_realBlocks_p;//the real number of blocks in a partition
|
||||
int counter=0;//for sequneceEvict
|
||||
NewMCOSPartition[] partitions;
|
||||
Position pos_map[];//position map
|
||||
SocketClientUtil[] cli;
|
||||
|
||||
private SecretKey userKey; //First onion encryption Layer
|
||||
byte s_buffer[][];
|
||||
|
||||
public SubCloudNewORAM(int npartitions, int realBlocks_p, int levels, int capacity, int c, Position posMap[], SocketClientUtil[] cLi,byte sBuffer[][])
|
||||
{
|
||||
n_partitions=npartitions;
|
||||
n_realBlocks_p=realBlocks_p;
|
||||
n_levels=levels;
|
||||
n_capacity=capacity;
|
||||
cloud=c;
|
||||
pos_map=posMap;
|
||||
cli=cLi;
|
||||
partitions=new NewMCOSPartition[n_partitions];
|
||||
s_buffer=sBuffer;
|
||||
for (int i=0;i<n_partitions;i++)
|
||||
{
|
||||
partitions[i]=new NewMCOSPartition(realBlocks_p, levels, posMap, cLi[cloud], this,s_buffer);
|
||||
partitions[i].partition=i;
|
||||
}
|
||||
|
||||
KeyGenerator kg;
|
||||
try {
|
||||
kg = KeyGenerator.getInstance("AES");
|
||||
kg.init(128);
|
||||
userKey = kg.generateKey();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void encryptData(byte[] data) {
|
||||
// SymmetricCypto scp=new SymmetricCypto(CommInfo.keySize);
|
||||
// scp.initEnc(this.userKey, null);
|
||||
// scp.enc_decData(data, CommInfo.blockSize);
|
||||
}
|
||||
|
||||
public void decryptData(byte[] data) {
|
||||
// SymmetricCypto scp=new SymmetricCypto(CommInfo.keySize);
|
||||
// scp.initDec(this.userKey, null);
|
||||
// scp.enc_decData(data, CommInfo.blockSize);
|
||||
}
|
||||
|
||||
public boolean initORAM()
|
||||
{
|
||||
byte cmd[]=new byte[14];
|
||||
cmd[0]=CommandType.initORAM;
|
||||
Util.intToByte(cmd, 1, n_partitions);
|
||||
Util.intToByte(cmd, 5, n_capacity);
|
||||
Util.intToByte(cmd, 9, n_levels);
|
||||
cmd[13] = (byte) this.cloud;
|
||||
|
||||
cli[cloud].send( cmd, 14, null , 0, null);
|
||||
|
||||
return cli[cloud].responseType!=ResponseType.wrong;
|
||||
}
|
||||
|
||||
public boolean openORAM()
|
||||
{
|
||||
byte cmd[]=new byte[2];
|
||||
cmd[0]=CommandType.openDB;
|
||||
cmd[1]=(byte) this.cloud;
|
||||
|
||||
cli[cloud].send( cmd, 2, null , 0, null);
|
||||
|
||||
return cli[cloud].responseType!=ResponseType.wrong;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeCloud(Queue slot) {
|
||||
/*****************
|
||||
* Random select a partition
|
||||
*
|
||||
* Select another cloud to do the shuffle operation
|
||||
* *********************/
|
||||
|
||||
//System.out.println("writeCloud begin");
|
||||
Random rnd=new Random();
|
||||
int p = 1;//rnd.nextInt(n_partitions);
|
||||
if (Util.debug == false){
|
||||
p = rnd.nextInt(n_partitions);
|
||||
//not write to the partition with more than the pre-defined real blocks
|
||||
while ( partitions[p].realDataNumber >= (partitions[p].top_level_len - 2*MCloudCommInfo.evictConditionSize) )
|
||||
p = rnd.nextInt(n_partitions);
|
||||
}
|
||||
|
||||
//generate a random cloud to do the shuffle operation
|
||||
int otherCloud = rnd.nextInt(MCloudCommInfo.cloudNumber);
|
||||
if (MCloudCommInfo.cloudNumber > 1){
|
||||
while (otherCloud == this.cloud)
|
||||
otherCloud = rnd.nextInt(MCloudCommInfo.cloudNumber);
|
||||
}
|
||||
|
||||
|
||||
partitions[p].writePartition(slot, cli[cloud], otherCloud, cli[otherCloud], userKey, cloud);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public byte[] readCloud(String key) {
|
||||
return readCloud(Integer.parseInt(key));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public byte[] readCloud(int id) {
|
||||
/*****************
|
||||
* If it is a dummy Block, random select a partition to read
|
||||
* **********************/
|
||||
byte[] data = null;
|
||||
int p = 0;
|
||||
if (id<=CommInfo.dummyID)
|
||||
{
|
||||
Random rnd=new Random();
|
||||
p = rnd.nextInt(n_partitions);
|
||||
}else{
|
||||
p = pos_map[id].partition;
|
||||
}
|
||||
if (p>=0){
|
||||
data = partitions[p].readPartition(id, userKey);
|
||||
return data;
|
||||
}else{
|
||||
return new byte[CommInfo.blockSize];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,349 @@
|
|||
package nankai.oram.client.partition;
|
||||
|
||||
/*************
|
||||
* The data in a level of a partition is encrypted by the key for level
|
||||
*
|
||||
* Each data is included by BID+DATA
|
||||
* BID = REALBLOCK? BLOCKID : - OFFSET
|
||||
*/
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import nankai.oram.client.common.Position;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.SocketClientUtil;
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.SymmetricCypto;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class Partition{
|
||||
public static int part=0;
|
||||
int n_levels;
|
||||
|
||||
int n_blocks;
|
||||
int n_realBlocks_p;//the real number of blocks in a partition
|
||||
int n_capacity;//the max capacity of a partition -- need the top level
|
||||
int top_level_len;//the number of blocks in the top level
|
||||
|
||||
int p = 0;
|
||||
int blockIDs[];//all the blockIDs. When re-shuffle, the dummyIDs will be re-filled
|
||||
int dummyNumbers[];//the dummy block numbers; When re-shuffle, the dummyIDs will be filled
|
||||
int nextDummy[];//the dummy block counter;
|
||||
boolean filled[];//filled level flag
|
||||
boolean flag[];//read flag
|
||||
SecretKey keys[];//level key for each partition
|
||||
|
||||
|
||||
byte s_buffer[][];//shuffule buffer - a large memory
|
||||
Position pos_map[];//position map
|
||||
SocketClientUtil cli;
|
||||
|
||||
byte cmdData[] = new byte[13];
|
||||
|
||||
public int realDataNumber = 0;
|
||||
KeyGenerator kg;
|
||||
public Partition(int nN, int n_partitions, Position posMap[], byte sBuffer[][], SocketClientUtil cLi)
|
||||
{
|
||||
s_buffer=sBuffer;
|
||||
pos_map=posMap;
|
||||
cli=cLi;
|
||||
|
||||
n_realBlocks_p = (int) Math.ceil(((double) nN) / n_partitions);
|
||||
n_blocks = n_realBlocks_p * n_partitions;
|
||||
|
||||
n_levels = (int) (Math.log((double) n_realBlocks_p) / Math.log(2.0)) + 1;
|
||||
n_capacity = (int) Math.ceil(CommInfo.capacity_parameter * n_realBlocks_p);
|
||||
top_level_len = n_capacity - (1 << n_levels) + 2;
|
||||
|
||||
p = part++;
|
||||
flag=new boolean[n_capacity];
|
||||
keys=new SecretKey[n_levels];
|
||||
blockIDs=new int[n_capacity];
|
||||
nextDummy=new int[n_levels];
|
||||
dummyNumbers=new int[n_levels];
|
||||
filled=new boolean[n_levels];
|
||||
|
||||
for (int i=0;i<n_levels;i++)
|
||||
{
|
||||
dummyNumbers[i]=0;
|
||||
nextDummy[i]=0;
|
||||
filled[i]=false;
|
||||
}
|
||||
for (int i=0;i<n_capacity;i++)
|
||||
{
|
||||
flag[i]=true;
|
||||
blockIDs[i]=CommInfo.dummyID;
|
||||
}
|
||||
|
||||
initKeys();
|
||||
}
|
||||
|
||||
|
||||
private void initKeys()
|
||||
{
|
||||
try {
|
||||
kg = KeyGenerator.getInstance("AES");
|
||||
kg.init(128);
|
||||
for (int j = 0; j < n_levels; j++)
|
||||
keys[j] = kg.generateKey();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] readPartition(int block_id) {
|
||||
|
||||
|
||||
/*******************************
|
||||
* From Each filled level, to read a block
|
||||
* if it is in this level, read the only one real block
|
||||
* else, read a dummy block *
|
||||
* *****************************/
|
||||
int readNumber = 0;
|
||||
byte[] data = new byte[CommInfo.blockSize];
|
||||
int level=-1;
|
||||
if (block_id!=CommInfo.dummyID)
|
||||
level = pos_map[block_id].level;
|
||||
for (int i=0;i<n_levels;i++)
|
||||
{
|
||||
if (filled[i])
|
||||
{
|
||||
if (level==i && block_id!=CommInfo.dummyID)
|
||||
{
|
||||
readNumber++;
|
||||
// in this level, to read a real block. get the offset
|
||||
readBlock(p, i, pos_map[block_id].offset, data);
|
||||
/*****************************
|
||||
* Decrypt the data
|
||||
* *************************/
|
||||
SymmetricCypto scp=new SymmetricCypto(CommInfo.keySize);
|
||||
scp.initDec(keys[i], null);
|
||||
scp.enc_decData(data, CommInfo.blockSize);
|
||||
|
||||
}else{
|
||||
readNumber++;
|
||||
// not in this level, to read a dummy block, get the dummy offset
|
||||
|
||||
int dID=nextDummy(i);
|
||||
if (dID == -1) // There is no dummy block can be read
|
||||
continue;
|
||||
|
||||
readBlock(p, i, dID, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Util.readNumber ++;
|
||||
Util.readbandwidth += CommInfo.blockSize + readNumber*4;
|
||||
Util.cloudcloudbandwidth += readNumber * CommInfo.blockSize *1.2 + readNumber*4;
|
||||
Util.cloudtocloud ++;
|
||||
|
||||
return data ;
|
||||
}
|
||||
|
||||
public void writePartition(int block_id, byte[] bData)
|
||||
{
|
||||
|
||||
int level=-1;
|
||||
for (int i=0;i<this.n_levels;i++)
|
||||
{
|
||||
if (!filled[i])
|
||||
{
|
||||
level=i-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************
|
||||
* fetch all the unread blocks from the server
|
||||
* ***************************************/
|
||||
int realNumber=0;
|
||||
if (level != -1) {
|
||||
for (int i = 0; i <= level; i++) {
|
||||
realNumber = fetchLevel(i, realNumber);
|
||||
filled[i]=false;
|
||||
}
|
||||
Util.cloudtocloud = Util.cloudtocloud+1;
|
||||
}
|
||||
/******************************************
|
||||
* If block_id is dummy block
|
||||
* It will not be add into the shffule buffer
|
||||
* ***************************************/
|
||||
if (block_id!=CommInfo.dummyID)
|
||||
System.arraycopy(bData, 0, s_buffer[realNumber++], 0, CommInfo.blockSize);
|
||||
|
||||
/***********************
|
||||
* Treate the special level, i.e., the top level
|
||||
* ************************/
|
||||
if (level != n_levels - 1) ++level;
|
||||
else{
|
||||
System.out.println(" Filled!!!¡¡¡¡¡¡¡¡");
|
||||
}
|
||||
/******************************************
|
||||
* Generate the dummy blocks and add them into the buffer
|
||||
* ***************************************/
|
||||
int begin = (1 << (level + 1)) - 2;
|
||||
int sbuffer_len=0;
|
||||
if (level != n_levels - 1) {
|
||||
sbuffer_len = 2 *(1 << level);
|
||||
} else sbuffer_len = top_level_len;
|
||||
|
||||
for (int i=realNumber;i<sbuffer_len;i++)
|
||||
{
|
||||
//generate the data
|
||||
Util.intToByte(s_buffer[i], 0, CommInfo.dummyID);
|
||||
byte[] bDummy=Util.generateDummyData(CommInfo.blockSize-4);
|
||||
System.arraycopy(bDummy, 0, s_buffer[i], 4, CommInfo.blockSize-4);
|
||||
}
|
||||
/******************************************
|
||||
* Shuffle the plian data in the shufflebuffer
|
||||
* Then encrypt Them using the level key
|
||||
* ***************************************/
|
||||
psuedo_random_permute(s_buffer, sbuffer_len);
|
||||
//Reset the key and dummyID
|
||||
keys[level]=kg.generateKey();
|
||||
nextDummy[level]=0;
|
||||
/******************************************
|
||||
* re-encrypt all the data
|
||||
* ***************************************/
|
||||
int bID=0;
|
||||
|
||||
SymmetricCypto scp=new SymmetricCypto(CommInfo.keySize);
|
||||
scp.initEnc(keys[level], null);
|
||||
filled[level]=true;
|
||||
|
||||
for (int i=0;i<sbuffer_len;i++)
|
||||
{
|
||||
//set the flag and blockIDs
|
||||
bID=Util.byteToInt(s_buffer[i], 0, 4);
|
||||
int _id = begin+i;
|
||||
if (bID==CommInfo.dummyID)
|
||||
bID=CommInfo.dummyID-i;
|
||||
else{
|
||||
//update position map
|
||||
pos_map[bID].partition=p;
|
||||
pos_map[bID].level=level;
|
||||
pos_map[bID].offset=i;
|
||||
}
|
||||
blockIDs[_id]=bID;
|
||||
Util.intToByte(s_buffer[i], 0, bID);
|
||||
flag[_id]=false;
|
||||
|
||||
//encrypt
|
||||
scp.enc_decData(s_buffer[i], CommInfo.blockSize);
|
||||
//partition + ID (_id)
|
||||
cmdData[0]=CommandType.writeBlock;
|
||||
Util.intToByte(cmdData, 1, p);
|
||||
Util.intToByte(cmdData, 5, _id);
|
||||
Util.intToByte(cmdData, 9, CommInfo.blockSize);
|
||||
//store into the database
|
||||
cli.send(cmdData, 13, s_buffer[i], CommInfo.blockSize, null);
|
||||
}
|
||||
for (int i=0;i<begin;i++)
|
||||
{
|
||||
blockIDs[i]=CommInfo.dummyID;
|
||||
flag[i]=true;
|
||||
}
|
||||
realDataNumber=0;
|
||||
for (int i=begin;i<this.n_capacity;i++)
|
||||
{
|
||||
if (blockIDs[i]>=0)
|
||||
realDataNumber++;
|
||||
}
|
||||
|
||||
Util.cloudcloudbandwidth += sbuffer_len*CommInfo.blockSize;
|
||||
|
||||
Util.writeNumber ++;
|
||||
Util.bandwidth += CommInfo.blockSize + sbuffer_len*4;
|
||||
Util.cloudtocloud ++;
|
||||
}
|
||||
|
||||
private void psuedo_random_permute(byte[][] sBuffer, int len) {
|
||||
Util.writeNumber = Util.writeNumber+1;
|
||||
|
||||
Random rnd=new Random();
|
||||
byte[] bData=new byte[CommInfo.blockSize];
|
||||
for (int i = len- 1; i > 0; --i) {
|
||||
int j = rnd.nextInt(i);
|
||||
/* bData=sBuffer[i].clone();
|
||||
sBuffer[i] = sBuffer[j].clone();
|
||||
sBuffer[j] = bData.clone();*/
|
||||
System.arraycopy(sBuffer[i], 0, bData, 0, CommInfo.blockSize);
|
||||
System.arraycopy(sBuffer[j], 0, sBuffer[i], 0, CommInfo.blockSize);
|
||||
System.arraycopy(bData, 0, sBuffer[j], 0, CommInfo.blockSize);
|
||||
}
|
||||
}
|
||||
|
||||
private int fetchLevel(int level, int length) {
|
||||
/******************************
|
||||
* Compute the position of begin and end
|
||||
* **********************************/
|
||||
SymmetricCypto scp=new SymmetricCypto(CommInfo.keySize);
|
||||
scp.initDec(keys[level], null);
|
||||
|
||||
int begin = (1 << (level + 1)) - 2;
|
||||
int level_len=0;
|
||||
if (level != n_levels - 1) {
|
||||
level_len = 2 *(1 << level);
|
||||
} else level_len = top_level_len;
|
||||
|
||||
int _id=0;
|
||||
|
||||
for (int j=0; j<level_len; j++)
|
||||
{
|
||||
_id=begin+j;
|
||||
if (!flag[_id] && blockIDs[_id]>=0)
|
||||
{
|
||||
readBlock(p, level, j, s_buffer[length]);
|
||||
/**************************
|
||||
* Decrypt it and judge whether it is a dummy block
|
||||
* *************************/
|
||||
scp.enc_decData(s_buffer[length], CommInfo.blockSize);
|
||||
length++;
|
||||
}
|
||||
|
||||
//reset the flag
|
||||
flag[_id]=true;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
private void readBlock(int p, int level, int offset, byte[] recData) {
|
||||
int begin = (1 << (level + 1)) - 2;
|
||||
int _id = begin+offset;
|
||||
cmdData[0]=CommandType.readBlock;
|
||||
Util.intToByte(cmdData, 1, p);
|
||||
|
||||
//reset the read flag as true
|
||||
flag[_id]=true;
|
||||
Util.intToByte(cmdData, 5, _id);
|
||||
|
||||
cli.send(cmdData, 9, null, 0, recData);
|
||||
|
||||
}
|
||||
|
||||
public int nextDummy(int level)
|
||||
{
|
||||
int begin = (1 << (level + 1)) - 2;
|
||||
int end=0;
|
||||
if (level != n_levels - 1) {
|
||||
end = 2 *(1 << level);
|
||||
} else end = top_level_len;
|
||||
//compute the position in the position map
|
||||
for (int i=nextDummy[level];i<end;i++)
|
||||
if (blockIDs[begin+i] <= CommInfo.dummyID)
|
||||
{
|
||||
nextDummy[level]=i+1;
|
||||
return i;
|
||||
}
|
||||
|
||||
//Notice that, there is no dummy blocks
|
||||
//System.out.println("No dummy !!!!!! return 0!!!!!!!!");
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package nankai.oram.common;
|
||||
|
||||
public interface CommInfo {
|
||||
|
||||
public static int dummyID=-1;
|
||||
public static int keySize=16;//the length of a key byte
|
||||
public static int v=2;//the rate of evict operation
|
||||
public static int blockSize=128;//the length of a block byte
|
||||
public static double capacity_parameter=4.6;//4.6*N, the parameter of max capacity of partition
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package nankai.oram.common;
|
||||
|
||||
public interface CommandType {
|
||||
|
||||
public static byte initORAM=1;
|
||||
public static byte readBlock=2;
|
||||
public static byte writeBlock=3;
|
||||
public static byte readCloud=4;
|
||||
public static byte noticeWriteCloud=5; //client notices the cloud to be ready for the write operation
|
||||
public static byte noticeShuffle=6; //client notices the cloud to be read for the shuffle operation
|
||||
public static byte shuffleData=7; //cloud sends the shuffle data to the other cloud
|
||||
public static byte backData=8;//the other cloud sends back the shuffled data
|
||||
public static byte directWriteCloud=9; //client write to cloud the unfilled level directly
|
||||
|
||||
|
||||
|
||||
|
||||
public static byte testTime=112;//the other cloud sends back the shuffled data
|
||||
public static byte closeThread=111;
|
||||
|
||||
|
||||
public static byte openDB=113;//the other cloud sends back the shuffled data
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package nankai.oram.common;
|
||||
|
||||
import com.mongodb.*;
|
||||
import com.mongodb.client.*;
|
||||
|
||||
public class MongDBUtil {
|
||||
MongoClient conn;
|
||||
MongoDatabase db;
|
||||
|
||||
public void connect(String ip, int port, String dbName)
|
||||
{
|
||||
conn = new MongoClient(ip, port);
|
||||
db = conn.getDatabase(dbName);
|
||||
}
|
||||
public void connect(String ip, int port )
|
||||
{
|
||||
conn = new MongoClient(ip, port);
|
||||
}
|
||||
public boolean createDB(String dbName)
|
||||
{
|
||||
if (conn==null)
|
||||
{
|
||||
System.out.println("no connection");
|
||||
return false;
|
||||
}
|
||||
System.out.println("createDB "+dbName);
|
||||
//first, drop it if exists
|
||||
conn.dropDatabase(dbName);
|
||||
//then, create
|
||||
db = conn.getDatabase(dbName);
|
||||
return true;
|
||||
}
|
||||
public boolean openDB(String dbName)
|
||||
{
|
||||
if (conn==null)
|
||||
{
|
||||
System.out.println("no connection");
|
||||
return false;
|
||||
}
|
||||
System.out.println("openDB "+dbName);
|
||||
db = conn.getDatabase(dbName);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* create table / collection
|
||||
* use the default index '__id' as the unique index
|
||||
* @param collectioName
|
||||
* @return
|
||||
*/
|
||||
public boolean createCollection(String collectioName)
|
||||
{
|
||||
if (db==null)
|
||||
{
|
||||
System.out.println("no db");
|
||||
return false;
|
||||
}
|
||||
db.createCollection(collectioName);
|
||||
return true;
|
||||
}
|
||||
|
||||
public MongoCollection getCollection(String collectioName)
|
||||
{
|
||||
return db.getCollection(collectioName);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package nankai.oram.common;
|
||||
|
||||
public interface ResponseType {
|
||||
|
||||
public static int wrong=0;
|
||||
public static int normal=1; //without value
|
||||
public static int normalWithValue=2; //right run and some returned value + LEN +DATA
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
package nankai.oram.common;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.Socket;
|
||||
|
||||
public class SocketClientUtil {
|
||||
String ip;
|
||||
int port;
|
||||
|
||||
Socket socket;
|
||||
DataInputStream in;
|
||||
DataOutputStream out;
|
||||
|
||||
byte recvMsg[];
|
||||
byte sendMsg[];
|
||||
|
||||
public static int responseType;//the returned value from the cloud server
|
||||
|
||||
public SocketClientUtil(String ip, int port) {
|
||||
this.ip = ip;
|
||||
this.port = port;
|
||||
recvMsg=new byte[1024];//1k
|
||||
sendMsg=new byte[4];//100k
|
||||
responseType=0;
|
||||
}
|
||||
|
||||
|
||||
public boolean connect() {
|
||||
try {
|
||||
// 向本机的2121端口发出客户请求
|
||||
socket = new Socket(ip, port);
|
||||
// System.out.println("Established a connection...");
|
||||
|
||||
socket.setKeepAlive(true);
|
||||
out = new DataOutputStream(socket.getOutputStream());
|
||||
in = new DataInputStream(socket.getInputStream());
|
||||
// 由Socket对象得到输出流,并构造PrintWriter对象
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error connect. " + e);
|
||||
return false;
|
||||
}
|
||||
// System.out.println("success for connection. " );
|
||||
return true;
|
||||
}
|
||||
|
||||
public void disConnect() {
|
||||
try {
|
||||
out.write(CommandType.closeThread);
|
||||
out.flush();
|
||||
out.close(); // 关闭Socket输出流
|
||||
in.close(); // 关闭Socket输入流
|
||||
socket.close(); // 关闭Socket
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error. " + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type request command type
|
||||
* @param cmdInfo some information for specific command
|
||||
* @param cmdLen the length of the cmdInfo
|
||||
* @param sendData the data which contains the concrete command information
|
||||
* @param dataLen the data length
|
||||
* @param receiveData TODO
|
||||
* @param retValue the returned data
|
||||
* @return
|
||||
*/
|
||||
public void send(byte[] cmdInfo, int cmdLen, byte[] sendData, int dataLen, byte[] receiveData) {
|
||||
try {
|
||||
/************************
|
||||
* Send
|
||||
* (1) the request - command
|
||||
* CommandType | len | data
|
||||
* And (2) the message content
|
||||
* *************************/
|
||||
|
||||
out.write(cmdInfo, 0, cmdLen);
|
||||
out.flush();
|
||||
if (dataLen > 0) {
|
||||
// out.write(sendData, 0, dataLen);
|
||||
// out.flush();
|
||||
|
||||
if (dataLen<512)
|
||||
{
|
||||
out.write(sendData, 0, dataLen);
|
||||
out.flush();
|
||||
}else{
|
||||
int num = dataLen / 512 ;
|
||||
int leftLen = dataLen % 512;
|
||||
int hasSend = 0;
|
||||
for (int i=0;i<num;i++)
|
||||
{
|
||||
out.write(sendData, hasSend, 512);
|
||||
out.flush();
|
||||
hasSend += 512;
|
||||
}
|
||||
if (leftLen>0){
|
||||
out.write(sendData, hasSend, leftLen);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
/*********************
|
||||
* Send them with different block
|
||||
* *********************/
|
||||
}
|
||||
|
||||
/*************************
|
||||
* Receive the response
|
||||
* ResponseType | len | data
|
||||
* *********************/
|
||||
while (in.read(recvMsg, 0, 1024) > 0) {
|
||||
break;
|
||||
}
|
||||
responseType=recvMsg[0];
|
||||
//System.out.println("server return:" + responseType);
|
||||
if (responseType==ResponseType.wrong){
|
||||
System.out.println(cmdInfo[0]+" "+cmdLen+" "+dataLen+"........");
|
||||
|
||||
for (int i=0;i<cmdLen;i++)
|
||||
System.out.print(cmdInfo[i]+" ");
|
||||
System.out.println();
|
||||
|
||||
for (int i=0;i<3;i++)
|
||||
System.out.print(sendData[i]+" ");
|
||||
System.out.println();
|
||||
|
||||
|
||||
System.out.println("Return error value!");
|
||||
}else{
|
||||
//System.out.println("server return success:" + responseType);
|
||||
if (responseType == ResponseType.normalWithValue)
|
||||
{
|
||||
int retLen=0;
|
||||
while ( (retLen = in.read(recvMsg, 0, 1024)) > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (retLen != CommInfo.blockSize)
|
||||
System.out.println("Wrong length" );
|
||||
|
||||
if (receiveData!=null && retLen == CommInfo.blockSize)
|
||||
System.arraycopy(recvMsg, 0, receiveData, 0, retLen);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void send(byte[] sendData, int dataLen) {
|
||||
try {
|
||||
// out.write(sendData, 0, dataLen);
|
||||
// out.flush();
|
||||
if (dataLen<512)
|
||||
{
|
||||
out.write(sendData, 0, dataLen);
|
||||
out.flush();
|
||||
}else{
|
||||
int length = dataLen / 512;
|
||||
int leftLen = dataLen % 512;
|
||||
int pos = 0;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
out.write(sendData, pos, 512);
|
||||
out.flush();
|
||||
pos += 512;
|
||||
}
|
||||
if (leftLen > 0) {
|
||||
out.write(sendData, pos, leftLen);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int receiving(byte[] recvData, int len) {
|
||||
int retLen = -1;
|
||||
try {
|
||||
retLen = in.read(recvData, 0, len) ;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return retLen;
|
||||
}
|
||||
|
||||
|
||||
public void sendAndReceive(byte[] cmdInfo, int cmdLen) {
|
||||
try {
|
||||
|
||||
out.write(cmdInfo, 0, cmdLen);
|
||||
out.flush();
|
||||
|
||||
/*************************
|
||||
* Receive the response
|
||||
* ResponseType | len | data
|
||||
* *********************/
|
||||
while (in.read(recvMsg, 0, 1024) > 0) {
|
||||
break;
|
||||
}
|
||||
responseType=recvMsg[0];
|
||||
//System.out.println("server return:" + responseType);
|
||||
if (responseType==ResponseType.wrong){
|
||||
System.out.println(cmdInfo[0]+" "+cmdLen+"........");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package nankai.oram.common;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
public class SymmetricCypto {
|
||||
Cipher cp;
|
||||
int keySize;
|
||||
static final String CIPHER_ALGORITHM_CBC_NoPadding = "AES/CBC/NoPadding";
|
||||
|
||||
byte[] iv;
|
||||
public SymmetricCypto(int keysize)
|
||||
{
|
||||
try {
|
||||
cp=Cipher.getInstance(CIPHER_ALGORITHM_CBC_NoPadding);
|
||||
keySize=keysize;
|
||||
iv=new byte[16];
|
||||
for (int i=0;i<16;i++)
|
||||
iv[i]=0;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void initEnc(SecretKey sk, byte[] IV) {
|
||||
try {
|
||||
cp.init(Cipher.ENCRYPT_MODE, sk, new IvParameterSpec( (IV==null)?iv:IV ));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public void initDec(SecretKey sk, byte[] IV)
|
||||
{
|
||||
try {
|
||||
cp.init(Cipher.DECRYPT_MODE, sk, new IvParameterSpec( (IV==null)?iv:IV ));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void enc_decData(byte[] bData, int len)
|
||||
{
|
||||
int blockNumber = len/keySize;
|
||||
for (int i=0;i<blockNumber;i++)
|
||||
{
|
||||
try {
|
||||
cp.doFinal(bData, i*keySize, keySize, bData, i*keySize);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package nankai.oram.common;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
|
||||
|
||||
public class Util {
|
||||
|
||||
public static boolean debug = false;
|
||||
public static int writeNumber = 0; //
|
||||
public static int cloudtocloud = 0; //
|
||||
public static long bandwidth = 0; //
|
||||
public static long cloudcloudbandwidth = 0; //
|
||||
public static long readbandwidth = 0; //
|
||||
public static int readNumber = 0; //
|
||||
|
||||
public static int byteToInt(byte[] src, int pos, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
for(int i =0; i< len; i++){
|
||||
ret += (src[pos+i]&0xff) << (24-8*i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void intToByte(byte[] dest, int pos, int value) {
|
||||
dest[pos+3] = (byte) (value & 0xff);
|
||||
dest[pos+2] = (byte) (value >> 8 & 0xff);
|
||||
dest[pos+1] = (byte) (value >> 16 & 0xff);
|
||||
dest[pos+0] = (byte) (value >> 24 & 0xff);
|
||||
}
|
||||
|
||||
public static int rand_int(int maxNum)
|
||||
{
|
||||
Random rnd=new Random();
|
||||
if (maxNum<=0) maxNum=1;
|
||||
return Math.abs(rnd.nextInt(maxNum));
|
||||
}
|
||||
|
||||
public static byte[] generateDummyData( int len)
|
||||
{
|
||||
byte[] bData=new byte[len];
|
||||
// Random rnd=new Random();
|
||||
// rnd.nextBytes(bData);
|
||||
for (int i=0;i<len;i++)
|
||||
bData[i]=-1;
|
||||
return bData;
|
||||
}
|
||||
|
||||
public static byte[] generateSessionData( int len)
|
||||
{
|
||||
byte[] bData=new byte[len];
|
||||
Random rnd=new Random();
|
||||
rnd.nextBytes(bData);
|
||||
return bData;
|
||||
}
|
||||
|
||||
public static byte[] generateIV(int dummyID) {
|
||||
byte[] iv=new byte[16];
|
||||
Util.intToByte(iv, 0, dummyID);
|
||||
for (int i=4;i<16;i++)
|
||||
{
|
||||
iv[i] = 0;
|
||||
}
|
||||
return iv;
|
||||
}
|
||||
|
||||
public static int fpeForPermution(int inData, SecretKey sfk, int modular)
|
||||
{
|
||||
SymmetricCypto scp =new SymmetricCypto(CommInfo.keySize);
|
||||
scp.initEnc(sfk, null);
|
||||
byte[] bData = new byte[CommInfo.keySize];
|
||||
for (int j=0; j<CommInfo.keySize; j++)
|
||||
bData[j]=(byte) inData;
|
||||
scp.enc_decData(bData, CommInfo.keySize);
|
||||
int ret = Math.abs( Util.byteToInt(bData, 0, 4) );
|
||||
return ret % modular;
|
||||
}
|
||||
|
||||
// public static byte[] hexStringToByte(String hex) {
|
||||
// int len = (hex.length() / 2);
|
||||
// byte[] result = new byte[len];
|
||||
// char[] achar = hex.toCharArray();
|
||||
// for (int i = 0; i < len; i++) {
|
||||
// int pos = i * 2;
|
||||
// result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// private static byte toByte(char c) {
|
||||
// byte b = (byte) "0123456789ABCDEF".indexOf(c);
|
||||
// return b;
|
||||
// }
|
||||
//
|
||||
// /** *//**
|
||||
// * 把字节数组转换成16进制字符串
|
||||
// * @param bArray
|
||||
// * @return
|
||||
// */
|
||||
// public static final String bytesToHexString(byte[] bArray) {
|
||||
// StringBuffer sb = new StringBuffer(bArray.length);
|
||||
// String sTemp;
|
||||
// for (int i = 0; i < bArray.length; i++) {
|
||||
// sTemp = Integer.toHexString(0xFF & bArray[i]);
|
||||
// if (sTemp.length() < 2)
|
||||
// sb.append(0);
|
||||
// sb.append(sTemp.toUpperCase());
|
||||
// }
|
||||
// return sb.toString();
|
||||
// }
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package nankai.oram.interfaces;
|
||||
|
||||
import java.util.Queue;
|
||||
|
||||
import nankai.oram.client.common.SlotObject;
|
||||
|
||||
public interface MultiCloudORAM {
|
||||
|
||||
public byte[] readCloud(String key);
|
||||
|
||||
public void writeCloud(Queue slot);
|
||||
public byte[] readCloud(int key);
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package nankai.oram.interfaces;
|
||||
|
||||
public interface ORAM {
|
||||
|
||||
public void write(String idStr, byte[] value);
|
||||
public byte[] read(String idStr);
|
||||
public void write(int id, byte[] value);
|
||||
public byte[] read(int id);
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package nankai.oram.server;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
import nankai.oram.server.mcloud.MCloudPartitionServerThread;
|
||||
import nankai.oram.server.mcloud.NewMCloudPartitionServerThread;
|
||||
|
||||
public class MCloudServer {
|
||||
private int queueSize = 100;
|
||||
private static int port = 2121;
|
||||
public MCloudServer() {
|
||||
try {
|
||||
boolean listening = true; // 是否对客户端进行监听
|
||||
ServerSocket serverSocket = null; // 服务器端Socket对象
|
||||
try {
|
||||
// 创建一个ServerSocket在端口2121监听客户请求
|
||||
serverSocket = new ServerSocket();
|
||||
|
||||
//关闭serverSocket时,立即释放serverSocket绑定端口以便端口重用,默认为false
|
||||
serverSocket.setReuseAddress(false);
|
||||
//accept等待连接超时时间为1000毫秒,默认为0,永不超时
|
||||
//serverSocket.setSoTimeout(10000);
|
||||
//为所有accept方法返回的socket对象设置接收缓存区大小,单位为字节,默认值和操作系统有关
|
||||
serverSocket.setReceiveBufferSize(128*1024);
|
||||
//设置性能参数,可设置任意整数,数值越大,相应的参数重要性越高(连接时间,延迟,带宽)
|
||||
serverSocket.setPerformancePreferences(3, 2, 1);
|
||||
//服务端绑定至端口,10为服务端连接请求队列长度
|
||||
serverSocket.bind(new InetSocketAddress(port), queueSize);
|
||||
System.out.println("Server starts..." + port);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Can not listen to. " + e);
|
||||
}
|
||||
|
||||
while (listening) {
|
||||
// 监听到客户请求,根据得到的Socket对象和客户计数创建服务线程,并启动之
|
||||
//new ServerThread(server.accept()).start();
|
||||
new MCloudPartitionServerThread(serverSocket.accept()).start();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error.... " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
/**
|
||||
* To run in a computer to simulate the multiple servers, we use the parameters of main to tell the socket bind port
|
||||
*/
|
||||
if (args.length>0){
|
||||
//the pos is cloud - 1
|
||||
int cloud = Integer.parseInt(args[0]);
|
||||
MCloudServer.port=MCloudCommInfo.port[cloud-1];
|
||||
System.out.println("cloud "+cloud+" port:"+MCloudServer.port);
|
||||
}
|
||||
new MCloudServer();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package nankai.oram.server;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
import nankai.oram.server.mcloud.NewMCloudPartitionServerThread;
|
||||
import nankai.oram.server.partition.PartitionServerThread;
|
||||
|
||||
public class NewMCloudServer {
|
||||
private int queueSize = 100;
|
||||
private static int port = 2121;
|
||||
public NewMCloudServer() {
|
||||
try {
|
||||
boolean listening = true; // 是否对客户端进行监听
|
||||
ServerSocket serverSocket = null; // 服务器端Socket对象
|
||||
try {
|
||||
// 创建一个ServerSocket在端口2121监听客户请求
|
||||
serverSocket = new ServerSocket();
|
||||
|
||||
//关闭serverSocket时,立即释放serverSocket绑定端口以便端口重用,默认为false
|
||||
serverSocket.setReuseAddress(true);
|
||||
//accept等待连接超时时间为1000毫秒,默认为0,永不超时
|
||||
//serverSocket.setSoTimeout(10000);
|
||||
//为所有accept方法返回的socket对象设置接收缓存区大小,单位为字节,默认值和操作系统有关
|
||||
serverSocket.setReceiveBufferSize(128*1024);
|
||||
//设置性能参数,可设置任意整数,数值越大,相应的参数重要性越高(连接时间,延迟,带宽)
|
||||
serverSocket.setPerformancePreferences(3, 2, 1);
|
||||
//服务端绑定至端口,10为服务端连接请求队列长度
|
||||
serverSocket.bind(new InetSocketAddress(port), queueSize);
|
||||
System.out.println("Server starts..." + port);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Can not listen to. " + e);
|
||||
}
|
||||
|
||||
while (listening) {
|
||||
// 监听到客户请求,根据得到的Socket对象和客户计数创建服务线程,并启动之
|
||||
//new ServerThread(server.accept()).start();
|
||||
new NewMCloudPartitionServerThread(serverSocket.accept()).start();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error.... " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
/**
|
||||
* To run in a computer to simulate the multiple servers, we use the parameters of main to tell the socket bind port
|
||||
*/
|
||||
if (args.length>0){
|
||||
//the pos is cloud - 1
|
||||
int cloud = Integer.parseInt(args[0]);
|
||||
NewMCloudServer.port=MCloudCommInfo.port[cloud-1];
|
||||
System.out.println("cloud "+cloud+" port:"+NewMCloudServer.port);
|
||||
}
|
||||
new NewMCloudServer();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package nankai.oram.server;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import nankai.oram.server.partition.PartitionServerThread;
|
||||
|
||||
public class ORAMServer {
|
||||
|
||||
private int queueSize = 10;
|
||||
private int port = 2121;
|
||||
public ORAMServer() {
|
||||
try {
|
||||
boolean listening = true; // 是否对客户端进行监听
|
||||
ServerSocket serverSocket = null; // 服务器端Socket对象
|
||||
try {
|
||||
// 创建一个ServerSocket在端口2121监听客户请求
|
||||
serverSocket = new ServerSocket();
|
||||
|
||||
//关闭serverSocket时,立即释放serverSocket绑定端口以便端口重用,默认为false
|
||||
serverSocket.setReuseAddress(true);
|
||||
//accept等待连接超时时间为1000毫秒,默认为0,永不超时
|
||||
//serverSocket.setSoTimeout(10000);
|
||||
//为所有accept方法返回的socket对象设置接收缓存区大小,单位为字节,默认值和操作系统有关
|
||||
serverSocket.setReceiveBufferSize(128*1024);
|
||||
//设置性能参数,可设置任意整数,数值越大,相应的参数重要性越高(连接时间,延迟,带宽)
|
||||
serverSocket.setPerformancePreferences(3, 2, 1);
|
||||
//服务端绑定至端口,10为服务端连接请求队列长度
|
||||
serverSocket.bind(new InetSocketAddress(port), queueSize);
|
||||
System.out.println("Server starts...");
|
||||
} catch (Exception e) {
|
||||
System.out.println("Can not listen to. " + e);
|
||||
}
|
||||
|
||||
while (listening) {
|
||||
// 监听到客户请求,根据得到的Socket对象和客户计数创建服务线程,并启动之
|
||||
//new ServerThread(server.accept()).start();
|
||||
new PartitionServerThread(serverSocket.accept()).start();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error.... " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// TODO 自动生成的方法存根
|
||||
new ORAMServer();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package nankai.oram.server;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.ResponseType;
|
||||
import nankai.oram.common.SymmetricCypto;
|
||||
import nankai.oram.server.partition.PartitionORAMServer;
|
||||
|
||||
public class ServerThread extends Thread {
|
||||
|
||||
Socket socket = null; // 保存与本线程相关的Socket对象
|
||||
byte recvCmd[];
|
||||
|
||||
public ServerThread(Socket socket) {
|
||||
this.socket = socket;
|
||||
recvCmd=new byte[1024];
|
||||
}
|
||||
|
||||
public void run() {
|
||||
DataInputStream in=null;
|
||||
DataOutputStream out=null;
|
||||
try {
|
||||
|
||||
in=new DataInputStream(socket.getInputStream());
|
||||
out=new DataOutputStream(socket.getOutputStream());
|
||||
|
||||
// 由Socket对象得到输出流,并构造PrintWriter对象
|
||||
byte type=0;
|
||||
int len=0;
|
||||
|
||||
while (true) {
|
||||
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
if ( (len = in.read(recvCmd, 0, 1024))>0)
|
||||
;//System.out.println("received"+len);
|
||||
}
|
||||
//System.out.println("over"+len);
|
||||
break;
|
||||
// type = 0;
|
||||
// len = 0;
|
||||
// while ((len = in.read(recvCmd, 0, 13)) > 0) {
|
||||
// type = recvCmd[0];
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// if (type == CommandType.testTime) {
|
||||
// System.out.println("return - ");
|
||||
// out.writeByte(ResponseType.normal);
|
||||
// out.flush();
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error.?>>>>> " + e);
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
try {
|
||||
out.close(); // 关闭Socket输出流
|
||||
in.close();// 关闭Socket输入流
|
||||
socket.close(); // 关闭Socket
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
System.out.println("closing........ ");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package nankai.oram.server;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import nankai.oram.server.partition.PartitionServerThread;
|
||||
|
||||
public class SocketServer {
|
||||
|
||||
private int queueSize = 10;
|
||||
private int port = 2121;
|
||||
public SocketServer() {
|
||||
try {
|
||||
boolean listening = true; // 是否对客户端进行监听
|
||||
ServerSocket serverSocket = null; // 服务器端Socket对象
|
||||
try {
|
||||
// 创建一个ServerSocket在端口2121监听客户请求
|
||||
serverSocket = new ServerSocket();
|
||||
|
||||
//关闭serverSocket时,立即释放serverSocket绑定端口以便端口重用,默认为false
|
||||
serverSocket.setReuseAddress(true);
|
||||
//accept等待连接超时时间为1000毫秒,默认为0,永不超时
|
||||
//serverSocket.setSoTimeout(10000);
|
||||
//为所有accept方法返回的socket对象设置接收缓存区大小,单位为字节,默认值和操作系统有关
|
||||
serverSocket.setReceiveBufferSize(128*1024);
|
||||
//设置性能参数,可设置任意整数,数值越大,相应的参数重要性越高(连接时间,延迟,带宽)
|
||||
serverSocket.setPerformancePreferences(3, 2, 1);
|
||||
//服务端绑定至端口,10为服务端连接请求队列长度
|
||||
serverSocket.bind(new InetSocketAddress(port), queueSize);
|
||||
System.out.println("Server starts..."+serverSocket.getInetAddress());
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Can not listen to. " + e);
|
||||
}
|
||||
|
||||
while (listening) {
|
||||
// 监听到客户请求,根据得到的Socket对象和客户计数创建服务线程,并启动之
|
||||
//new ServerThread(server.accept()).start();
|
||||
new ServerThread(serverSocket.accept()).start();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error.... " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// TODO 自动生成的方法存根
|
||||
new SocketServer();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
package nankai.oram.server.mcloud;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.MongDBUtil;
|
||||
import nankai.oram.server.partition.PartitionORAMServer;
|
||||
|
||||
import org.bson.Document;
|
||||
|
||||
import com.mongodb.client.FindIterable;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoCursor;
|
||||
|
||||
public class MCloudORAMserver {
|
||||
public static MCloudORAMserver instance;
|
||||
byte cloud;
|
||||
boolean initFlag;
|
||||
int N;
|
||||
int n_levels;
|
||||
int n_partitions;
|
||||
int n_blocks;
|
||||
int n_realBlocks_p;//the real number of blocks in a partition
|
||||
int n_capacity;//the max capacity of a partition -- need the top level
|
||||
public MongDBUtil dbUtil;
|
||||
byte[] bBlockData;
|
||||
|
||||
|
||||
byte s_buffer[][];//shuffule buffer - a large memory
|
||||
|
||||
private MCloudORAMserver()
|
||||
{
|
||||
bBlockData=new byte[CommInfo.blockSize];
|
||||
initFlag=false;
|
||||
dbUtil=new MongDBUtil();
|
||||
dbUtil.connect("localhost", 27017);
|
||||
cloud = 0;
|
||||
}
|
||||
public static MCloudORAMserver getInstance()
|
||||
{
|
||||
if (instance==null)
|
||||
instance=new MCloudORAMserver();
|
||||
return instance;
|
||||
}
|
||||
/**
|
||||
* This function will create the database for the ORAM
|
||||
*/
|
||||
public boolean init(int paritions, int capacity, int levels, byte cloud)
|
||||
{
|
||||
if (initFlag)
|
||||
return false;
|
||||
n_partitions = paritions;
|
||||
n_capacity = capacity;
|
||||
n_levels = levels;
|
||||
this.cloud = cloud;
|
||||
|
||||
//Create DB and open DB
|
||||
if (!dbUtil.createDB("MCloudPartitionORAM"+cloud))
|
||||
return false;
|
||||
//init partitions: create the table/collection for the partitions
|
||||
try {
|
||||
initPartitions();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// TODO ×Ô¶¯Éú³ÉµÄ catch ¿é
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
initFlag=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public boolean openDB(byte cloud)
|
||||
{
|
||||
this.cloud=cloud;
|
||||
if (!dbUtil.openDB("MCloudPartitionORAM"+cloud))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean writeBlock(int p, int _id, byte[] blockData, int pos) throws UnsupportedEncodingException
|
||||
{
|
||||
System.arraycopy(blockData, pos, bBlockData, 0, CommInfo.blockSize);
|
||||
|
||||
MongoCollection<Document> collection = dbUtil.getCollection("part_"+p);
|
||||
|
||||
String str=new String(bBlockData, "ISO-8859-1");
|
||||
|
||||
collection.findOneAndReplace(new Document("_id", _id), new Document("_id", _id).append("data", str));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public boolean readBlock(int p, int _id, byte[] receiveData) {
|
||||
boolean bError = false;
|
||||
try{
|
||||
MongoCollection<Document> collection = dbUtil
|
||||
.getCollection("part_" + p);
|
||||
// Find the data and return them
|
||||
|
||||
FindIterable<Document> findIterable = collection.find(new Document(
|
||||
"_id", _id));
|
||||
MongoCursor<Document> mongoCursor = findIterable.iterator();
|
||||
if (mongoCursor.hasNext()) {
|
||||
Document doc1 = mongoCursor.next();
|
||||
|
||||
String bData = (String) doc1.get("data");
|
||||
|
||||
byte[] bs = bData.getBytes("ISO-8859-1");
|
||||
|
||||
System.arraycopy(bs, 0, receiveData, 0, CommInfo.blockSize);
|
||||
return true;
|
||||
}
|
||||
}catch(Exception ex)
|
||||
{
|
||||
bError=true;
|
||||
ex.printStackTrace();
|
||||
}finally{
|
||||
if (bError)
|
||||
System.out.println("!!!!!!!!!!!!!!!!!readBlock mongdbError,p:"+p+" _id:"+_id);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void initPartitions() throws UnsupportedEncodingException
|
||||
{
|
||||
int i=0;
|
||||
for (i=0;i<n_partitions;i++)
|
||||
{
|
||||
dbUtil.createCollection("part_"+i);
|
||||
|
||||
//insert all the data records into the collection
|
||||
|
||||
MongoCollection<Document> collection = dbUtil.getCollection("part_"+i);
|
||||
//Each level, there are max 2^i real blocks, but more than 2^i dummy blocks
|
||||
for (int j = 0; j < n_capacity; j++) {
|
||||
/*collection.insertOne(new Document("_id", j).append("data",
|
||||
new String(bBlockData, "ISO-8859-1")));*/
|
||||
collection.insertOne(new Document("_id", j).append("data",
|
||||
bBlockData ));
|
||||
}
|
||||
/***************************************
|
||||
* Each level, there are 2^(i+1) blocks
|
||||
* ***********************************/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,606 @@
|
|||
package nankai.oram.server.mcloud;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.ResponseType;
|
||||
import nankai.oram.common.SocketClientUtil;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class MCloudPartitionServerThread extends Thread {
|
||||
|
||||
Socket socket = null; // 保存与本线程相关的Socket对象
|
||||
byte recvCmd[];
|
||||
byte recvMsg[];
|
||||
byte sendMsg[];
|
||||
MCloudORAMserver oram;
|
||||
|
||||
public MCloudPartitionServerThread(Socket socket) {
|
||||
this.socket = socket;
|
||||
recvCmd = new byte[37];
|
||||
recvMsg = new byte[1024];
|
||||
sendMsg = new byte[1024];
|
||||
oram = MCloudORAMserver.getInstance();
|
||||
//System.out.println(" new connection ......... ");
|
||||
}
|
||||
|
||||
public void run() {
|
||||
DataInputStream in = null;
|
||||
DataOutputStream out = null;
|
||||
try {
|
||||
|
||||
in = new DataInputStream(socket.getInputStream());
|
||||
out = new DataOutputStream(socket.getOutputStream());
|
||||
|
||||
byte type = 0;
|
||||
int len = 0;
|
||||
|
||||
while (true) {
|
||||
type = 0;
|
||||
len = 0;
|
||||
while ((len = in.read(recvCmd, 0, 1)) > 0) {
|
||||
type = recvCmd[0];
|
||||
// System.out
|
||||
// .println("-----------------------------------------------------------");
|
||||
// System.out.println("receive a command type:" + type + " len "
|
||||
// + len);
|
||||
break;
|
||||
}
|
||||
|
||||
//close the thread
|
||||
if (type == CommandType.closeThread)
|
||||
break;
|
||||
|
||||
switch (type) {
|
||||
case CommandType.openDB:
|
||||
{
|
||||
in.read(recvCmd, 1, 1);
|
||||
oram.openDB(recvCmd[1]);
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
|
||||
break;
|
||||
}
|
||||
case CommandType.initORAM: {
|
||||
len = in.read(recvCmd, 1, 13);
|
||||
if (len != 13) {
|
||||
System.out.println("initORAM error data! " + len);
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else
|
||||
initORAM(out);
|
||||
break;
|
||||
}
|
||||
case CommandType.readCloud: {
|
||||
len = in.read(recvCmd, 1, 24);
|
||||
if (len != 24) {
|
||||
System.out.println("readCloud error data! " + len);
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else {
|
||||
/**************************************
|
||||
* partition+_id
|
||||
* **********************************/
|
||||
readCloud(out, in);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CommandType.noticeWriteCloud: {
|
||||
len = in.read(recvCmd, 1, 24);
|
||||
// content: session ID | unfilled - partition | other cloud for shuffling | length of ids
|
||||
if (len != 24) {
|
||||
System.out.println("noticeWriteCloud error data! " + len);
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else {
|
||||
/**************************************
|
||||
* partition+_id
|
||||
* **********************************/
|
||||
noticeWriteCloud(out, in);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CommandType.noticeShuffle: {
|
||||
len = in.read(recvCmd, 1, 36);
|
||||
// content: session ID | unfilled - partition | other cloud for shuffling | length of ids
|
||||
if (len != 36) {
|
||||
System.out.println("noticeWriteCloud error data! " + len);
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else {
|
||||
/**************************************
|
||||
* partition+_id
|
||||
* **********************************/
|
||||
noticeShuffle(out, in);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CommandType.directWriteCloud:{
|
||||
len = in.read(recvCmd, 1, 12);
|
||||
if (len != 12) {
|
||||
System.out.println("directWriteCloud error data! " + len);
|
||||
for (int i=0;i<len;i++)
|
||||
System.out.print(recvCmd[i]+" ");
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else {
|
||||
/**************************************
|
||||
* partition+_id
|
||||
* **********************************/
|
||||
directWriteCloud(out, in);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CommandType.shuffleData:{
|
||||
len = in.read(recvCmd, 1, 12);
|
||||
if (len != 12) {
|
||||
System.out.println("shuffleData error data! " + len);
|
||||
for (int i=0;i<len;i++)
|
||||
System.out.print(recvCmd[i]+" ");
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else {
|
||||
/**************************************
|
||||
* partition+_id
|
||||
* **********************************/
|
||||
shuffleData(out, in);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error.?>>>>> " + e);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
out.close(); // 关闭Socket输出流
|
||||
in.close();// 关闭Socket输入流
|
||||
socket.close(); // 关闭Socket
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
//System.out.println("closing............................ ");
|
||||
}
|
||||
|
||||
private void initORAM(DataOutputStream out) throws IOException {
|
||||
/*********
|
||||
* CMD 9, CMDTYPE | PARTITIONS | CAPACITY
|
||||
* *********/
|
||||
//System.out.println("init oram");
|
||||
|
||||
int paritions = Util.byteToInt(recvCmd, 1, 4);
|
||||
int capacity = Util.byteToInt(recvCmd, 5, 4);
|
||||
int levels = Util.byteToInt(recvCmd, 9, 4);
|
||||
byte cloud = recvCmd[13];
|
||||
// System.out.println("init paritions capacity:" + paritions + " "
|
||||
// + capacity);
|
||||
oram.init(paritions, capacity, levels, cloud);
|
||||
|
||||
// System.out.println("init OK.");
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
|
||||
private synchronized void shuffleData(DataOutputStream out, DataInputStream in )
|
||||
throws IOException {
|
||||
|
||||
byte[] sessionID = new byte[8];
|
||||
|
||||
System.arraycopy(recvCmd, 1, sessionID, 0, 8);
|
||||
int idsLen = Util.byteToInt(recvCmd, 9, 4);
|
||||
|
||||
/**************************************************************
|
||||
* Get the session Object, must be received, because client first send noticeShuffle,
|
||||
* and then the target cloud sends the shuffled data
|
||||
*************************************************************/
|
||||
SessionManager manager=SessionManager.getInstance();
|
||||
//System.out.print("3. ->shuffleData ");
|
||||
SessionObject session = manager.getObject(sessionID);
|
||||
if (session==null)
|
||||
{
|
||||
//create it
|
||||
System.out.println("Cannot find the session OBJECT!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
return;
|
||||
//session=new SessionObject(sessionID);
|
||||
}
|
||||
|
||||
|
||||
int filledLevelLength = session.filledLevelLength;
|
||||
/***********************************************
|
||||
* Receive the block data from other cloud
|
||||
*
|
||||
* Firstly, onion decrypt them
|
||||
*******************************************/
|
||||
byte[] recBlcokData = new byte[CommInfo.blockSize];
|
||||
for (int i=0;i<idsLen; i++)
|
||||
{
|
||||
if (in.read(recBlcokData, 0, CommInfo.blockSize) <= 0) {
|
||||
System.out.println("shuffleData: ERROR id block data!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
}
|
||||
|
||||
//System.out.println("i: "+i+" "+recBlcokData[8]);
|
||||
session.setBlockData(recBlcokData);
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Finally, shuffule them
|
||||
*******************************************/
|
||||
// System.out.println("begin psuedo_random_permute ");
|
||||
//session.psuedo_random_permute();
|
||||
|
||||
|
||||
/***********************
|
||||
* return back the data
|
||||
* ********************************/
|
||||
byte[] backCmd=new byte[5];
|
||||
backCmd[0]=CommandType.backData;
|
||||
Util.intToByte(backCmd, 1, session.filledLevelLength);
|
||||
|
||||
out.write(backCmd, 0, 5);
|
||||
out.flush();
|
||||
for (int i=0;i<session.filledLevelLength;i++)
|
||||
{
|
||||
//System.out.println("after shuffle i: "+i+" "+session.shffule[i][8]);
|
||||
out.write(session.shffule[i], 0, CommInfo.blockSize);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
//The end of the session
|
||||
manager.removeObject(session);
|
||||
|
||||
}
|
||||
|
||||
private synchronized void directWriteCloud(DataOutputStream out, DataInputStream in )
|
||||
throws IOException {
|
||||
/****************************************
|
||||
* (1)Send All the data, onionkeys in slots to the otherCloud
|
||||
*
|
||||
* CommandType: shuffleData
|
||||
* Content: session ID | unfilled levels number |
|
||||
* onion keys and slots data
|
||||
* ************************************/
|
||||
|
||||
//System.out.println("directWriteCloud");
|
||||
|
||||
int partition = Util.byteToInt(recvCmd, 1, 4);
|
||||
int unfilledLevel = Util.byteToInt(recvCmd, 5, 4);
|
||||
int filledLevelLength = Util.byteToInt(recvCmd, 9, 4); ;
|
||||
|
||||
/*******************
|
||||
* Has received the write operation command?
|
||||
* If not, create the session object
|
||||
* *********************/
|
||||
byte[] recBlcokData = new byte[CommInfo.blockSize];
|
||||
int beginID=(1 << (unfilledLevel + 1)) - 2;
|
||||
for (int i=0;i<filledLevelLength;i++)
|
||||
{
|
||||
if (in.read(recBlcokData, 0, CommInfo.blockSize) <= 0) {
|
||||
System.out.println("ERROR read data!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
}else{
|
||||
//System.out.println("writeBlock " + recBlcokData[2]);
|
||||
oram.writeBlock(partition, beginID+i, recBlcokData, 0);
|
||||
}
|
||||
//System.out.println("i: "+i+ " "+recBlcokData[0]);
|
||||
}
|
||||
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* When receive this data, the cloud would read data and send them to the other cloud
|
||||
* @param out
|
||||
* @param in
|
||||
* @throws IOException
|
||||
*/
|
||||
private synchronized void readCloud(DataOutputStream out, DataInputStream in )
|
||||
throws IOException {
|
||||
|
||||
|
||||
byte[] bretData = new byte[CommInfo.blockSize];
|
||||
|
||||
int partition = Util.byteToInt(recvCmd, 9, 4);
|
||||
int targetPos = Util.byteToInt(recvCmd, 13, 4);
|
||||
int length= Util.byteToInt(recvCmd, 17, 4);
|
||||
int shuffleCloud= Util.byteToInt(recvCmd, 21, 4);
|
||||
|
||||
//read all the ids and then send them
|
||||
byte[] ids = new byte[length * 4];
|
||||
if (length > 0) {
|
||||
if (in.read(ids, 0, length * 4) != length * 4) {
|
||||
System.out.println("error 1");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//System.out.println("readcloud - shuffleCloud:"+shuffleCloud+" session "+recvCmd[1]);
|
||||
|
||||
SocketClientUtil SCU=new SocketClientUtil(MCloudCommInfo.ip[shuffleCloud], MCloudCommInfo.port[shuffleCloud]);
|
||||
SCU.connect();
|
||||
byte[] cmd=new byte[13];
|
||||
cmd[0]=CommandType.shuffleData;
|
||||
System.arraycopy(recvCmd, 1, cmd, 1, 8);
|
||||
Util.intToByte(cmd, 9, length);//
|
||||
|
||||
SCU.send(cmd, 13);
|
||||
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
|
||||
if (length > 0) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
int _id = Util.byteToInt(ids, i * 4, 4);
|
||||
|
||||
oram.readBlock(partition, _id, bData);
|
||||
//System.out.println("_id: "+_id+" i: "+i+" "+bData[8]);
|
||||
SCU.send(bData, CommInfo.blockSize);
|
||||
}
|
||||
}
|
||||
|
||||
//Then, waiting for the response
|
||||
byte[] backCmd=new byte[5];
|
||||
if (SCU.receiving(backCmd, 5)!=5 || backCmd[0]!=CommandType.backData)
|
||||
System.out.println("wrong back command!");
|
||||
int len=Util.byteToInt(backCmd, 1, 4);
|
||||
for (int i=0; i<len; i++)
|
||||
{
|
||||
//receive the data block and add it to the shuffle
|
||||
if (SCU.receiving(bData, CommInfo.blockSize)!=CommInfo.blockSize){
|
||||
System.out.println("wrong back data!");
|
||||
}
|
||||
|
||||
if (targetPos==i){
|
||||
System.arraycopy(bData, 0, bretData, 0, CommInfo.blockSize);
|
||||
}
|
||||
}
|
||||
|
||||
SCU.disConnect();
|
||||
|
||||
out.writeByte(ResponseType.normalWithValue);
|
||||
out.flush();
|
||||
out.write(bretData, 0, CommInfo.blockSize);
|
||||
out.flush();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* When receive this data, the cloud would read data and send them to the other cloud
|
||||
* @param out
|
||||
* @param in
|
||||
* @throws IOException
|
||||
*/
|
||||
private synchronized void noticeShuffle(DataOutputStream out, DataInputStream in )
|
||||
throws IOException {
|
||||
/****************************************
|
||||
* (1)Send All the data, onionkeys in slots to the otherCloud
|
||||
*
|
||||
* CommandType: shuffleData
|
||||
* Content: session ID | unfilled levels number |
|
||||
* onion keys and slots data
|
||||
* ************************************/
|
||||
|
||||
//System.out.println("noticeShuffle");
|
||||
byte[] sessionID = new byte[8];
|
||||
byte[] sfk = new byte[16];
|
||||
|
||||
System.arraycopy(recvCmd, 1, sessionID, 0, 8);
|
||||
System.arraycopy(recvCmd, 9, sfk, 0, 16);
|
||||
|
||||
|
||||
int partition = Util.byteToInt(recvCmd, 25, 4);
|
||||
int idsLen = Util.byteToInt(recvCmd, 29, 4);
|
||||
int levels = Util.byteToInt(recvCmd, 33, 4);
|
||||
|
||||
/*******************
|
||||
* Has received the write operation command?
|
||||
* If not, create the session object
|
||||
* *********************/
|
||||
SessionManager manager=SessionManager.getInstance();
|
||||
//System.out.print("1. ->noticeShuffle ");
|
||||
SessionObject session = new SessionObject(sessionID);
|
||||
session.setSFKey(sfk);
|
||||
|
||||
//receive the IDs
|
||||
byte[] ids = new byte[idsLen*4];
|
||||
if (idsLen>0){
|
||||
// read all the ids
|
||||
if (in.read(ids, 0, idsLen*4) <= 0)
|
||||
System.out.println("ERROR read IDs data!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
}else{
|
||||
;//System.out.println("ids Len is 0!!");
|
||||
}
|
||||
|
||||
//read the block and set to buffer
|
||||
session.createShuffle(levels);
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int i=0;i<idsLen;i++)
|
||||
{
|
||||
//Read form the dabase to get the target block
|
||||
int _id = Util.byteToInt(ids, i * 4, 4);
|
||||
|
||||
oram.readBlock(partition, _id, bData);
|
||||
//System.out.println("noticeShuffle i: "+i+ " "+bData[8]);
|
||||
session.setBlockData(i, bData);
|
||||
}
|
||||
|
||||
manager.addObject(session);
|
||||
|
||||
|
||||
if (in.read(recvCmd,0,2)!=2)
|
||||
System.out.println("error 2");
|
||||
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
|
||||
}
|
||||
/**
|
||||
* When receive this data, the cloud would read data and send them to the other cloud
|
||||
* @param out
|
||||
* @param in
|
||||
* @throws IOException
|
||||
*/
|
||||
private synchronized void noticeWriteCloud(DataOutputStream out, DataInputStream in )
|
||||
throws IOException {
|
||||
/****************************************
|
||||
* (1)Notice this cloud to send the data to the otherCloud for shuffling
|
||||
* CommandType: writeCloud
|
||||
* content: session ID | unfilled - partition | other cloud for shuffling | length of ids
|
||||
*
|
||||
* When receive this data, the cloud would read data and send them to the other cloud
|
||||
* ************************************/
|
||||
|
||||
|
||||
int partition = Util.byteToInt(recvCmd, 1, 4);
|
||||
int cloud = Util.byteToInt(recvCmd, 5, 4);
|
||||
int unfilledLevel= Util.byteToInt(recvCmd, 9, 4);
|
||||
int filledLevelLength= Util.byteToInt(recvCmd, 13, 4);
|
||||
int unreadDataNumber= Util.byteToInt(recvCmd, 17, 4);
|
||||
int otherCloud= Util.byteToInt(recvCmd, 21, 4);
|
||||
|
||||
byte[][] s_buffer=new byte[filledLevelLength][CommInfo.blockSize];
|
||||
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
int nowPos = 0;
|
||||
if (in.read(bData, 0, CommInfo.blockSize)!=CommInfo.blockSize)
|
||||
{
|
||||
System.out.println("error 3");
|
||||
}else{
|
||||
System.arraycopy(bData, 0, s_buffer[nowPos++], 0, CommInfo.blockSize);
|
||||
}
|
||||
|
||||
byte[] ids=new byte[unreadDataNumber*4 ];
|
||||
//
|
||||
if (unreadDataNumber > 0) {
|
||||
// if (in.read(ids, 0, unreadDataNumber * 4) != unreadDataNumber * 4) {
|
||||
// System.out.println("error 4");
|
||||
// }
|
||||
|
||||
int dataLen = unreadDataNumber*4;
|
||||
if (dataLen<512){
|
||||
if (in.read(ids, 0, dataLen)!=dataLen)
|
||||
System.out.println("ids Error!!!");
|
||||
}else{
|
||||
int num = dataLen / 512 ;
|
||||
int leftLen = dataLen % 512;
|
||||
int hasRead = 0;
|
||||
for (int i=0;i<num;i++)
|
||||
{
|
||||
|
||||
if (in.read(ids, hasRead, 512)!=512)
|
||||
System.out.println("noticeShuffle 512 Error!!!");
|
||||
hasRead += 512;
|
||||
}
|
||||
if (leftLen>0){
|
||||
if (in.read(ids, hasRead, leftLen)!=leftLen)
|
||||
System.out.println("noticeShuffle leftLen Error!!!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < unreadDataNumber; i++) {
|
||||
int _id = Util.byteToInt(ids, i * 4, 4);
|
||||
|
||||
oram.readBlock(partition, _id, bData);
|
||||
System.arraycopy(bData, 0, s_buffer[nowPos++], 0,
|
||||
CommInfo.blockSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//generate dummy block
|
||||
for (int i=nowPos; i<filledLevelLength;i++)
|
||||
{
|
||||
byte[] bDummy=Util.generateDummyData(CommInfo.blockSize);
|
||||
System.arraycopy(bDummy, 0, s_buffer[nowPos++], 0, CommInfo.blockSize);
|
||||
}
|
||||
|
||||
|
||||
byte[] sfk=new byte[16];
|
||||
if (in.read(sfk, 0, 16) <= 0) {
|
||||
System.out.println("ERROR read key data!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
}
|
||||
|
||||
|
||||
if (in.read(recvCmd,0,2)!=2)
|
||||
System.out.println("error 2");
|
||||
|
||||
//send to other cloud and storage
|
||||
|
||||
psuedo_random_permute(sfk, s_buffer, filledLevelLength);
|
||||
|
||||
if (otherCloud != cloud){
|
||||
// Then send to another cloud to write
|
||||
SocketClientUtil SCU = new SocketClientUtil(
|
||||
MCloudCommInfo.ip[otherCloud],
|
||||
MCloudCommInfo.port[otherCloud]);
|
||||
SCU.connect();
|
||||
byte[] cmd = new byte[13];
|
||||
cmd[0] = CommandType.directWriteCloud;
|
||||
Util.intToByte(cmd, 1, partition);//
|
||||
Util.intToByte(cmd, 5, unfilledLevel);//
|
||||
Util.intToByte(cmd, 9, filledLevelLength);//
|
||||
|
||||
SCU.send(cmd, 13);
|
||||
for (int i = 0; i < filledLevelLength; i++) {
|
||||
SCU.send(s_buffer[i], CommInfo.blockSize);
|
||||
}
|
||||
|
||||
//System.out.println("direct write cloud ok!");
|
||||
// Then, waiting for the response
|
||||
byte[] backCmd = new byte[1];
|
||||
if (SCU.receiving(backCmd, 1) != 1
|
||||
|| backCmd[0] != ResponseType.normal)
|
||||
System.out.println("wrong back command!");
|
||||
|
||||
SCU.disConnect();
|
||||
}else{
|
||||
//If it is not the other cloud, will be written here
|
||||
int beginID=(1 << (unfilledLevel + 1)) - 2;
|
||||
for (int i = 0; i < filledLevelLength; i++) {
|
||||
oram.writeBlock(partition, beginID+i, s_buffer[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public void psuedo_random_permute(byte[] sfk1, byte[][] shffule, int filledLevelLength) {
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
|
||||
SecretKey sfk = new SecretKeySpec(sfk1, "AES");
|
||||
// for (int i = 0; i < filledLevelLength; i++) {
|
||||
// System.out.println("i: "+i+" "+shffule[i][0]);
|
||||
// }
|
||||
|
||||
for (int i = 0; i <filledLevelLength; i++) {
|
||||
|
||||
int j = Util.fpeForPermution(i, sfk, filledLevelLength);
|
||||
System.arraycopy(shffule[i], 0, bData, 0, CommInfo.blockSize);
|
||||
System.arraycopy(shffule[j], 0, shffule[i], 0, CommInfo.blockSize);
|
||||
System.arraycopy(bData, 0, shffule[j], 0, CommInfo.blockSize);
|
||||
|
||||
// System.out.println("permute: "+i+" "+j);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
package nankai.oram.server.mcloud;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.MongDBUtil;
|
||||
import nankai.oram.server.partition.PartitionORAMServer;
|
||||
|
||||
import org.bson.Document;
|
||||
|
||||
import com.mongodb.client.FindIterable;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoCursor;
|
||||
|
||||
public class NewMCloudORAMserver {
|
||||
public static NewMCloudORAMserver instance;
|
||||
byte cloud;
|
||||
boolean initFlag;
|
||||
int N;
|
||||
int n_levels;
|
||||
int n_partitions;
|
||||
int n_blocks;
|
||||
int n_realBlocks_p;//the real number of blocks in a partition
|
||||
int n_capacity;//the max capacity of a partition -- need the top level
|
||||
public MongDBUtil dbUtil;
|
||||
byte[] bBlockData;
|
||||
|
||||
|
||||
byte s_buffer[][];//shuffule buffer - a large memory
|
||||
|
||||
private NewMCloudORAMserver()
|
||||
{
|
||||
bBlockData=new byte[CommInfo.blockSize];
|
||||
initFlag=false;
|
||||
dbUtil=new MongDBUtil();
|
||||
dbUtil.connect("localhost", 27017);
|
||||
cloud = 0;
|
||||
}
|
||||
public static NewMCloudORAMserver getInstance()
|
||||
{
|
||||
if (instance==null)
|
||||
instance=new NewMCloudORAMserver();
|
||||
return instance;
|
||||
}
|
||||
/**
|
||||
* This function will create the database for the ORAM
|
||||
*/
|
||||
public boolean init(int paritions, int capacity, int levels, byte cloud)
|
||||
{
|
||||
if (initFlag)
|
||||
return false;
|
||||
n_partitions = paritions;
|
||||
n_capacity = capacity;
|
||||
n_levels = levels;
|
||||
this.cloud = cloud;
|
||||
|
||||
//Create DB and open DB
|
||||
if (!dbUtil.createDB("NEWMCloudPartitionORAM"+cloud))
|
||||
return false;
|
||||
//init partitions: create the table/collection for the partitions
|
||||
try {
|
||||
initPartitions();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// TODO ×Ô¶¯Éú³ÉµÄ catch ¿é
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
initFlag=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public boolean openDB(byte cloud)
|
||||
{
|
||||
this.cloud=cloud;
|
||||
if (!dbUtil.openDB("NEWMCloudPartitionORAM"+cloud))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean writeBlock(int p, int _id, byte[] blockData, int pos) throws UnsupportedEncodingException
|
||||
{
|
||||
System.arraycopy(blockData, pos, bBlockData, 0, CommInfo.blockSize);
|
||||
|
||||
MongoCollection<Document> collection = dbUtil.getCollection("part_"+p);
|
||||
|
||||
String str=new String(bBlockData, "ISO-8859-1");
|
||||
|
||||
collection.findOneAndReplace(new Document("_id", _id), new Document("_id", _id).append("data", str));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public boolean readBlock(int p, int _id, byte[] receiveData) {
|
||||
boolean bError = false;
|
||||
try{
|
||||
MongoCollection<Document> collection = dbUtil
|
||||
.getCollection("part_" + p);
|
||||
// Find the data and return them
|
||||
|
||||
FindIterable<Document> findIterable = collection.find(new Document(
|
||||
"_id", _id));
|
||||
MongoCursor<Document> mongoCursor = findIterable.iterator();
|
||||
if (mongoCursor.hasNext()) {
|
||||
Document doc1 = mongoCursor.next();
|
||||
|
||||
String bData = (String) doc1.get("data");
|
||||
|
||||
byte[] bs = bData.getBytes("ISO-8859-1");
|
||||
|
||||
System.arraycopy(bs, 0, receiveData, 0, CommInfo.blockSize);
|
||||
return true;
|
||||
}
|
||||
}catch(Exception ex)
|
||||
{
|
||||
bError=true;
|
||||
ex.printStackTrace();
|
||||
}finally{
|
||||
if (bError)
|
||||
System.out.println("!!!!!!!!!!!!!!!!!readBlock mongdbError,p:"+p+" _id:"+_id);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void initPartitions() throws UnsupportedEncodingException
|
||||
{
|
||||
int i=0;
|
||||
for (i=0;i<n_partitions;i++)
|
||||
{
|
||||
dbUtil.createCollection("part_"+i);
|
||||
|
||||
//insert all the data records into the collection
|
||||
|
||||
MongoCollection<Document> collection = dbUtil.getCollection("part_"+i);
|
||||
//Each level, there are max 2^i real blocks, but more than 2^i dummy blocks
|
||||
for (int j = 0; j < n_capacity; j++) {
|
||||
/*collection.insertOne(new Document("_id", j).append("data",
|
||||
new String(bBlockData, "ISO-8859-1")));*/
|
||||
collection.insertOne(new Document("_id", j).append("data",
|
||||
bBlockData ));
|
||||
}
|
||||
/***************************************
|
||||
* Each level, there are 2^(i+1) blocks
|
||||
* ***********************************/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,640 @@
|
|||
package nankai.oram.server.mcloud;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.ResponseType;
|
||||
import nankai.oram.common.SocketClientUtil;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class NewMCloudPartitionServerThread extends Thread {
|
||||
|
||||
Socket socket = null; // 保存与本线程相关的Socket对象
|
||||
byte recvCmd[];
|
||||
byte recvMsg[];
|
||||
byte sendMsg[];
|
||||
NewMCloudORAMserver oram;
|
||||
|
||||
public NewMCloudPartitionServerThread(Socket socket) {
|
||||
this.socket = socket;
|
||||
recvCmd = new byte[29];
|
||||
recvMsg = new byte[1024];
|
||||
sendMsg = new byte[1024];
|
||||
oram = NewMCloudORAMserver.getInstance();
|
||||
//System.out.println(" new connection ......... ");
|
||||
}
|
||||
|
||||
public void run() {
|
||||
DataInputStream in = null;
|
||||
DataOutputStream out = null;
|
||||
try {
|
||||
|
||||
in = new DataInputStream(socket.getInputStream());
|
||||
out = new DataOutputStream(socket.getOutputStream());
|
||||
|
||||
byte type = 0;
|
||||
int len = 0;
|
||||
|
||||
while (true) {
|
||||
type = 0;
|
||||
len = 0;
|
||||
while ((len = in.read(recvCmd, 0, 1)) > 0) {
|
||||
type = recvCmd[0];
|
||||
// System.out
|
||||
// .println("-----------------------------------------------------------");
|
||||
// System.out.println("receive a command type:" + type + " len "
|
||||
// + len);
|
||||
break;
|
||||
}
|
||||
|
||||
//close the thread
|
||||
if (type == CommandType.closeThread)
|
||||
break;
|
||||
|
||||
switch (type) {
|
||||
case CommandType.openDB:
|
||||
{
|
||||
in.read(recvCmd, 1, 1);
|
||||
oram.openDB(recvCmd[1]);
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
|
||||
break;
|
||||
}
|
||||
case CommandType.initORAM: {
|
||||
len = in.read(recvCmd, 1, 13);
|
||||
if (len != 13) {
|
||||
System.out.println("initORAM error data! " + len);
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else
|
||||
initORAM(out);
|
||||
break;
|
||||
}
|
||||
case CommandType.readCloud: {
|
||||
len = in.read(recvCmd, 1, 8);
|
||||
if (len != 8) {
|
||||
System.out.println("readCloud error data! " + len);
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else {
|
||||
/**************************************
|
||||
* partition+_id
|
||||
* **********************************/
|
||||
readCloud(out, in);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CommandType.noticeWriteCloud: {
|
||||
len = in.read(recvCmd, 1, 21);
|
||||
// content: session ID | unfilled - partition | other cloud for shuffling | length of ids
|
||||
if (len != 21) {
|
||||
System.out.println("noticeWriteCloud error data! " + len);
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else {
|
||||
/**************************************
|
||||
* partition+_id
|
||||
* **********************************/
|
||||
noticeWriteCloud(out, in);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CommandType.directWriteCloud:
|
||||
{
|
||||
len = in.read(recvCmd, 1, 12);
|
||||
// content: session ID | unfilled - partition | other cloud for shuffling | length of ids
|
||||
if (len != 12) {
|
||||
System.out.println("directWriteCloud error data! " + len);
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else {
|
||||
/**************************************
|
||||
* partition+_id
|
||||
* **********************************/
|
||||
directWriteCloud(out, in);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CommandType.noticeShuffle: {
|
||||
len = in.read(recvCmd, 1, 28);
|
||||
// content: session ID | unfilled - partition | other cloud for shuffling | length of ids
|
||||
if (len != 28) {
|
||||
System.out.println("noticeWriteCloud error data! " + len);
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else {
|
||||
/**************************************
|
||||
* partition+_id
|
||||
* **********************************/
|
||||
noticeShuffle(out, in);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CommandType.shuffleData:{
|
||||
len = in.read(recvCmd, 1, 12);
|
||||
if (len != 12) {
|
||||
System.out.println("shuffleData error data! " + len);
|
||||
for (int i=0;i<len;i++)
|
||||
System.out.print(recvCmd[i]+" ");
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else {
|
||||
/**************************************
|
||||
* partition+_id
|
||||
* **********************************/
|
||||
shuffleData(out, in);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error.?>>>>> " + e);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
out.close(); // 关闭Socket输出流
|
||||
in.close();// 关闭Socket输入流
|
||||
socket.close(); // 关闭Socket
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
//System.out.println("closing............................ ");
|
||||
}
|
||||
|
||||
private void initORAM(DataOutputStream out) throws IOException {
|
||||
/*********
|
||||
* CMD 9, CMDTYPE | PARTITIONS | CAPACITY
|
||||
* *********/
|
||||
// System.out.println("init oram");
|
||||
|
||||
int paritions = Util.byteToInt(recvCmd, 1, 4);
|
||||
int capacity = Util.byteToInt(recvCmd, 5, 4);
|
||||
int levels = Util.byteToInt(recvCmd, 9, 4);
|
||||
byte cloud = recvCmd[13];
|
||||
// System.out.println("init paritions capacity:" + paritions + " "
|
||||
// + capacity);
|
||||
oram.init(paritions, capacity, levels, cloud);
|
||||
|
||||
// System.out.println("init OK.");
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* When receive this data, the cloud would read data and send them to the other cloud
|
||||
* @param out
|
||||
* @param in
|
||||
* @throws IOException
|
||||
*/
|
||||
private void shuffleData(DataOutputStream out, DataInputStream in)
|
||||
throws IOException {
|
||||
/****************************************
|
||||
* (2)Send All the data, onionkeys in slots to the otherCloud
|
||||
*
|
||||
* CommandType: shuffleData
|
||||
* Content: session ID | unfilled levels number |
|
||||
* onion keys and slots data
|
||||
* ************************************/
|
||||
|
||||
byte[] sessionID = new byte[8];
|
||||
|
||||
System.arraycopy(recvCmd, 1, sessionID, 0, 8);
|
||||
int idsLen = Util.byteToInt(recvCmd, 9, 4);
|
||||
|
||||
//System.out.println("4. shuffleData " + sessionID[0]);
|
||||
/**************************************************************
|
||||
* Get the session Object, must be received, because client first send noticeShuffle,
|
||||
* and then the target cloud sends the shuffled data
|
||||
*************************************************************/
|
||||
SessionManager manager=SessionManager.getInstance();
|
||||
SessionObject session = manager.getObject(sessionID);
|
||||
if (session==null)
|
||||
{
|
||||
//create it
|
||||
System.out.println("Cannot find the session OBJECT!!!!!!!!!!!!!!!!!!!!!!!"+sessionID[0]+" "+sessionID[5]);
|
||||
return;
|
||||
//session=new SessionObject(sessionID);
|
||||
}
|
||||
//verify the length
|
||||
if (idsLen != session.idsLen)
|
||||
System.out.println("wrong ID number!!!!!!!!!!!!!!!!!!!!!!! idsLen:"+idsLen+" "+session.idsLen);
|
||||
|
||||
//System.out.println("shuffleData: idsLen "+idsLen);
|
||||
|
||||
int filledLevelLength = session.filledLevelLength;
|
||||
/***********************************************
|
||||
* Receive the block data from other cloud
|
||||
*
|
||||
* Firstly, onion decrypt them
|
||||
*******************************************/
|
||||
byte[] recBlcokData = new byte[CommInfo.blockSize];
|
||||
for (int i=0;i<idsLen; i++)
|
||||
{
|
||||
if (in.read(recBlcokData, 0, CommInfo.blockSize) <= 0) {
|
||||
System.out.println("shuffleData: ERROR id block data!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
}
|
||||
/******************** do the onion decryption ********************************/
|
||||
session.setBlockDataWithOnionDecryption(filledLevelLength - idsLen + i, recBlcokData, session.levels[i]);
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Finally, shuffule them
|
||||
*******************************************/
|
||||
// System.out.println("begin psuedo_random_permute ");
|
||||
session.psuedo_random_permute();
|
||||
//re-encrypt them and send backs
|
||||
session.onionEncryption();
|
||||
|
||||
/***********************
|
||||
* return back the data
|
||||
* ********************************/
|
||||
byte[] backCmd=new byte[5];
|
||||
backCmd[0]=CommandType.backData;
|
||||
Util.intToByte(backCmd, 1, session.filledLevelLength);
|
||||
|
||||
out.write(backCmd, 0, 5);
|
||||
out.flush();
|
||||
for (int i=0;i<session.filledLevelLength;i++)
|
||||
{
|
||||
out.write(session.shffule[i], 0, CommInfo.blockSize);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
//The end of the session
|
||||
manager.removeObject(session);
|
||||
}
|
||||
|
||||
|
||||
private void directWriteCloud(DataOutputStream out, DataInputStream in)
|
||||
throws IOException {
|
||||
/****************************************
|
||||
* (1)Send All the data, onionkeys in slots to the otherCloud
|
||||
*
|
||||
* CommandType: shuffleData
|
||||
* Content: session ID | unfilled levels number |
|
||||
* onion keys and slots data
|
||||
* ************************************/
|
||||
|
||||
//System.out.println("directWriteCloud");
|
||||
|
||||
int partition = Util.byteToInt(recvCmd, 1, 4);
|
||||
int unfilledLevel = Util.byteToInt(recvCmd, 5, 4);
|
||||
int filledLevelLength = Util.byteToInt(recvCmd, 9, 4); ;
|
||||
|
||||
/*******************
|
||||
* Has received the write operation command?
|
||||
* If not, create the session object
|
||||
* *********************/
|
||||
byte[] recBlcokData = new byte[CommInfo.blockSize];
|
||||
int beginID=(1 << (unfilledLevel + 1)) - 2;
|
||||
for (int i=0;i<filledLevelLength;i++)
|
||||
{
|
||||
if (in.read(recBlcokData, 0, CommInfo.blockSize) <= 0) {
|
||||
System.out.println("ERROR read data!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
}else{
|
||||
oram.writeBlock(partition, beginID+i, recBlcokData, 0);
|
||||
}
|
||||
//System.out.println("i: "+i+ " "+recBlcokData[0]);
|
||||
}
|
||||
|
||||
//read the sfk
|
||||
byte[] sfk=new byte[2];
|
||||
if (in.read(sfk, 0, 2) <= 0) {
|
||||
System.out.println("ERROR read key data!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
}
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
|
||||
}
|
||||
/**
|
||||
* When receive this data, the cloud would read data and send them to the other cloud
|
||||
* @param out
|
||||
* @param in
|
||||
* @throws IOException
|
||||
*/
|
||||
private void noticeShuffle(DataOutputStream out, DataInputStream in)
|
||||
throws IOException {
|
||||
/****************************************
|
||||
* (1)Send All the data, onionkeys in slots to the otherCloud
|
||||
*
|
||||
* CommandType: shuffleData
|
||||
* Content: session ID | unfilled levels number |
|
||||
* onion keys and slots data
|
||||
* ************************************/
|
||||
|
||||
//System.out.println("1. noticeShuffle");
|
||||
byte[] sessionID = new byte[8];
|
||||
|
||||
System.arraycopy(recvCmd, 1, sessionID, 0, 8);
|
||||
int partition = Util.byteToInt(recvCmd, 9, 4);
|
||||
int unfilledLevel = Util.byteToInt(recvCmd, 13, 4);
|
||||
int filledLevelLength = Util.byteToInt(recvCmd, 17, 4);
|
||||
int idsLen = Util.byteToInt(recvCmd, 21, 4);
|
||||
int evictSize = Util.byteToInt(recvCmd, 25, 4);
|
||||
// System.out.println(" partition "+ partition +" unfilledLevel "+ unfilledLevel+" filledLevelLength "+filledLevelLength+" idsLen "+idsLen );
|
||||
int rndLength = filledLevelLength - idsLen - 2*evictSize;
|
||||
if (rndLength<0)
|
||||
System.out.println(" rndLength "+ rndLength +" filledLevelLength "+filledLevelLength+" idsLen "+idsLen+" evictSize "+evictSize );
|
||||
|
||||
|
||||
if (filledLevelLength <=0 )
|
||||
;//System.out.println("ERROR!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
|
||||
/*******************
|
||||
* Has received the write operation command?
|
||||
* If not, create the session object
|
||||
* *********************/
|
||||
SessionManager manager=SessionManager.getInstance();
|
||||
SessionObject session = manager.getObject(sessionID);
|
||||
if (session==null)
|
||||
{
|
||||
//create it
|
||||
session=new SessionObject(sessionID);
|
||||
}
|
||||
|
||||
//receive the IDs
|
||||
byte[] levels = new byte[idsLen];
|
||||
if (idsLen>0){
|
||||
// read all the ids
|
||||
// if (in.read(levels, 0, idsLen) <= 0)
|
||||
// System.out.println("ERROR read IDs data!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
|
||||
readSocketLongData(in, idsLen, levels);
|
||||
|
||||
|
||||
}else{
|
||||
;//System.out.println("ids Len is 0!!");
|
||||
}
|
||||
session.setLevels(levels, idsLen);
|
||||
|
||||
|
||||
//receive each data and buffer them
|
||||
session.createShuffle(filledLevelLength);
|
||||
byte[] recBlcokData = new byte[CommInfo.blockSize];
|
||||
for (int i=0;i< 2*evictSize ;i++)
|
||||
{
|
||||
if (in.read(recBlcokData, 0, CommInfo.blockSize) <= 0) {
|
||||
System.out.println("ERROR read data!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
}
|
||||
//System.out.println("i: "+i+ " "+recBlcokData[0]);
|
||||
session.setBlockData(i, recBlcokData);
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
* read the random value and generate the dummy data
|
||||
******************************************************/
|
||||
byte[] rnds=new byte[rndLength*4];
|
||||
{
|
||||
|
||||
|
||||
readSocketLongData(in, rndLength*4, rnds);
|
||||
|
||||
for (int i=0;i<rndLength;i++)
|
||||
{
|
||||
int did=Util.byteToInt(rnds, i*4, 4);
|
||||
//add the dummy block into the buffer
|
||||
session.setBlockData(i+2*evictSize, this.generateXORBlock(did));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//receive the onion keys
|
||||
session.createkey(unfilledLevel);
|
||||
byte[] bkeyData = new byte[CommInfo.keySize];
|
||||
for (int i=MCloudCommInfo.severBeginLevel; i<=unfilledLevel; i++)
|
||||
{
|
||||
if (in.read(bkeyData, 0, CommInfo.keySize) <= 0) {
|
||||
System.out.println("ERROR read key data!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
}
|
||||
session.setKey(i, bkeyData);
|
||||
}
|
||||
|
||||
//read the sfk
|
||||
byte[] sfk=new byte[16];
|
||||
if (in.read(sfk, 0, 16) <= 0) {
|
||||
System.out.println("ERROR read key data!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
}
|
||||
|
||||
session.setSFKey(sfk);
|
||||
manager.addObject(session);
|
||||
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public byte[] generateXORBlock(int dummyID)
|
||||
{
|
||||
//Encrypt the 0x00 default value by the userkey
|
||||
byte[] data=new byte[CommInfo.blockSize];
|
||||
for (int i=0;i<CommInfo.blockSize;i++)
|
||||
{
|
||||
data[i] = 0;
|
||||
}
|
||||
|
||||
// SecretKey userKey;
|
||||
// /****************************
|
||||
// * The first 4 bytes is the dummmyID and the random value, to make sure it is less than 0
|
||||
// *
|
||||
// * But now, to simplify the implementation, we ignore the random value for the same 0000000
|
||||
// * ******************************/
|
||||
//
|
||||
// byte[] iv = Util.generateIV(dummyID);
|
||||
|
||||
//encrypt
|
||||
// SymmetricCypto scp=new SymmetricCypto(CommInfo.keySize);
|
||||
// scp.initEnc(userKey, iv);
|
||||
// scp.enc_decData(data, CommInfo.blockSize);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* When receive this data, the cloud would read data and send them to the other cloud
|
||||
* @param out
|
||||
* @param in
|
||||
* @throws IOException
|
||||
*/
|
||||
private void noticeWriteCloud(DataOutputStream out, DataInputStream in)
|
||||
throws IOException {
|
||||
/****************************************
|
||||
* (1)Notice this cloud to send the data to the otherCloud for shuffling
|
||||
* CommandType: writeCloud
|
||||
* content: session ID | unfilled - partition | other cloud for shuffling | length of ids
|
||||
*
|
||||
* When receive this data, the cloud would read data and send them to the other cloud
|
||||
* ************************************/
|
||||
|
||||
//System.out.println("3. noticeWriteCloud "+recvCmd[1]);
|
||||
byte[] sessionID = new byte[8];
|
||||
|
||||
System.arraycopy(recvCmd, 1, sessionID, 0, 8);
|
||||
int partition = Util.byteToInt(recvCmd, 9, 4);
|
||||
int unfilledLevel = Util.byteToInt(recvCmd, 13, 4);
|
||||
int cloud = recvCmd[17];
|
||||
int idsLen = Util.byteToInt(recvCmd, 18, 4);
|
||||
|
||||
byte[] ids = null;
|
||||
// 4 ID + 1 level
|
||||
if (idsLen > 0) {
|
||||
|
||||
ids = new byte[idsLen*4];
|
||||
|
||||
// if (in.read(ids, 0, idsLen*4)!=idsLen*4)
|
||||
// System.out.println("ids Error!!!");
|
||||
|
||||
readSocketLongData(in, idsLen*4, ids);
|
||||
|
||||
|
||||
|
||||
}else{
|
||||
;//System.out.println("data length is 0!");
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* SEND COMMAND TO OTHER CLOUD
|
||||
* ***************************/
|
||||
byte[] cmd=new byte[13];
|
||||
cmd[0]=CommandType.shuffleData;
|
||||
System.arraycopy(sessionID, 0, cmd, 1, 8);//session ID
|
||||
Util.intToByte(cmd, 9, idsLen);//idsLen
|
||||
|
||||
SocketClientUtil SCU=new SocketClientUtil(MCloudCommInfo.ip[cloud], MCloudCommInfo.port[cloud]);
|
||||
SCU.connect();
|
||||
|
||||
// System.out.println("Ready for shuffle data command sending!");
|
||||
// for (int i=0;i<13;i++)
|
||||
// System.out.print(cmd[i]+" ");
|
||||
SCU.send(cmd, 13);
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
for (int i = 0; i < idsLen; i++) {
|
||||
int _id = Util.byteToInt(ids, i * 4, 4);
|
||||
// System.out.println("read _id: "+_id+" partition: "+partition);
|
||||
//IDS 4 id | 1 level
|
||||
|
||||
// if (_id == 0) {
|
||||
// System.out
|
||||
// .println("noticeWriteCloud :!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!idsLen!!!!!!"
|
||||
// + idsLen);
|
||||
// for (int z = 0; z < idsLen * 4; z++)
|
||||
// System.out.print(ids[z] + " ");
|
||||
//
|
||||
// for (int z = 0; z < idsLen ; z++)
|
||||
// {
|
||||
// int _did = Util.byteToInt(ids, z * 4, 4);
|
||||
// System.out.print(_did + " ");
|
||||
// }
|
||||
// }
|
||||
|
||||
oram.readBlock(partition, _id, bData);
|
||||
SCU.send(bData, CommInfo.blockSize);
|
||||
}
|
||||
|
||||
//Then, waiting for the response
|
||||
byte[] backCmd=new byte[5];
|
||||
if (SCU.receiving(backCmd, 5)!=5 || backCmd[0]!=CommandType.backData)
|
||||
System.out.println("wrong back command!");
|
||||
int length=Util.byteToInt(backCmd, 1, 4);
|
||||
int beginID=(1 << (unfilledLevel + 1)) - 2;
|
||||
for (int i=0;i<length; i++)
|
||||
{
|
||||
if (SCU.receiving(bData, CommInfo.blockSize)!=CommInfo.blockSize)
|
||||
System.out.println("wrong back data!");
|
||||
else{
|
||||
//System.out.println("write _id: "+(beginID+i)+" beginID: "+beginID);
|
||||
//store it in the database
|
||||
oram.writeBlock(partition, beginID+i, bData, 0);
|
||||
}
|
||||
}
|
||||
|
||||
SCU.disConnect();
|
||||
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
private void readSocketLongData(DataInputStream in, int dataLen, byte[] ids)
|
||||
throws IOException {
|
||||
if (dataLen<512){
|
||||
if (in.read(ids, 0, dataLen)!=dataLen)
|
||||
System.out.println("ids Error!!!");
|
||||
}else{
|
||||
int num = dataLen / 512 ;
|
||||
int leftLen = dataLen % 512;
|
||||
int hasRead = 0;
|
||||
for (int i=0;i<num;i++)
|
||||
{
|
||||
|
||||
if (in.read(ids, hasRead, 512)!=512)
|
||||
System.out.println("noticeWriteCloud 512 Error!!!");
|
||||
hasRead += 512;
|
||||
}
|
||||
if (leftLen>0){
|
||||
if (in.read(ids, hasRead, leftLen)!=leftLen)
|
||||
System.out.println("noticeWriteCloud leftLen Error!!!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void readCloud(DataOutputStream out, DataInputStream in)
|
||||
throws IOException {
|
||||
/*********
|
||||
* P + ID
|
||||
* *********/
|
||||
// System.out.println("readCloud");
|
||||
|
||||
int p = Util.byteToInt(recvCmd, 1, 4);
|
||||
int len = Util.byteToInt(recvCmd, 5, 4); // the next length of all the
|
||||
// IDs
|
||||
//System.out.println("readCloud p _id :" + p + " len: " + len);
|
||||
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
|
||||
if (len>0){
|
||||
byte[] ids = new byte[len * 4];
|
||||
|
||||
// read all the ids
|
||||
while (in.read(ids, 0, len * 4) > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < CommInfo.blockSize; i++)
|
||||
bData[i] = 0;
|
||||
|
||||
byte[] bRnd = new byte[CommInfo.blockSize];
|
||||
for (int i = 0; i < len; i++) {
|
||||
int _id = Util.byteToInt(ids, i * 4, 4);
|
||||
if (_id == 0)
|
||||
System.out
|
||||
.println("readCloud :!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
oram.readBlock(p, _id, bRnd);
|
||||
for (int j = 0; j < CommInfo.blockSize; j++)
|
||||
bData[j] ^= bRnd[j];
|
||||
}
|
||||
}
|
||||
|
||||
out.writeByte(ResponseType.normalWithValue);
|
||||
out.flush();
|
||||
out.write(bData, 0, CommInfo.blockSize);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package nankai.oram.server.mcloud;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
public class SessionManager {
|
||||
public static SessionManager instance;
|
||||
|
||||
public Vector objects ;
|
||||
public synchronized static SessionManager getInstance()
|
||||
{
|
||||
if (instance==null)
|
||||
instance=new SessionManager();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private SessionManager()
|
||||
{
|
||||
objects = new Vector();
|
||||
}
|
||||
|
||||
public synchronized SessionObject getObject(byte[] sessionID)
|
||||
{
|
||||
SessionObject obj = null;
|
||||
int size = objects.size();
|
||||
for (int i=0; i<size; i++)
|
||||
{
|
||||
obj = (SessionObject) objects.get(i);
|
||||
if (obj.isEqual(sessionID) )
|
||||
return obj;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized void addObject(SessionObject obj)
|
||||
{
|
||||
objects.add(obj);
|
||||
//System.out.println("2. add --------------------size: "+objects.size());
|
||||
}
|
||||
public synchronized void removeObject(SessionObject obj)
|
||||
{
|
||||
objects.remove(obj);
|
||||
//System.out.println("4. remove -----------------size: "+objects.size());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package nankai.oram.server.mcloud;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import nankai.oram.client.mCloud.MCloudCommInfo;
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.SymmetricCypto;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class SessionObject {
|
||||
|
||||
public byte[] sessionID;
|
||||
public byte[] levels;
|
||||
public int idsLen = 0;
|
||||
byte[][] shffule;
|
||||
public int filledLevelLength;
|
||||
public SecretKey key[];
|
||||
public int unfilledLevel;
|
||||
SecretKey sfk; //onion level key and shuffle key
|
||||
SymmetricCypto scp;
|
||||
|
||||
int bPos =0;
|
||||
|
||||
public SessionObject(byte[] sid)
|
||||
{
|
||||
scp =new SymmetricCypto(CommInfo.keySize);
|
||||
//System.out.print("2. add session ");
|
||||
sessionID = new byte[8];
|
||||
for(int i=0;i<8;i++){
|
||||
//System.out.print(sid[i]+" ");
|
||||
sessionID[i]=sid[i];
|
||||
}
|
||||
//System.out.println();
|
||||
}
|
||||
|
||||
public void setLevels(byte[] ls, int len)
|
||||
{
|
||||
if (ls!=null)
|
||||
;//System.out.println("has received IDs and levels Data!!");
|
||||
idsLen=len;
|
||||
levels=new byte[idsLen];
|
||||
System.arraycopy(ls, 0, levels, 0, len);
|
||||
}
|
||||
|
||||
public boolean isEqual(byte[] sid)
|
||||
{
|
||||
for(int i=0;i<8;i++)
|
||||
{
|
||||
if (sessionID[i]!=sid[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void createShuffle(int filledLevelLength)
|
||||
{
|
||||
this.filledLevelLength = filledLevelLength;
|
||||
shffule=new byte[filledLevelLength][CommInfo.blockSize];
|
||||
bPos = 0;
|
||||
}
|
||||
|
||||
public void createkey(int unfilledLevel)
|
||||
{
|
||||
this.unfilledLevel = unfilledLevel;
|
||||
key = new SecretKey[unfilledLevel+1];
|
||||
}
|
||||
|
||||
public void setKey(int level, byte[] bdata)
|
||||
{
|
||||
key[level] = new SecretKeySpec(bdata, "AES");
|
||||
}
|
||||
|
||||
public void setSFKey( byte[] bdata)
|
||||
{
|
||||
|
||||
// System.out.print("setSFKey " );
|
||||
// for (int i=0;i<6;i++)
|
||||
// System.out.print ( bdata[i]+" " );
|
||||
// System.out.println( );
|
||||
|
||||
sfk = new SecretKeySpec(bdata, "AES");
|
||||
}
|
||||
|
||||
public void setBlockData(int pos, byte[] bdata)
|
||||
{
|
||||
bPos++;
|
||||
System.arraycopy(bdata, 0, shffule[pos], 0, CommInfo.blockSize);
|
||||
}
|
||||
|
||||
public void setBlockData( byte[] bdata)
|
||||
{
|
||||
System.arraycopy(bdata, 0, shffule[bPos++], 0, CommInfo.blockSize);
|
||||
}
|
||||
public void setBlockDataWithOnionDecryption(int pos, byte[] bdata, int level)
|
||||
{
|
||||
// System.out.println("shuffleData: onion decryption: -> level:"+level+" pos:"+pos);
|
||||
// scp.initDec(key[level], null);
|
||||
// scp.enc_decData(bdata, CommInfo.blockSize);
|
||||
|
||||
System.arraycopy(bdata, 0, shffule[pos], 0, CommInfo.blockSize);
|
||||
}
|
||||
|
||||
public void psuedo_random_permute() {
|
||||
byte[] bData = new byte[CommInfo.blockSize];
|
||||
|
||||
|
||||
// for (int i = 0; i < filledLevelLength; i++) {
|
||||
// System.out.println("i: "+i+" "+shffule[i][0]);
|
||||
// }
|
||||
|
||||
for (int i = 0; i <filledLevelLength; i++) {
|
||||
|
||||
int j = Util.fpeForPermution(i, sfk, filledLevelLength);
|
||||
System.arraycopy(shffule[i], 0, bData, 0, CommInfo.blockSize);
|
||||
System.arraycopy(shffule[j], 0, shffule[i], 0, CommInfo.blockSize);
|
||||
System.arraycopy(bData, 0, shffule[j], 0, CommInfo.blockSize);
|
||||
|
||||
// System.out.println("permute: "+i+" "+j);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void onionEncryption() {
|
||||
// for (int i = 0; i <filledLevelLength; i++) {
|
||||
// scp.initEnc(sfk, null);
|
||||
// scp.enc_decData(shffule[i], CommInfo.blockSize);
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
package nankai.oram.server.partition;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import org.bson.Document;
|
||||
|
||||
import com.mongodb.client.FindIterable;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoCursor;
|
||||
import com.mongodb.client.model.Filters;
|
||||
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.MongDBUtil;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class PartitionORAMServer {
|
||||
public static PartitionORAMServer instance;
|
||||
boolean initFlag;
|
||||
int n_partitions;
|
||||
int n_capacity;//the max capacity of a partition -- need the top level
|
||||
public MongDBUtil dbUtil;
|
||||
byte[] bBlockData;
|
||||
|
||||
private PartitionORAMServer()
|
||||
{
|
||||
bBlockData=new byte[CommInfo.blockSize];
|
||||
initFlag=false;
|
||||
dbUtil=new MongDBUtil();
|
||||
dbUtil.connect("localhost", 27017);
|
||||
}
|
||||
public static PartitionORAMServer getInstance()
|
||||
{
|
||||
if (instance==null)
|
||||
instance=new PartitionORAMServer();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public boolean openDB()
|
||||
{
|
||||
if (!dbUtil.openDB("PartitionORAM"))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* This function will create the database for the ORAM
|
||||
*/
|
||||
public boolean init(int nN)
|
||||
{
|
||||
if (initFlag)
|
||||
return false;
|
||||
n_partitions = (int) Math.ceil(Math.sqrt(nN));
|
||||
int n_realBlocks_p = (int) Math.ceil(((double) nN) / n_partitions);
|
||||
|
||||
n_capacity = (int) Math.ceil(CommInfo.capacity_parameter * n_realBlocks_p);
|
||||
|
||||
//Create DB and open DB
|
||||
if (!dbUtil.createDB("PartitionORAM"))
|
||||
return false;
|
||||
//init partitions: create the table/collection for the partitions
|
||||
try {
|
||||
initPartitions();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// TODO ×Ô¶¯Éú³ÉµÄ catch ¿é
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
initFlag=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean writeBlock(int p, int _id, byte[] blockData, int pos) throws UnsupportedEncodingException
|
||||
{
|
||||
System.arraycopy(blockData, pos, bBlockData, 0, CommInfo.blockSize);
|
||||
|
||||
MongoCollection<Document> collection = dbUtil.getCollection("part_"+p);
|
||||
|
||||
String str=new String(bBlockData, "ISO-8859-1");
|
||||
|
||||
collection.findOneAndReplace(new Document("_id", _id), new Document("_id", _id).append("data", str));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public boolean readBlock(int p, int _id, byte[] receiveData) throws UnsupportedEncodingException {
|
||||
MongoCollection<Document> collection = dbUtil
|
||||
.getCollection("part_" + p);
|
||||
// Find the data and return them
|
||||
|
||||
FindIterable<Document> findIterable = collection.find(new Document(
|
||||
"_id", _id));
|
||||
MongoCursor<Document> mongoCursor = findIterable.iterator();
|
||||
if (mongoCursor.hasNext()) {
|
||||
Document doc1 = mongoCursor.next();
|
||||
|
||||
String bData = (String) doc1.get("data");
|
||||
|
||||
byte[] bs = bData.getBytes("ISO-8859-1");
|
||||
|
||||
System.arraycopy(bs, 0, receiveData, 0, CommInfo.blockSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void initPartitions() throws UnsupportedEncodingException
|
||||
{
|
||||
int i=0;
|
||||
for (i=0;i<n_partitions;i++)
|
||||
{
|
||||
dbUtil.createCollection("part_"+i);
|
||||
|
||||
//insert all the data records into the collection
|
||||
|
||||
MongoCollection<Document> collection = dbUtil.getCollection("part_"+i);
|
||||
//Each level, there are max 2^i real blocks, but more than 2^i dummy blocks
|
||||
for (int j = 0; j < n_capacity; j++) {
|
||||
/*collection.insertOne(new Document("_id", j).append("data",
|
||||
new String(bBlockData, "ISO-8859-1")));*/
|
||||
collection.insertOne(new Document("_id", j).append("data",
|
||||
bBlockData ));
|
||||
}
|
||||
/***************************************
|
||||
* Each level, there are 2^(i+1) blocks
|
||||
* ***********************************/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
package nankai.oram.server.partition;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
import nankai.oram.common.CommInfo;
|
||||
import nankai.oram.common.CommandType;
|
||||
import nankai.oram.common.ResponseType;
|
||||
import nankai.oram.common.Util;
|
||||
|
||||
public class PartitionServerThread extends Thread {
|
||||
|
||||
|
||||
Socket socket = null; // 保存与本线程相关的Socket对象
|
||||
byte recvCmd[];
|
||||
byte recvMsg[];
|
||||
byte sendMsg[];
|
||||
PartitionORAMServer oram;
|
||||
|
||||
public PartitionServerThread(Socket socket) {
|
||||
this.socket = socket;
|
||||
recvCmd=new byte[13];
|
||||
recvMsg=new byte[10240];
|
||||
sendMsg=new byte[10240];
|
||||
oram=PartitionORAMServer.getInstance();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
DataInputStream in=null;
|
||||
DataOutputStream out=null;
|
||||
try {
|
||||
|
||||
in=new DataInputStream(socket.getInputStream());
|
||||
out=new DataOutputStream(socket.getOutputStream());
|
||||
|
||||
// 由Socket对象得到输出流,并构造PrintWriter对象
|
||||
byte type=0;
|
||||
int len=0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
type=0;
|
||||
len=0;
|
||||
while ( (len = in.read(recvCmd, 0, 13)) >0) {
|
||||
type = recvCmd[0];
|
||||
// System.out.println("-----------------------------------------------------------");
|
||||
// System.out.println("receive a command type:"+ type+" "+ recvCmd[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (type == CommandType.closeThread)
|
||||
break;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CommandType.openDB:
|
||||
{
|
||||
System.out.println("open DB");
|
||||
if (oram.openDB()==false)
|
||||
System.out.println("open DB ERROR");
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
|
||||
break;
|
||||
}
|
||||
case CommandType.testTime:
|
||||
{
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
break;
|
||||
}
|
||||
case CommandType.initORAM:
|
||||
{
|
||||
if (len!=5){
|
||||
// System.out.println("initORAM error data! " + len);
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
}else
|
||||
initORAM(out);
|
||||
break;
|
||||
}
|
||||
case CommandType.readBlock:
|
||||
{
|
||||
if (len != 9) {
|
||||
System.out.println("readBlock error data! " + len);
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else {
|
||||
/**************************************
|
||||
* partition+_id
|
||||
* **********************************/
|
||||
readBlock(out);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CommandType.writeBlock:
|
||||
{
|
||||
if (len != 13) {
|
||||
System.out.println("writeBlock error data! " + len);
|
||||
|
||||
for (int i=0;i<len;i++)
|
||||
System.out.print(recvCmd[i]+" ");
|
||||
System.out.println();
|
||||
|
||||
while (in.read(recvMsg, 0, 10240) > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i=0;i<3;i++)
|
||||
System.out.print(recvMsg[i]+" ");
|
||||
System.out.println();
|
||||
|
||||
out.writeByte(ResponseType.wrong);
|
||||
out.flush();
|
||||
} else {
|
||||
while (in.read(recvMsg, 0, 10240) > 0) {
|
||||
break;
|
||||
}
|
||||
/**************************************
|
||||
* partition+_id+length+block
|
||||
* **********************************/
|
||||
writeBlock(out);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error.?>>>>> " + e);
|
||||
e.printStackTrace();
|
||||
}finally{
|
||||
try {
|
||||
out.close(); // 关闭Socket输出流
|
||||
in.close();// 关闭Socket输入流
|
||||
socket.close(); // 关闭Socket
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
System.out.println("closing........ ");
|
||||
}
|
||||
}
|
||||
|
||||
private void initORAM(DataOutputStream out) throws IOException {
|
||||
/*********
|
||||
* LEN = 4, N value
|
||||
* *********/
|
||||
// System.out.println("init oram");
|
||||
|
||||
int N = Util.byteToInt(recvCmd, 1, 4);
|
||||
// System.out.println("init N blocks:" + N);
|
||||
oram.init(N);
|
||||
|
||||
// System.out.println("init OK.");
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
private void readBlock(DataOutputStream out ) throws IOException {
|
||||
/*********
|
||||
* P + ID
|
||||
* *********/
|
||||
//System.out.println("readBlock");
|
||||
|
||||
int p = Util.byteToInt(recvCmd, 1, 4);
|
||||
int _id = Util.byteToInt(recvCmd, 5, 4);
|
||||
//System.out.println("p _id :" + p + " " + _id );
|
||||
|
||||
oram.readBlock(p, _id, sendMsg);
|
||||
|
||||
out.writeByte(ResponseType.normalWithValue);
|
||||
out.flush();
|
||||
out.write(sendMsg, 0, CommInfo.blockSize);
|
||||
//System.out.println("return back data:" + sendMsg[0]+" " +sendMsg[5]);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
private void writeBlock(DataOutputStream out ) throws IOException {
|
||||
|
||||
//System.out.println("writeBlock");
|
||||
|
||||
int p = Util.byteToInt(recvCmd, 1, 4);
|
||||
int _id = Util.byteToInt(recvCmd, 5, 4);
|
||||
int len = Util.byteToInt(recvCmd, 9, 4);
|
||||
//System.out.println("p _id len:" + p + " " + _id + " "
|
||||
// + len);
|
||||
//System.out.println(recvMsg[0]+" "+recvMsg[1]+"........");
|
||||
if (len!=CommInfo.blockSize)
|
||||
System.out.println("Error Length");
|
||||
|
||||
oram.writeBlock(p, _id, recvMsg, 0);
|
||||
|
||||
//System.out.println("write OK.");
|
||||
out.writeByte(ResponseType.normal);
|
||||
out.flush();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue