
org.factcenter.pathORam.PathORamDriver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of inchworm Show documentation
Show all versions of inchworm Show documentation
Secure computation, one step at a time.
The newest version!
package org.factcenter.pathORam;
import org.factcenter.inchworm.Converters;
import org.factcenter.qilin.util.BitMatrix;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
public class PathORamDriver extends BlockStorageBase {
/**
* Objects the implements the PathORam "remote" storage. It's the external
* memory access to which seem random for external viewer
*/
protected final PathORamServer server;
/**
* Source of randomness
*/
protected Random random;
protected PositionMap positionMap;
protected Stash stash;
protected Logger logger;
public PathORamDriver(PathORamServer server, Random random,
PositionMap positionMap, Stash stash) {
super(server.getBlockSize(), server.getBlocksCount());
this.server = server;
this.random = random;
this.positionMap = positionMap;
this.stash = stash;
this.logger = LoggerFactory.getLogger(getClass());
}
protected enum Method {
READ, WRITE;
}
@Override
public void storeBlock(Block block) {
checkInput(block.getId(), block.getData());
access(Method.WRITE, block);
}
/**
* Asserts that the giver input is in the bounds of the underlying storage
*/
public void checkInput(int blockIndex, BitMatrix blockData) {
if (blockData.getNumCols() != getBlockSizeBits()){
throw new IllegalArgumentException("Wrong blockSize. Expected " + getBlockSizeBits() + " got " + blockData.getNumCols());
}
if (blockIndex < 0 || blockIndex > getBlockCount()) {
throw new IllegalArgumentException("Wrong index " + blockIndex);
}
}
@Override
public Block fetchBlock(int blockIndex) {
checkInput(blockIndex, new BitMatrix(getBlockSizeBits()));
// just passing block index to access. a bit ugly but allows to write the code as close the
// pseudo code in the paper as possible
return access(Method.READ, Block.create(blockIndex, null, false));
}
/**
* The access method as described in the paper
*
* @param operation
* READ/WRITE opcode
* @param block
* Block to write / read. (data will be null if operation is READ)
* @return The data read
* Note: One should use the exposed store/fetch methods
*/
public Block access(Method operation, Block block) {
int index = block.getId();
BitMatrix data = block.getData();
logger.debug("PathORamDriver.access: operationd = {} index={} data={} pathORamSize={} blockSize={}",
operation.toString(),
index,
null != data ? Converters.toHexString(data.getPackedBits(false)) : "null",
server.getBlocksCount(),
server.getBlockSize());
// lines 1-2 from the paper. This might be a recursive call to a smaller PathORam
int oldPosition = positionMap.updatePosition(index);
logger.debug("PathORamDriver.access oldPosition={} index={} pathORamSize={}", oldPosition, index, server.getBlocksCount());
Block readData = null;
// lines 3-5
List allBlocks = readPathToRoot(oldPosition);
fillStash(allBlocks);
// lines 6-9
readData = stash.fetchBlock(index);
if (Method.WRITE == operation) {
logger.debug("PathORam.access going to store in stash our block (WRITE)");
stash.storeBlock(block);
}
logger.debug("PathORamDriver.access before popping buckets " + stash.getBlockCount());
// lines 10-15
Map path = stash.popBucket(oldPosition, positionMap, server.getBucketSize());
for (int level : path.keySet()){
server.writeBucket(oldPosition, level, path.get(level));
}
logger.debug("PathORamDriver.access after popping buckets " + stash.getBlockCount());
// line 16
return readData;
}
/**
* Read all blocks that reside on the path from node number oldPosition to
* the root of the tree
*/
public List readPathToRoot(int oldPosition) {
List allBlockInPath = new LinkedList();
for (int level = server.getTreeHeight(); level >= 0; level--) {
Bucket bucket = server.readBucket(oldPosition, level);
for (Block block : bucket.getBlocks()) {
//if (block.getValidBit()) {
allBlockInPath.add(block);
//}
}
}
return allBlockInPath;
}
// /**
// * @return if the block is dummy
// */
// public boolean isBlockDummy(Block block) {
// return Block.isDummyId(block.getId());
// }
/**
* This method fills the implemented in subclass stash with the blocks read
* from storage
*/
public void fillStash(List allBlocks) {
for (Block block : allBlocks){
stash.storeBlock(block);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy