Commit 86124779 authored by Jack Doerner's avatar Jack Doerner

Yuval Ishai suggested this optimization for Floram reads.

parent bb457cae
......@@ -178,15 +178,21 @@ void bitpropagator_getblockvector_with_callback(obliv uint8_t * activeblock_delt
printf("END FSS SETUP %lld\n", current_timestamp());
#endif
bitpropagator_offline_start(bp->bpo, bp->toplevel_local);
bp->readycount = 0;
if (bp->endlevel > bp->startlevel) {
bitpropagator_offline_start(bp->bpo, bp->toplevel_local);
bp->readycount = 0;
#ifdef _OPENMP
//This is a hack to work around the fact that openmp and obliv-c are incompatible.
bitpropagator_offline_parallelizer(bp, bp->bpo, &index, local_output, local_bit_output, bp->pd2, bitpropagator_traverselevels, bitpropagator_Z_pusher, cbfn, cbpass);
//This is a hack to work around the fact that openmp and obliv-c are incompatible.
bitpropagator_offline_parallelizer(bp, bp->bpo, &index, local_output, local_bit_output, bp->pd2, bitpropagator_traverselevels, bitpropagator_Z_pusher, cbfn, cbpass);
#else
bitpropagator_offline_parallelizer(bp, bp->bpo, &index, local_output, local_bit_output, NULL, bitpropagator_traverselevels, bitpropagator_Z_pusher, cbfn, cbpass);
bitpropagator_offline_parallelizer(bp, bp->bpo, &index, local_output, local_bit_output, NULL, bitpropagator_traverselevels, bitpropagator_Z_pusher, cbfn, cbpass);
#endif
} else if (*cbfn!=NULL) {
cbfn(cbpass, NULL);
memcpy(local_output, bp->toplevel_local, (1ll << bp->startlevel) * BLOCKSIZE);
for (size_t ii = 0; ii < (1ll << bp->startlevel); ii++) local_bit_output[ii] = bp->toplevel_local[ii * BLOCKSIZE] & 1;
}
//write output
ocCopyN(&ocCopyChar, activeblock_delta, bp->activeblock_A, BLOCKSIZE*bp->blockmultiple);
......
......@@ -77,6 +77,12 @@ void bitpropagator_cprg_offline_start(uint8_t * local_output, bool * local_bit_o
bpo->lba[0] = bpo->lda2[0] & 1;
if (bpo->thislevel == bpo->endlevel) {
memcpy(bpo->ldb, bpo->lda, BLOCKSIZE*bpo->blockmultiple);
memcpy(accumulator_L, bpo->lda, BLOCKSIZE*bpo->blockmultiple);
memcpy(bpo->lbb, bpo->lba, sizeof(bool));
}
#ifdef ORAM_PROFILE_SCHEDULING
printf("END FSS CPRG OFFLINE LEVEL %d %lld\n", bpo->thislevel,current_timestamp());
#endif
......
......@@ -14,6 +14,7 @@ struct floram {
scanwrom* wrom;
scanrom* rom;
void* bitpropagator;
void* bitpropagator_smaller;
obliv uint8_t* stash;
obliv int32_t* stashi;
obliv uint8_t* activeblock_delta;
......@@ -137,10 +138,10 @@ void floram_read(void* data, floram* ram, obliv size_t index) obliv {
facb_pass facb_data = {.ram=ram, .blockid = blockid, .subblockid = subblockid, .found = false};
~obliv() ram->bgbc(ram->activeblock_delta, ram->blockvector_local, ram->bitvector_local, ram->bitpropagator, blockid, floram_scan_callback_ro, &facb_data);
~obliv() ram->bgbc(ram->activeblock_delta, ram->blockvector_local, ram->bitvector_local, ram->bitpropagator_smaller, blockid/(BLOCKSIZE*8), floram_scan_callback_ro, &facb_data);
obliv if (facb_data.found == false) {
scanrom_read_with_bitvector(ram->stash, ram->rom, blockid, ram->bitvector_local);
scanrom_read_with_blockvector(ram->stash, ram->rom, blockid, ram->activeblock_delta, ram->blockvector_local, ram->bitvector_local);
}
ram->stashi[0] = -1;
......@@ -261,11 +262,13 @@ floram* floram_new(OcCopy* cpy, void* data, size_t n, bool cprg, bool from_share
ram->bgbc = bitpropagator_cprg_getblockvector_with_callback;
ram->bf = bitpropagator_cprg_free;
ram->bitpropagator = bitpropagator_cprg_new(ram->blockcount, ram->blockmultiple);
ram->bitpropagator_smaller = bitpropagator_cprg_new((ram->blockcount+(BLOCKSIZE*8)-1)/(BLOCKSIZE*8), 1);
} else {
ram->bgb = bitpropagator_getblockvector;
ram->bgbc = bitpropagator_getblockvector_with_callback;
ram->bf = bitpropagator_free;
ram->bitpropagator = bitpropagator_new(ram->blockcount, ram->blockmultiple, MIN(5, LOG2LL(ram->blockcount)));
ram->bitpropagator_smaller = bitpropagator_new((ram->blockcount+(BLOCKSIZE*8)-1)/(BLOCKSIZE*8), 1, MIN(5, LOG2LL((ram->blockcount+(BLOCKSIZE*8)-1)/(BLOCKSIZE*8))));
}
floram_pma(&ram->blockvector_local, 16, ram->blockcount * ram->memblocksize);
......@@ -343,6 +346,7 @@ floram* floram_new(OcCopy* cpy, void* data, size_t n, bool cprg, bool from_share
void floram_free(floram* ram) {
ram->bf(ram->bitpropagator);
ram->bf(ram->bitpropagator_smaller);
scanrom_free(ram->rom);
scanwrom_free(ram->wrom);
free(ram->blocktemp);
......
......@@ -2,11 +2,11 @@
#include "floram_util.h"
void scanrom_read_with_bitvector_offline(uint8_t * data, uint8_t * local_data, bool * bitvector, size_t memblocksize, size_t blockcount) {
memset(data, 0, memblocksize);
void scanrom_read_with_bitvector_offline(uint8_t * output_share, uint8_t * rom_memory, bool * bitvector, size_t memblocksize, size_t blockcount) {
memset(output_share, 0, memblocksize);
uint64_t * d = local_data;
bool * b = bitvector;
uint64_t * rm = rom_memory;
bool * biv = bitvector;
uint64_t ** sums;
size_t threadcount;
......@@ -25,16 +25,59 @@ void scanrom_read_with_bitvector_offline(uint8_t * data, uint8_t * local_data, b
#pragma omp for schedule(guided)
for (size_t ii = 0; ii < blockcount; ii++) {
#pragma omp simd aligned(d,b,s:16)
#pragma omp simd aligned(rm,biv,s:16)
for (size_t jj = 0; jj < memblocksize /sizeof(uint64_t); jj++) {
s[jj] ^= b[ii] * d[ii * ((memblocksize) /sizeof(uint64_t)) + jj];
s[jj] ^= biv[ii] * rm[ii * ((memblocksize) /sizeof(uint64_t)) + jj];
}
}
}
for (size_t ii = 0; ii < threadcount; ii++) {
for (size_t jj = 0; jj < memblocksize /sizeof(uint64_t); jj++) {
((uint64_t *)data)[jj] ^= sums[ii][jj];
((uint64_t *)output_share)[jj] ^= sums[ii][jj];
}
free(sums[ii]);
}
free(sums);
}
void scanrom_read_with_blockvector_offline(uint8_t * z_and_output, uint8_t * rom_memory, bool * bitvector, uint8_t * blockvector, size_t memblocksize, size_t blockcount) {
uint64_t * rm = rom_memory;
uint64_t ** sums;
size_t threadcount;
floram_set_procs_for_data_size(memblocksize * blockcount);
#pragma omp parallel
{
threadcount = omp_get_num_threads();
#pragma omp single
sums = malloc(threadcount * sizeof(uint64_t *));
uint64_t * s;
floram_zpma(&s, 16, memblocksize);
sums[omp_get_thread_num()] = s;
#pragma omp for schedule(guided)
for (size_t ii = 0; ii < blockcount; ii++) {
bool bitvector_bit = bitvector[ii/(BLOCKSIZE * 8)];
uint8_t z_block_part = z_and_output[(ii%(BLOCKSIZE*8))/8];
uint8_t * blockvector_block = &blockvector[(ii/(BLOCKSIZE * 8))*BLOCKSIZE];
uint8_t blockvector_block_part = blockvector_block[(ii%(BLOCKSIZE*8))/8];
bool b_temp = (((bitvector_bit * z_block_part) ^ blockvector_block_part) >> (ii % 8)) & 0x1;
#pragma omp simd aligned(rm,s:16)
for (size_t jj = 0; jj < memblocksize /sizeof(uint64_t); jj++) {
s[jj] ^= b_temp * rm[ii * memblocksize/sizeof(uint64_t) + jj];
}
}
}
memset(z_and_output, 0, memblocksize);
for (size_t ii = 0; ii < threadcount; ii++) {
for (size_t jj = 0; jj < memblocksize /sizeof(uint64_t); jj++) {
((uint64_t *)z_and_output)[jj] ^= sums[ii][jj];
}
free(sums[ii]);
}
......@@ -63,17 +106,18 @@ void scanrom_encrypt_offline(uint8_t * out, uint8_t * in, uint8_t* key, size_t i
}
#endif
void scanwrom_write_with_blockvector_offline(uint8_t * local_data, uint8_t * blockvector, bool * bitvector, uint8_t*Zblock, size_t memblocksize, size_t blockcount) {
uint64_t * d = local_data;
uint64_t * b = blockvector;
uint64_t * z = Zblock;
void scanwrom_write_with_blockvector_offline(uint8_t * wrom_memory, uint8_t * blockvector, bool * bitvector, uint8_t*z_block, size_t memblocksize, size_t blockcount) {
uint64_t * wm = wrom_memory;
uint64_t * blv = blockvector;
bool * biv = bitvector;
uint64_t * z = z_block;
floram_set_procs_for_data_size(memblocksize * blockcount);
#pragma omp parallel for schedule(guided)
for (size_t ii = 0; ii< blockcount; ii++) {
#pragma omp simd aligned(d,b,bitvector,z:16)
#pragma omp simd aligned(wm,blv,biv,z:16)
for (size_t jj = 0; jj < memblocksize/sizeof(uint64_t); jj++) {
d[ii * memblocksize/sizeof(uint64_t) + jj] ^= b[ii * memblocksize/sizeof(uint64_t) + jj] ^ (bitvector[ii] * z[jj]);
wm[ii * memblocksize/sizeof(uint64_t) + jj] ^= blv[ii * memblocksize/sizeof(uint64_t) + jj] ^ (biv[ii] * z[jj]);
}
}
}
\ No newline at end of file
......@@ -4,10 +4,11 @@
typedef void (* duplexer_fn)(void *, void *);
void scanrom_read_with_bitvector_offline(uint8_t * data, uint8_t * local_data, bool * bitvector, size_t fullblocksize, size_t blockcount);
void scanrom_read_with_bitvector_offline(uint8_t * output_share, uint8_t * rom_memory, bool * bitvector, size_t memblocksize, size_t blockcount);
void scanrom_read_with_blockvector_offline(uint8_t * z_and_output, uint8_t * rom_memory, bool * bitvector, uint8_t * blockvector, size_t memblocksize, size_t blockcount);
void scanrom_encrypt_offline(uint8_t * out, uint8_t * in, uint8_t* key, size_t index, size_t blockmultiple, size_t blockcount);
void scanwrom_write_with_blockvector_offline(uint8_t * local_data, uint8_t * blockvector, bool * bitvector, uint8_t*Zblock, size_t memblocksize, size_t blockcount);
void scanwrom_write_with_blockvector_offline(uint8_t * wrom_memory, uint8_t * blockvector, bool * bitvector, uint8_t*z_block, size_t memblocksize, size_t blockcount);
#endif
\ No newline at end of file
......@@ -33,7 +33,7 @@ struct scanwrom {
void scanrom_read_with_bitvector(obliv uint8_t * data, scanrom * rom, obliv size_t index, bool * bitvector) obliv {
void scanrom_read_with_bitvector(obliv uint8_t * data_output, scanrom * rom, obliv size_t index, bool * bitvector) obliv {
#ifdef ORAM_PROFILE_SCHEDULING
~obliv() printf("BEGIN ROM READ %lld\n", current_timestamp());
#endif
......@@ -66,7 +66,66 @@ void scanrom_read_with_bitvector(obliv uint8_t * data, scanrom * rom, obliv size
#endif
}
ocCopyN(&ocCopyChar, data, rom->blocktemp, rom->memblocksize);
ocCopyN(&ocCopyChar, data_output, rom->blocktemp, rom->memblocksize);
#ifdef ORAM_PROFILE_SCHEDULING
~obliv() printf("END ROM READ %lld\n", current_timestamp());
#endif
}
/* the following function implements Yuval Ishai's suggested optimization for
truncating the last ayers of the FSS tree in the case of reading. We assume
that the blockvector is a factor of BLOCKSIZE smaller than it would be in
the usual case, and set both parties blockvectors to be equal except for a
single bit
*/
void scanrom_read_with_blockvector(obliv uint8_t * data_output, scanrom * rom, obliv size_t index, obliv uint8_t * activeblock_delta, uint8_t * blockvector, bool * bitvector) obliv {
#ifdef ORAM_PROFILE_SCHEDULING
~obliv() printf("BEGIN ROM READ %lld\n", current_timestamp());
#endif
~obliv(en) {
memset(rom->blocktemp, 0, BLOCKSIZE*sizeof(obliv uint8_t));
obliv size_t index_maj = ((index % (BLOCKSIZE*8)) >> 3);
obliv size_t index_min = ((index % (BLOCKSIZE*8)) & 0x7);
for (size_t ii = 0; ii < BLOCKSIZE; ii++) {
rom->blocktemp[ii] = activeblock_delta[ii];
for (size_t jj = 0; jj < 8; jj++) {
obliv if ((ii == index_maj) & (jj == index_min)) ((obliv bool *) &rom->blocktemp[ii])[jj] ^= 1;
}
}
for (size_t ii = 0; ii < BLOCKSIZE/sizeof(uint64_t); ii++) revealOblivLLong(&((uint64_t *)rom->local_blocktemp)[ii], ((obliv uint64_t *)rom->blocktemp)[ii], 2);
for (size_t ii = 0; ii < BLOCKSIZE/sizeof(uint64_t); ii++) revealOblivLLong(&((uint64_t *)rom->local_blocktemp)[ii], ((obliv uint64_t *)rom->blocktemp)[ii], 1);
scanrom_read_with_blockvector_offline(rom->local_blocktemp, rom->local_data, bitvector, blockvector, rom->memblocksize, rom->blockcount);
memset(rom->ivtemp, 0, BLOCKSIZE * sizeof(obliv uint8_t));
ocFromSharedCharN(ocCurrentProto(), rom->blocktemp, rom->local_blocktemp, rom->memblocksize);
#ifndef SCANROM_DISABLE_ENCRYPTION
#ifdef ORAM_PROFILE_SCHEDULING
printf("BEGIN ROM DECRYPT %lld\n", current_timestamp());
#endif
for (size_t ii = 0; ii < rom->memblocksize/BLOCKSIZE; ii += 1) {
be64enc(&rom->ivtemp[BLOCKSIZE - sizeof(size_t)], index*rom->blockmultiple + ii);
oaes_128_from_expanded_double(&rom->blocktemp[rom->memblocksize + ii*BLOCKSIZE], &rom->blocktemp[2*rom->memblocksize + ii*BLOCKSIZE],
rom->halfkey_a, rom->halfkey_b, rom->ivtemp, rom->ivtemp);
}
for (size_t ii = 0; ii < rom->memblocksize; ii ++) {
rom->blocktemp[ii] ^= rom->blocktemp[rom->memblocksize + ii] ^ rom->blocktemp[2*rom->memblocksize + ii];
}
#ifdef ORAM_PROFILE_SCHEDULING
printf("END ROM DECRYPT %lld\n", current_timestamp());
#endif
#endif
}
ocCopyN(&ocCopyChar, data_output, rom->blocktemp, rom->memblocksize);
#ifdef ORAM_PROFILE_SCHEDULING
~obliv() printf("END ROM READ %lld\n", current_timestamp());
......
......@@ -5,7 +5,8 @@
typedef struct scanrom scanrom;
typedef struct scanwrom scanwrom;
void scanrom_read_with_bitvector(obliv uint8_t * data, scanrom * rom, obliv size_t index, bool * bitvector) obliv;
void scanrom_read_with_bitvector(obliv uint8_t * data_output, scanrom * rom, obliv size_t index, bool * bitvector) obliv;
void scanrom_read_with_blockvector(obliv uint8_t * data_output, scanrom * rom, obliv size_t index, obliv uint8_t * activeblock_delta, uint8_t * blockvector, bool * bitvector) obliv;
void scanrom_read(obliv uint8_t * data, scanrom* rom, size_t index);
void scanrom_write_xor_shares(scanrom* rom, obliv uint8_t * data, size_t index, size_t len);
void scanrom_set_key(scanrom* rom, uint8_t* key_local);
......@@ -16,7 +17,7 @@ void scanrom_clear(scanrom* rom);
scanrom* scanrom_new(size_t memblocksize, size_t n, void* key_local);
void scanrom_free(scanrom* rom);
void scanwrom_write_with_blockvector(scanwrom* rom, obliv uint8_t * active_block_pair, uint8_t * blockvector, bool* bitvector, obliv uint8_t * old_data, obliv uint8_t * new_data) obliv;
void scanwrom_write_with_blockvector(scanwrom* rom, obliv uint8_t * active_block_delta, uint8_t * blockvector, bool * bitvector, obliv uint8_t * old_data, obliv uint8_t * new_data) obliv;
void scanwrom_read(obliv uint8_t* data, scanwrom* rom, size_t index);
void scanwrom_write(scanwrom* rom, obliv uint8_t* data, size_t index);
void scanwrom_read_xor_shares(uint8_t * data, scanwrom* rom, size_t index, size_t len);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment