This commit is contained in:
emigranteMuse 2017-03-06 19:16:22 +08:00
commit 40f771b724
48 changed files with 7373 additions and 0 deletions

8
.classpath Normal file
View File

@ -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>

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/bin/

17
.project Normal file
View File

@ -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>

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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("ÉÐδʵÏÖ");
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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};
}

View File

@ -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;
}
}

View File

@ -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];
}
}
}

View File

@ -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;
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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);
}
}

View File

@ -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
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}
}

View File

@ -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();
// }
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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........ ");
}
}
}

View File

@ -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();
}
}

View File

@ -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
* ***********************************/
}
}
}

View File

@ -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);
}
}
}

View File

@ -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
* ***********************************/
}
}
}

View File

@ -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();
}
}

View File

@ -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());
}
}

View File

@ -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);
// }
}
}

View File

@ -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
* ***********************************/
}
}
}

View File

@ -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();
}
}