123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263 |
- #include "dpf.h"
- #include <openssl/rand.h>
- #include <omp.h>
- #include <time.h>
- uint128_t dpf_reverse_lsb(uint128_t input){
- uint128_t xor = 1;
- return input ^ xor;
- }
- uint128_t dpf_lsb(uint128_t input){
- return input & 1;
- }
- uint128_t dpf_set_lsb_zero(uint128_t input){
- int lsb = input & 1;
- if(lsb == 1){
- return dpf_reverse_lsb(input);
- }else{
- return input;
- }
- }
- void _output_bit_to_bit(uint128_t input){
- for(int i = 0; i < 64; i++)
- {
- if( (1ll << i) & input)
- printf("1");
- else
- printf("0");
- }
- }
- void print_block(uint128_t input) {
- uint64_t *val = (uint64_t *) &input;
- //printf("%016lx%016lx\n", val[0], val[1]);
- _output_bit_to_bit(val[0]);
- _output_bit_to_bit(val[1]);
- printf("\n");
- }
- uint128_t addModP(uint128_t in1, uint128_t in2){
- uint128_t out = in1 + in2;
- //if we wrapped around, add in the MODP
- if(out + MODP < in1 || out > 0-MODP){
- out += MODP;
- //printf("addModP wrapped\n");
- }
- return out;
- }
- uint128_t subModP(uint128_t in1, uint128_t in2){
- uint128_t out = in1 - in2;
- //if we wrapped around, subtract the MODP
- if(in2 > in1){
- out -= MODP;
- //printf("subModP wrapped\n");
- }
- //straight-line version?
- //out -= (in2 > in1) * MODP;
- return out;
- }
- //performance for this is really bad
- //but it gets _much_ better when compiled with -O2
- uint128_t multModP(uint128_t in1, uint128_t in2){
- uint128_t out = 0;
- uint128_t in1high = in1 >> 64;
- uint128_t in2high = in2 >> 64;
- uint128_t in1low = in1 & (uint128_t)0xffffffffffffffff;
- uint128_t in2low = in2 & (uint128_t)0xffffffffffffffff;
-
- //printf("\n");
- //print_block(in1high); printf("\n");
- //print_block(in2high); printf("\n");
- //print_block(in1low); printf("\n");
- //print_block(in2low); printf("\n");
- //printf("\n");
- uint128_t outlow = in1low * in2low;
- if(outlow + MODP < in1low || outlow + MODP < in2low|| outlow > 0-MODP) {
- outlow += MODP;
- //printf("mult wrap\n");
- }
-
- //print_block(outlow);
-
- uint128_t outhigh = in1high * in2high;
- uint128_t outmid1 = in1high*in2low;
- uint128_t outmid2 = in2high*in1low;
-
- //print_block(outhigh);
- //print_block(outmid1);
- //print_block(outmid2);
-
- //the low part gets the low order bits of the mids
- uint128_t outlow1 = addModP(outmid1 << 64, outmid2 << 64);
-
- //uint128_t outlow1 = ((outmid1 & (uint128_t)0xffffffffffffffff) + (outmid2 & (uint128_t)0xffffffffffffffff)) << 64;
- //if(outlow1 + MODP < ((outmid1 & (uint128_t)0xffffffffffffffff) << 64)) outlow1 += MODP;
-
- //print_block(outlow1);
-
- out = addModP(outlow, outlow1);
- //print_block(out);
-
- //multiply in the wrap for as many times as we wrapped
- uint128_t lowWraps = ((outmid1 >> 64) + (outmid2 >> 64)) * MODP;
- out = addModP(out, lowWraps);
-
- //print_block(lowWraps);
-
- //now we need to account for wraps caused by outhigh
- uint128_t outhighlow = (outhigh & (uint128_t)0xffffffffffffffff) * MODP;
- uint128_t outhighhigh = (outhigh >> 64) * MODP;
- uint128_t outhighhighlow = outhighhigh << 64;
- uint128_t outhighhighhigh = (outhighhigh >> 64) * MODP;
-
- //print_block(outhighlow);
- //print_block(outhighhigh);
- //print_block(outhighhighlow);
- //print_block(outhighhighhigh);
-
- out = addModP(out, addModP(outhighlow, addModP(outhighhighlow, outhighhighhigh)));
-
- //print_block(out);
- return out;
- }
- uint128_t getRandomBlock(){
- static uint8_t* randKey = NULL;//(uint8_t*) malloc(16);
- static EVP_CIPHER_CTX* randCtx;
- static uint128_t counter = 0;
-
- int len = 0;
- uint128_t output = 0;
- if(!randKey){
- randKey = (uint8_t*) malloc(16);
- if(!(randCtx = EVP_CIPHER_CTX_new()))
- printf("errors occured in creating context\n");
- if(!RAND_bytes(randKey, 16)){
- printf("failed to seed randomness\n");
- }
- if(1 != EVP_EncryptInit_ex(randCtx, EVP_aes_128_ecb(), NULL, randKey, NULL))
- printf("errors occured in randomness init\n");
- EVP_CIPHER_CTX_set_padding(randCtx, 0);
- }
-
- if(1 != EVP_EncryptUpdate(randCtx, (uint8_t*)&output, &len, (uint8_t*)&counter, 16))
- printf("errors occured in generating randomness\n");
- counter++;
- return output;
- }
- //this is the PRG used for the DPF
- void dpfPRG(EVP_CIPHER_CTX *ctx, uint128_t input, uint128_t* output1, uint128_t* output2, int* bit1, int* bit2){
-
- input = dpf_set_lsb_zero(input);
- int len = 0;
- uint128_t stashin[2];
- stashin[0] = input;
- stashin[1] = dpf_reverse_lsb(input);
- uint128_t stash[2];
- EVP_CIPHER_CTX_set_padding(ctx, 0);
- if(1 != EVP_EncryptUpdate(ctx, (uint8_t*)stash, &len, (uint8_t*)stashin, 32))
- printf("errors occured in encrypt\n");
- //no need to do this since we're working with exact multiples of the block size
- //if(1 != EVP_EncryptFinal_ex(ctx, stash + len, &len))
- // printf("errors occured in final\n");
-
- stash[0] = stash[0] ^ input;
- stash[1] = stash[1] ^ input;
- stash[1] = dpf_reverse_lsb(stash[1]);
- *bit1 = dpf_lsb(stash[0]);
- *bit2 = dpf_lsb(stash[1]);
- *output1 = dpf_set_lsb_zero(stash[0]);
- *output2 = dpf_set_lsb_zero(stash[1]);
- }
- static int getbit(uint128_t x, int n, int b){
- return ((uint128_t)(x) >> (n - b)) & 1;
- }
- void genDPF(EVP_CIPHER_CTX *ctx, int domainSize, uint128_t index, int dataSize, uint8_t* data, unsigned char** k0, unsigned char **k1){
- int maxLayer = domainSize;
-
- uint128_t s[maxLayer + 1][2];
- int t[maxLayer + 1 ][2];
- uint128_t sCW[maxLayer];
- int tCW[maxLayer][2];
-
- s[0][0] = getRandomBlock();
- s[0][1] = getRandomBlock();
- t[0][0] = 0;
- t[0][1] = 1;
-
- uint128_t s0[2], s1[2]; // 0=L,1=R
- int t0[2], t1[2];
- #define LEFT 0
- #define RIGHT 1
- for(int i = 1; i <= maxLayer; i++){
- dpfPRG(ctx, s[i-1][0], &s0[LEFT], &s0[RIGHT], &t0[LEFT], &t0[RIGHT]);
- dpfPRG(ctx, s[i-1][1], &s1[LEFT], &s1[RIGHT], &t1[LEFT], &t1[RIGHT]);
-
- int keep, lose;
- int indexBit = getbit(index, domainSize, i);
- if(indexBit == 0){
- keep = LEFT;
- lose = RIGHT;
- }else{
- keep = RIGHT;
- lose = LEFT;
- }
-
-
- sCW[i-1] = s0[lose] ^ s1[lose];
- tCW[i-1][LEFT] = t0[LEFT] ^ t1[LEFT] ^ indexBit ^ 1;
- tCW[i-1][RIGHT] = t0[RIGHT] ^ t1[RIGHT] ^ indexBit;
-
- if(t[i-1][0] == 1){
- s[i][0] = s0[keep] ^ sCW[i-1];
- t[i][0] = t0[keep] ^ tCW[i-1][keep];
- }else{
- s[i][0] = s0[keep];
- t[i][0] = t0[keep];
- }
- if(t[i-1][1] == 1){
- s[i][1] = s1[keep] ^ sCW[i-1];
- t[i][1] = t1[keep] ^ tCW[i-1][keep];
- }else{
- s[i][1] = s1[keep];
- t[i][1] = t1[keep];
- }
-
- }
-
- unsigned char *buff0;
- unsigned char *buff1;
- buff0 = (unsigned char*) malloc(1 + 16 + 1 + 18 * maxLayer + dataSize);
- buff1 = (unsigned char*) malloc(1 + 16 + 1 + 18 * maxLayer + dataSize);
-
- //take data, xor it with dataSize bits generated from s_0^n and another dataSize bits generated from s_1^n
- //use a counter mode encryption of 0 with each seed as key to get prg output
- uint8_t *lastCW = (uint8_t*) malloc(dataSize);
- uint8_t *convert0 = (uint8_t*) malloc(dataSize+16);
- uint8_t *convert1 = (uint8_t*) malloc(dataSize+16);
- uint8_t *zeros = (uint8_t*) malloc(dataSize+16);
- memset(zeros, 0, dataSize+16);
-
- memcpy(lastCW, data, dataSize);
-
- int len = 0;
- //generate dataSize length prg outputs from the seeds
- EVP_CIPHER_CTX *seedCtx0;
- EVP_CIPHER_CTX *seedCtx1;
- if(!(seedCtx0 = EVP_CIPHER_CTX_new()))
- printf("errors occured in creating context\n");
- if(!(seedCtx1 = EVP_CIPHER_CTX_new()))
- printf("errors occured in creating context\n");
- if(1 != EVP_EncryptInit_ex(seedCtx0, EVP_aes_128_ctr(), NULL, (uint8_t*)&s[maxLayer][0], NULL))
- printf("errors occured in init of dpf gen\n");
- if(1 != EVP_EncryptInit_ex(seedCtx1, EVP_aes_128_ctr(), NULL, (uint8_t*)&s[maxLayer][1], NULL))
- printf("errors occured in init of dpf gen\n");
- if(1 != EVP_EncryptUpdate(seedCtx0, convert0, &len, zeros, dataSize))
- printf("errors occured in encrypt\n");
- if(1 != EVP_EncryptUpdate(seedCtx1, convert1, &len, zeros, dataSize))
- printf("errors occured in encrypt\n");
- for(int i = 0; i < dataSize; i++){
- lastCW[i] = lastCW[i] ^ ((uint8_t*)convert0)[i] ^ ((uint8_t*)convert1)[i];
- }
- if(buff0 == NULL || buff1 == NULL){
- printf("Memory allocation failed\n");
- exit(1);
- }
- buff0[0] = domainSize;
- memcpy(&buff0[1], &s[0][0], 16);
- buff0[17] = t[0][0];
- for(int i = 1; i <= maxLayer; i++){
- memcpy(&buff0[18 * i], &sCW[i-1], 16);
- buff0[18 * i + 16] = tCW[i-1][0];
- buff0[18 * i + 17] = tCW[i-1][1];
- }
- memcpy(&buff0[18 * maxLayer + 18], lastCW, dataSize);
- buff1[0] = domainSize;
- memcpy(&buff1[18], &buff0[18], 18 * (maxLayer));
- memcpy(&buff1[1], &s[0][1], 16);
- buff1[17] = t[0][1];
- memcpy(&buff1[18 * maxLayer + 18], lastCW, dataSize);
- *k0 = buff0;
- *k1 = buff1;
-
- free(lastCW);
- free(convert0);
- free(convert1);
- free(zeros);
- EVP_CIPHER_CTX_free(seedCtx0);
- EVP_CIPHER_CTX_free(seedCtx1);
- }
- uint128_t evalDPF(EVP_CIPHER_CTX *ctx, unsigned char* k, uint128_t x, int dataSize, uint8_t* dataShare){
- //NOTE: if dataSize is not a multiple of 16, the size of dataShare should be
- //the next multiple of 16 after dataSize or else there is a memory bug.
- //Thanks to Emma Dauterman for pointing this out.
- //dataShare is of size dataSize
-
- int n = k[0];
- int maxLayer = n;
- uint128_t s[maxLayer + 1];
- int t[maxLayer + 1];
- uint128_t sCW[maxLayer];
- int tCW[maxLayer][2];
- memcpy(&s[0], &k[1], 16);
- t[0] = k[17];
- for(int i = 1; i <= maxLayer; i++){
- memcpy(&sCW[i-1], &k[18 * i], 16);
- tCW[i-1][0] = k[18 * i + 16];
- tCW[i-1][1] = k[18 * i + 17];
- }
- uint128_t sL, sR;
- int tL, tR;
- for(int i = 1; i <= maxLayer; i++){
- dpfPRG(ctx, s[i - 1], &sL, &sR, &tL, &tR);
- if(t[i-1] == 1){
- sL = sL ^ sCW[i-1];
- sR = sR ^ sCW[i-1];
- tL = tL ^ tCW[i-1][0];
- tR = tR ^ tCW[i-1][1];
- }
- int xbit = getbit(x, n, i);
- if(xbit == 0){
- s[i] = sL;
- t[i] = tL;
- }else{
- s[i] = sR;
- t[i] = tR;
- }
- }
-
- //get the data share out
- int len = 0;
- uint8_t *zeros = (uint8_t*) malloc(dataSize+16);
- memset(zeros, 0, dataSize+16);
- //use a counter mode encryption of 0 with each seed as key to get prg output
- //printf("here\n");
-
- EVP_CIPHER_CTX *seedCtx;
- if(!(seedCtx = EVP_CIPHER_CTX_new()))
- printf("errors occured in creating context\n");
- if(1 != EVP_EncryptInit_ex(seedCtx, EVP_aes_128_ctr(), NULL, (uint8_t*)&s[maxLayer], NULL))
- printf("errors occured in init of dpf eval\n");
- if(1 != EVP_EncryptUpdate(seedCtx, dataShare, &len, zeros, ((dataSize-1)|15)+1))
- printf("errors occured in encrypt\n");
-
- for(int i = 0; i < dataSize; i++){
- if(t[maxLayer] == 1){
- //xor in correction word
- dataShare[i] = dataShare[i] ^ k[18*n+18+i];
-
- //printf("xoring stuff in at index %d\n", i);
- }
- //printf("%x\n", (*dataShare)[i]);
- }
-
- free(zeros);
- EVP_CIPHER_CTX_free(seedCtx);
-
- //print_block(s[maxLayer]);
- //printf("%x\n", t[maxLayer]);
- //use the last seed for dpf checking
- return s[maxLayer];
- }
- //use the correllated randomness so that servers and user pick same randomness
- //this is the PRF for dpf checking
- void PRF(EVP_CIPHER_CTX *ctx, uint128_t seed, int layer, int count, uint128_t* output){
- int len = 0;
- uint128_t input = seed;
- int tries = 0;
-
- //xor count with 32 bits of input and layer with next 32 bits.
- //count = -1 is for determining whether to swap or not when shuffling halves
- // if output mod 2 == 1, then user/servers will swap
- int* temp;
- temp = (int*)&input;
- temp[0] = temp[0] ^ count;
- temp[1] = temp[1] ^ layer;
- uint128_t stash = 0;
-
- do{
- temp[2] = temp[2] ^ tries;
- uint128_t stashin = input;
- if(1 != EVP_EncryptUpdate(ctx, (uint8_t*)&stash, &len, (uint8_t*)&stashin, 16))
- printf("errors occured in encrypt\n");
- stash = stash ^ input;
- tries++;
-
- //drop blocks that are not in Z_p when count is not -1
- } while(count != -1 && stash + MODP < stash);
- *output = stash;
- }
- void clientGenProof(EVP_CIPHER_CTX *ctx, uint128_t seed, int index, uint128_t aShare, uint128_t bShare, uint8_t* outputsAIn, uint8_t* outputsBIn){
- uint128_t *outputsA = (uint128_t*) outputsAIn;
- uint128_t *outputsB = (uint128_t*) outputsBIn;
- //outputs will hold the following items in the following order
- //this comes out to 10 values
- //outputs for server A of the first multiplication proof (cc)
- //f0amult1 (index) 0
- //g0amult1 1
- //h0amult1 2
- //h1amult1 3
- //h2amult1 4
- //outputs for server A of the second multiplication proof (mC)
- //f0amult2 5
- //g0amult2 6
- //h0amult2 7
- //h1amult2 8
- //h2amult2 9
- //all the same things needed for server B as well
- //client generates a bunch of randomness and assigns most of the outputs
- //whp these are all in the field we're using
- for(int i = 0; i < 10; i++){
- outputsB[i] = getRandomBlock();
- }
- outputsA[0] = getRandomBlock();
- outputsA[1] = getRandomBlock();
- outputsA[5] = getRandomBlock();
- outputsA[6] = getRandomBlock();
- //find f0,g0 based on randomness generated above
- uint128_t f0mult1 = subModP(outputsA[0], outputsB[0]);
- uint128_t g0mult1 = subModP(outputsA[1], outputsB[1]);
- uint128_t f0mult2 = subModP(outputsA[5], outputsB[5]);
- uint128_t g0mult2 = subModP(outputsA[6], outputsB[6]);
- //find f1,g1 (shortcut since client knows non-zero index)
- uint128_t rvalue;
- PRF(ctx, seed, 0, index, &rvalue);
- uint128_t f1mult1 = multModP(subModP(aShare, bShare), rvalue);
- uint128_t g1mult1 = f1mult1;
- uint128_t f1mult2 = subModP(aShare, bShare);
- uint128_t g1mult2 = f1mult1;
- //printf("value for m on client side"); print_block(f1mult2);
- //printf("value for c on client side");print_block(f1mult1);
- //calculate h0,h1 values by multiplying
- uint128_t h0mult1 = multModP(f0mult1,g0mult1);
- uint128_t h0mult2 = multModP(f0mult2,g0mult2);
- uint128_t h1mult1 = multModP(f1mult1,g1mult1);
- uint128_t h1mult2 = multModP(f1mult2,g1mult2);
- //put shares of h0,h1 in output
- outputsA[2] = addModP(h0mult1, outputsB[2]);
- outputsA[7] = addModP(h0mult2, outputsB[7]);
- outputsA[3] = addModP(h1mult1, outputsB[3]);
- outputsA[8] = addModP(h1mult2, outputsB[8]);
- //find f2,g2
- uint128_t two = 2;
- uint128_t f2mult1 = evalLinearR(two, f0mult1, f1mult1);
- uint128_t g2mult1 = evalLinearR(two, g0mult1, g1mult1);
- uint128_t f2mult2 = evalLinearR(two, f0mult2, f1mult2);
- uint128_t g2mult2 = evalLinearR(two, g0mult2, g1mult2);
- //calculate h2 values by multiplying
- uint128_t h2mult1 = multModP(f2mult1,g2mult1);
- uint128_t h2mult2 = multModP(f2mult2,g2mult2);
- //put shares of h2 in output
- outputsA[4] = addModP(h2mult1, outputsB[4]);
- outputsA[9] = addModP(h2mult2, outputsB[9]);
- /*
- //for testing, trying to produce output of proof
- //compute f(r), g(r)
- uint128_t frmult1 = evalLinearR(10, f0mult1, f1mult1);
- uint128_t grmult1 = evalLinearR(10, g0mult1, g1mult1);
- uint128_t frmult2 = evalLinearR(10, f0mult2, f1mult2);
- uint128_t grmult2 = evalLinearR(10, g0mult2, g1mult2);
- //compute h(r)
- uint128_t hrmult1 = evalQuadraticR(10, h0mult1, h1mult1, h2mult1);
- uint128_t hrmult2 = evalQuadraticR(10, h0mult2, h1mult2, h2mult2);
-
- printf("values: ");
- printf("\nf1: ");print_block(frmult1);
- printf("\ng1: ");print_block(grmult1);
- printf("\nh1: ");print_block(hrmult1);
- printf("\nf2: ");print_block(frmult2);
- printf("\ng2: ");print_block(grmult2);
- printf("\nh2: ");print_block(hrmult2);
- */
- }
- void serverSetupProof(EVP_CIPHER_CTX *ctx, uint8_t *seedIn, int dbSize, uint8_t* vectorsIn, uint8_t* mIn, uint8_t* cIn){
- uint128_t* m = (uint128_t*) mIn;
- uint128_t* c = (uint128_t*) cIn;
- uint128_t* vectors = (uint128_t*) vectorsIn;
- uint128_t seed;
- memcpy(&seed, seedIn, 16);
- uint128_t prfOutput;
- uint128_t workingM = 0;
- uint128_t workingC = 0;
- for(int i = 0; i < dbSize; i++){
- PRF(ctx, seed, 0, i, &prfOutput);
- workingM = addModP(workingM, vectors[i]);
- workingC = addModP(workingC, multModP(vectors[i], prfOutput));
- }
- memcpy(m, &workingM, 16);
- memcpy(c, &workingC, 16);
- }
- void serverComputeQuery(EVP_CIPHER_CTX *ctx, uint8_t *seedIn, uint8_t* mIn, uint8_t* cIn, uint8_t* proofIn, uint8_t* ansIn){
- uint128_t* m = (uint128_t*) mIn;
- uint128_t* c = (uint128_t*) cIn;
- uint128_t* proof = (uint128_t*) proofIn;
- uint128_t* ans = (uint128_t*) ansIn;
- uint128_t seed;
- memcpy(&seed, seedIn, 16);
- //including this just for readability
- uint128_t f0mult1 = proof[0];
- uint128_t g0mult1 = proof[1];
- uint128_t h0mult1 = proof[2];
- uint128_t h1mult1 = proof[3];
- uint128_t h2mult1 = proof[4];
- uint128_t f0mult2 = proof[5];
- uint128_t g0mult2 = proof[6];
- uint128_t h0mult2 = proof[7];
- uint128_t h1mult2 = proof[8];
- uint128_t h2mult2 = proof[9];
- //generate a random point r from seed
- uint128_t r1, r2;
- PRF(ctx, seed, 1, 0, &r1);
- PRF(ctx, seed, 2, 0, &r2);
- //for testing
- //r1 = 10;
- //r2 = 10;
-
- //compute f(r), g(r)
- uint128_t frmult1 = evalLinearR(r1, f0mult1, *c);
- uint128_t grmult1 = evalLinearR(r1, g0mult1, *c);
- uint128_t frmult2 = evalLinearR(r2, f0mult2, *m);
- uint128_t grmult2 = evalLinearR(r2, g0mult2, *c);
- //compute h(r)
- uint128_t hrmult1 = evalQuadraticR(r1, h0mult1, h1mult1, h2mult1);
- uint128_t hrmult2 = evalQuadraticR(r2, h0mult2, h1mult2, h2mult2);
- //set the appropriate elements of ans (6 elements)
- ans[0] = frmult1;
- ans[1] = grmult1;
- ans[2] = hrmult1;
- ans[3] = frmult2;
- ans[4] = grmult2;
- ans[5] = hrmult2;
- }
- int serverVerifyProof(uint8_t* ans1In, uint8_t* ans2In){
- uint128_t* ans1 = (uint128_t*) ans1In;
- uint128_t* ans2 = (uint128_t*) ans2In;
-
- uint128_t f1 = subModP(ans1[0], ans2[0]);
- uint128_t g1 = subModP(ans1[1], ans2[1]);
- uint128_t h1 = subModP(ans1[2], ans2[2]);
- uint128_t f2 = subModP(ans1[3], ans2[3]);
- uint128_t g2 = subModP(ans1[4], ans2[4]);
- uint128_t h2 = subModP(ans1[5], ans2[5]);
- uint128_t prod1 = multModP(f1, g1);
- uint128_t prod2 = multModP(f2, g2);
-
- /*
- printf("recovered values: ");
- printf("\nf1: ");print_block(f1);
- printf("\ng1: ");print_block(g1);
- printf("\nh1: ");print_block(h1);
- printf("\nf2: ");print_block(f2);
- printf("\ng2: ");print_block(g2);
- printf("\nh2: ");print_block(h2);
- printf("\n\nprod1: ");print_block(prod1);
- printf("\nprod2: ");print_block(prod2);
- */
- int pass = (memcmp(&prod1, &h1, 16) == 0) && (memcmp(&prod2, &h2, 16) == 0);
- return pass;
- }
- uint128_t evalLinearR(uint128_t r, uint128_t p0, uint128_t p1){
- uint128_t slope = subModP(p1, p0);
- uint128_t pr = addModP(multModP(slope, r), p0);
- return pr;
- }
- uint128_t evalQuadraticR(uint128_t r, uint128_t h0, uint128_t h1, uint128_t h2){
- // h(r) = (1/2)(r-1)(r-2)h0 - r(r-2)h1 + (1/2)r(r-1)h2
- //(1/2)(r-1)(r-2)h0
- uint128_t t0 = 0;
- if(r%2 == 0) {
- t0 = multModP(h0, multModP(r-1, (r-2)/2));
- }
- else{
- t0 = multModP(h0, multModP((r-1)/2, r-2));
- }
- //r(r-2)h1
- uint128_t t1 = multModP(multModP(r, r-2), h1);
-
- //(1/2)r(r-1)h2
- uint128_t t2 = 0;
- if(r%2 == 0) {
- t2 = multModP(h2, multModP(r-1, r/2));
- }
- else{
- t2 = multModP(h2, multModP((r-1)/2, r));
- }
-
- //final sum
- uint128_t ret = addModP(subModP(t0, t1), t2);
- }
- //client check inputs
- void clientVerify(EVP_CIPHER_CTX *ctx, uint128_t seed, int index, uint128_t aShare, uint128_t bShare, int dbLayers, uint8_t* bits, uint8_t* nonZeroVectorsIn){
-
- uint128_t *nonZeroVectors = (uint128_t*) nonZeroVectorsIn;
-
- //note that index is the actual index, not the virtual address, in our application to oblivious key value stores
- //printf("clientVerify\n");
-
- //set bits vector to all zeros
- memset(bits, 0, dbLayers);
-
- //#pragma omp parallel for
- for(int i = 0; i < dbLayers; i++){
- uint128_t whenToSwap;
- int newIndex;
- int oldIndex;
- //set newAlphaIndex
- oldIndex = index % (1<<(dbLayers - i));
- newIndex = index % (1<<(dbLayers - i - 1));
- //if the index has changed, then the nonzero value was in the second half
- if(newIndex != oldIndex){
- bits[i] = 1;
- }
- //printf("bits %d before potential flip: %d\n", i, bits[i]);
- //check if the halves will be swapped and set the entry of bits
- PRF(ctx, seed, i, -1, &whenToSwap);
- bits[i] = bits[i] ^ ((uint128_t)whenToSwap % 2);
-
- uint128_t temp;
- uint128_t temp2;
- //check the mask value and set entry of nonZeroVectors
- PRF(ctx, seed, i, oldIndex, &temp);
- temp2 = multModP(subModP(aShare, bShare), temp);
- memcpy(&nonZeroVectors[i], &temp2, 16);
-
- }
-
- }
- //server check inputs
- void serverVerify(EVP_CIPHER_CTX *ctx, uint8_t *seedIn, int dbLayers, int dbSize, uint8_t* vectorsIn, uint8_t* outVectorsIn){
- //outVectors should be of length 2*dbLayers since there are 2 sums per layer
- //printf("serverVerify\n");
- //don't modify vectors -- it should be treated as read-only, so make a copy
- //uint128_t* vectorsWorkSpace = malloc(dbSize*sizeof(uint128_t));
- //memcpy(vectorsWorkSpace, vectors, dbSize*sizeof(uint128_t));
-
- uint128_t *vectors = (uint128_t*) vectorsIn;
- uint128_t *outVectors = (uint128_t*) outVectorsIn;
- uint128_t seed;
- memcpy(&seed, seedIn, 16);
-
- uint128_t* vectorsWorkSpace = vectors;
-
- uint128_t prfOutput;
- uint128_t leftSum, rightSum;
- int newDbSize = dbSize;
-
-
- //#pragma omp declare reduction(ADDMODP: uint128_t : omp_out += omp_in + (omp_out + omp_in < omp_out || omp_out+omp_in > 0-MODP)*MODP)
-
- for(int i = 0; i < dbLayers; i++){
-
- leftSum = 0;
- rightSum = 0;
-
- //multiply each element by a ``random'' value and add into the appropriate sum
- //#pragma omp parallel for \
- // default(shared) private(prfOutput) \
- // reduction(ADDMODP:rightSum,leftSum)
- for(int j = 0; j < newDbSize; j++){
- PRF(ctx, seed, i, j, &prfOutput);
- if(j >= (1<<(dbLayers - i - 1))){ //if j is in right half
- //rightSum = multModP(vectorsWorkSpace[j], prfOutput);
- //printf("ladeeda%d\n", j);
- //use line commented below when compiling without openmp
- //looks like it actually works with openmp too!
- rightSum = addModP(rightSum, multModP(vectorsWorkSpace[j], prfOutput));
- }
- else{ // j is in left half
- //leftSum = multModP(vectorsWorkSpace[j], prfOutput);
- //printf("ladeedee%d\n", j);
- //use line commented below when compiling without openmp
- //looks like it actually works with openmp too!
- leftSum = addModP(leftSum, multModP(vectorsWorkSpace[j], prfOutput));
- }
- }
- //printf("\n");
-
- //add together left and right halves for next iteration
- //#pragma omp parallel for
- for(int j = 1<<(dbLayers - i - 1); j < newDbSize; j++){
- vectorsWorkSpace[j - (1<<(dbLayers - i - 1))] = addModP(vectorsWorkSpace[j - (1<<(dbLayers - i - 1))], vectorsWorkSpace[j]);
- }
-
- //adjust newDbSize for next round
- newDbSize = 1 << (dbLayers - (i+1));
-
- //check if the halves will be swapped and place the sums in the appropriate spots
- PRF(ctx, seed, i, -1, &prfOutput);
- if((uint128_t)prfOutput % 2 == 0){
- memcpy(&outVectors[2*i], &leftSum, 16);
- memcpy(&outVectors[2*i+1], &rightSum, 16);
- }
- else{
- memcpy(&outVectors[2*i], &rightSum, 16);
- memcpy(&outVectors[2*i+1], &leftSum, 16);
- }
-
- //print_block(rightSum);
- //print_block(leftSum);
-
- }
- //free(vectorsWorkSpace);
- }
- //auditor functionality
- int auditorVerify(int dbLayers, uint8_t* bits, uint8_t* nonZeroVectorsIn, uint8_t* outVectorsAIn, uint8_t* outVectorsBIn){
-
- uint128_t *nonZeroVectors = (uint128_t*)nonZeroVectorsIn;
- uint128_t *outVectorsA = (uint128_t*)outVectorsAIn;
- uint128_t *outVectorsB = (uint128_t*)outVectorsBIn;
-
- //printf("auditorVerify\n");
- int pass = 1; //set this to 0 if any check fails
- uint128_t zero = 0;
-
- //#pragma omp parallel for
- for(int i = 0; i < dbLayers; i++){
- uint128_t mergeAB[2];
-
- //merge the output vectors to get the values
- mergeAB[0] = subModP(outVectorsA[2*i], outVectorsB[2*i]);
- mergeAB[1] = subModP(outVectorsA[2*i+1], outVectorsB[2*i+1]);
-
- //printf("%d %lu, %lu, %lu, %lu\n", i, outVectorsA[2*i], outVectorsA[2*i+1], outVectorsB[2*i], outVectorsB[2*i+1]);
-
- //first check that the appropriate side is 0
- //only need to check AB since if it is 0 then so is BA
- //then check that the other side is equal to the corresponding nonZeroVectors entry for one direction
- if( memcmp(&mergeAB[1-bits[i]], &zero, 16) != 0 || (
- memcmp(&mergeAB[bits[i]], &nonZeroVectors[i], 16) != 0
- )){
- printf("fail conditions in round %d: %d %d \n", i, memcmp(&mergeAB[1-bits[i]], &zero, 16), memcmp(&mergeAB[bits[i]], &nonZeroVectors[i], 16));
- printf("auditor expected to see \n");print_block(nonZeroVectors[i]);
- printf("but auditor saw \n");print_block(mergeAB[bits[i]]);
- printf("difference \n"); print_block(nonZeroVectors[i] - mergeAB[bits[i]]);print_block(mergeAB[bits[i]] - nonZeroVectors[i]);
- pass = 0;
- }
-
- }
-
- return pass;
- }
- void digest_message(const unsigned char *message, size_t message_len, unsigned char **digest, unsigned int *digest_len)
- {
- EVP_MD_CTX *mdctx;
- if((mdctx = EVP_MD_CTX_create()) == NULL)
- printf("digest error\n");
- if(1 != EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL))
- printf("digest error\n");
- if(1 != EVP_DigestUpdate(mdctx, message, message_len))
- printf("digest error\n");
- if((*digest = (unsigned char *)OPENSSL_malloc(EVP_MD_size(EVP_sha256()))) == NULL)
- printf("digest error\n");
- if(1 != EVP_DigestFinal_ex(mdctx, *digest, digest_len))
- printf("digest error\n");
- EVP_MD_CTX_destroy(mdctx);
- }
- void riposteClientVerify(EVP_CIPHER_CTX *ctx, uint128_t seed, int dbSize, uint128_t *va, uint128_t *vb, uint8_t **digestA, uint8_t **digestB){
- uint128_t *mVectorA = (uint128_t*) malloc(dbSize*16);
- uint128_t *mVectorB = (uint128_t*) malloc(dbSize*16);
- uint128_t prfOutput;
- //#pragma omp parallel for \
- //default(shared) private(prfOutput)
- for(int i = 0; i < dbSize; i++){
- PRF(ctx, seed, 0, i, &prfOutput);
- mVectorA[i] = va[i] ^ prfOutput;
- mVectorB[i] = vb[i] ^ prfOutput;
- }
-
- int len = 0;
- digest_message((uint8_t*)mVectorA, dbSize*16, digestA, &len);
- digest_message((uint8_t*)mVectorB, dbSize*16, digestB, &len);
- free(mVectorA);
- free(mVectorB);
- }
- void riposteServerVerify(EVP_CIPHER_CTX *ctx, uint128_t seed, int dbSize, uint128_t *vector, uint128_t *mVector, uint128_t *cValue){
-
- PRF(ctx, seed, 1, 0, cValue);
- uint128_t prfOutput;
-
- //#pragma omp parallel for \
- //default(shared) private(prfOutput)
- for(int i = 0; i < dbSize; i++){
- PRF(ctx, seed, 0, i, &prfOutput);
- mVector[i] = vector[i] ^ prfOutput;
- }
- }
- int riposteAuditorVerify(uint8_t *digestA, uint8_t *digestB, uint8_t *ma, uint8_t *mb, uint128_t ca, uint128_t cb, int dbSize){
- int pass = 1;
-
- //check that the masked seeds are equal
- if(ca != cb){
- printf("failed audit, masked seeds unequal\n");
- pass = 0;
- }
-
- //check that m vectors differ in only 1 place
- int differenceCount = 0;
-
- //#pragma omp parallel for
- for(int i = 0; i < dbSize; i++) {
- if(memcmp(&ma[i*16], &mb[i*16], 16) != 0){
- //#pragma omp critical
- differenceCount++;
- }
- }
- if(differenceCount != 1){
- printf("failed audit, difference count incorrect %d\n", differenceCount);
- pass = 0;
- }
- //check that the digests match their expected values
- int len = 0;
- uint8_t *newDigestA = (uint8_t*)malloc(32);
- uint8_t *newDigestB = (uint8_t*)malloc(32);
- digest_message(ma, dbSize*16, &newDigestA, &len);
- digest_message(mb, dbSize*16, &newDigestB, &len);
- if(memcmp(digestA, newDigestA, 32) != 0 || memcmp(digestB, newDigestB, 32) != 0){
- printf("failed audit, digest mismatch %d %d\n", memcmp(digestA, newDigestA, 32), memcmp(digestB, newDigestB, 32) != 0);
- pass = 0;
- }
-
- free(newDigestA);
- free(newDigestB);
-
- return pass;
- }
- int dpf_tests(){
- //int main(){
- //pick 2 64-bit values as a fixed aes key
- //and use those values to key the aes we will be using as a PRG
- EVP_CIPHER_CTX *ctx;
- if(!(ctx = EVP_CIPHER_CTX_new()))
- printf("errors occured in creating context\n");
- unsigned char *aeskey = (unsigned char*) "0123456789123456";
- if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, aeskey, NULL))
- printf("errors occured in init\n");
- EVP_CIPHER_CTX_set_padding(ctx, 0);
-
-
- //printf("mult test: %d", multModP((uint128_t)5<<125,((uint128_t)6)<<125)); return 0;
- //generate DPF keys for a particular query
- unsigned char *k0;
- unsigned char *k1;
-
-
- //functionality test for dpf
- char* data = "this is the data!";
- int dataSize = strlen(data)+1;
- //can only test with smaller constants because
- //gcc does not support 128 bit constants
- genDPF(ctx, 128, 300, dataSize, data, &k0, &k1);
-
- //evaluate dpf
- uint128_t res1;
- uint128_t res2;
- uint8_t* dataShare0 = (uint8_t*) malloc(dataSize+16);
- uint8_t* dataShare1 = (uint8_t*) malloc(dataSize+16);
-
- res1 = evalDPF(ctx, k0, 12, dataSize, dataShare0);
- res2 = evalDPF(ctx, k1, 12, dataSize, dataShare1);
- printf("\nresult evaluated at 12: ");
- print_block(res1 ^ res2);
- res1 = evalDPF(ctx, k0, 300, dataSize, dataShare0);
- res2 = evalDPF(ctx, k1, 300, dataSize, dataShare1);
- printf("\nresult evaluated at 300: ");
- print_block(res1 ^ res2);
- uint8_t* recoveredData = (uint8_t*) malloc(dataSize);
- printf("data recovered: ");
- for(int i = 0; i < dataSize; i++){
- recoveredData[i] = dataShare0[i] ^ dataShare1[i];
- printf("%c", recoveredData[i]);
- //printf("%x\n", dataShare1[i]);
- }
- printf("\n");
- //return 0;
-
-
- //now we'll do a simple functionality test of the dpf checking.
- //this will in no way be rigorous or even representative of the
- //usual use case since all the evaluation points are small
- //just a sanity check before moving on to the obliv key val stuff
-
- uint128_t db[] = {4343423, 232132, 465437, 43, 300, 5346643};
- int dbSize = 6;
- int dbLayers = 3;
- uint128_t* seed = malloc(sizeof(uint128_t));
- *seed = getRandomBlock();
-
- //allocate the various arrays we will need
- uint8_t* bits = malloc(dbLayers);
- uint128_t* nonZeroVectors = malloc(sizeof(uint128_t)*dbLayers);
- uint128_t* vectorsA = malloc(sizeof(uint128_t)*dbSize);
- uint128_t* vectorsB = malloc(sizeof(uint128_t)*dbSize);
- uint128_t* outVectorsA = malloc(sizeof(uint128_t)*2*dbLayers);
- uint128_t* outVectorsB = malloc(sizeof(uint128_t)*2*dbLayers);
-
- //evaluate the db at each point for each server
- //#pragma omp parallel for
- for(int i = 0; i < dbSize; i++){
- uint128_t res1, res2;
- res1 = evalDPF(ctx, k0, db[i], dataSize, dataShare0);
- res2 = evalDPF(ctx, k1, db[i], dataSize, dataShare1);
- memcpy(&vectorsA[i], &res1, 16);
- memcpy(&vectorsB[i], &res2, 16);
- }
- uint128_t* proofA = (uint128_t*)malloc(sizeof(uint128_t)*10);
- uint128_t* proofB = (uint128_t*)malloc(sizeof(uint128_t)*10);
- uint128_t* ansA = (uint128_t*)malloc(sizeof(uint128_t)*6);
- uint128_t* ansB = (uint128_t*)malloc(sizeof(uint128_t)*6);
- uint128_t mA, cA, mB, cB;
-
- //run the dpf verification functions
- clientGenProof(ctx, *seed, 4, vectorsA[4], vectorsB[4], (uint8_t*)proofA, (uint8_t*)proofB);
- serverSetupProof(ctx, (uint8_t*)seed, dbSize, (uint8_t*) vectorsA, (uint8_t*)&mA, (uint8_t*) &cA);
- serverSetupProof(ctx, (uint8_t*)seed, dbSize, (uint8_t*) vectorsB, (uint8_t*)&mB, (uint8_t*) &cB);
- //printf("m on server side"); print_block(subModP(mA,mB));
- //printf("c on server side");print_block(subModP(cA,cB));
- serverComputeQuery(ctx, (uint8_t*)seed, (uint8_t*)&mA, (uint8_t*) &cA, (uint8_t*)proofA, (uint8_t*) ansA);
- serverComputeQuery(ctx, (uint8_t*)seed, (uint8_t*)&mB, (uint8_t*) &cB, (uint8_t*)proofB, (uint8_t*) ansB);
- int pass = -1;
- pass = serverVerifyProof((uint8_t*) ansA, (uint8_t*) ansB);
- printf("dpf check verification: %d (should be 1)\n", pass);
-
- //now test the riposte auditing
- free(outVectorsA);
- free(outVectorsB);
- outVectorsA = malloc(sizeof(uint128_t)*dbSize);
- outVectorsB = malloc(sizeof(uint128_t)*dbSize);
- uint128_t cValueA = 0;
- uint128_t cValueB = 0;
- uint8_t *digestA = (uint8_t*) malloc(32);
- uint8_t *digestB = (uint8_t*) malloc(32);
- riposteClientVerify(ctx, *seed, dbSize, vectorsA, vectorsB, &digestA, &digestB);
- riposteServerVerify(ctx, *seed, dbSize, vectorsA, outVectorsA, &cValueA);
- riposteServerVerify(ctx, *seed, dbSize, vectorsB, outVectorsB, &cValueB);
-
- pass = riposteAuditorVerify(digestA, digestB, (uint8_t*)outVectorsA, (uint8_t*)outVectorsB, cValueA, cValueB, dbSize);
- printf("riposte dpf check verification: %d (should be 1)\n", pass);
-
- //tamper with dpf outputs to see if auditor catches it
- //memcpy(&outVectorsB[2], &outVectorsA[1], 16);
- //pass = riposteAuditorVerify(digestA, digestB, (uint8_t*)outVectorsA, (uint8_t*)outVectorsB, cValueA, cValueB, dbSize);
- //printf("riposte dpf check verification: %d (should be 0)\n", pass);
-
- //return 0;
- //performance test of dpf verification
-
- int dbSizes[4];
- dbSizes[0] = 1000;
- dbSizes[1] = 10000;
- dbSizes[2] = 100000;
- dbSizes[3] = 1000000;
- int dbLayer[4];
- dbLayer[0] = 10;
- dbLayer[1] = 14;
- dbLayer[2] = 17;
- dbLayer[3] = 20;
- clock_t begin, elapsed;
- seed = malloc(sizeof(uint128_t));
- *seed = getRandomBlock();
-
- vectorsA = malloc(sizeof(uint128_t)*dbSizes[3]);
- vectorsB = malloc(sizeof(uint128_t)*dbSizes[3]);
-
- memset(vectorsA,'a',dbSizes[3]*16);
- memset(vectorsB,'a',dbSizes[3]*16);
- vectorsA[10] = 13;
- vectorsB[10] = 12;
-
- /*
- void clientGenProof(EVP_CIPHER_CTX *ctx, uint128_t seed, int index, uint128_t aShare, uint128_t bShare, uint8_t* outputsAIn, uint8_t* outputsBIn);
- void serverSetupProof(EVP_CIPHER_CTX *ctx, uint8_t *seedIn, int dbSize, uint8_t* vectorsIn, uint8_t* mIn, uint8_t* cIn);
- void serverComputeQuery(EVP_CIPHER_CTX *ctx, uint8_t *seedIn, uint8_t* mIn, uint8_t* cIn, uint8_t* proofIn, uint8_t* ansIn);
- int serverVerifyProof(uint8_t* ans1In, uint8_t* ans2In);
- */
- //us
- for(int i = 0; i < 4; i++){
- proofA = (uint128_t*)malloc(sizeof(uint128_t)*10);
- proofB = (uint128_t*)malloc(sizeof(uint128_t)*10);
- ansA = (uint128_t*)malloc(sizeof(uint128_t)*6);
- ansB = (uint128_t*)malloc(sizeof(uint128_t)*6);
- uint128_t mA, cA, mB, cB;
-
- begin = clock();
- clientGenProof(ctx, *seed, 10, vectorsA[10], vectorsB[10], (uint8_t*)proofA, (uint8_t*)proofB);
- elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
- printf("client proof gen time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
-
- begin = clock();
- serverSetupProof(ctx, (uint8_t*)seed, dbSizes[i], (uint8_t*)vectorsA, (uint8_t*)&mA, (uint8_t*)&cA);
- elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
- printf("server prep time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
- serverSetupProof(ctx, (uint8_t*)seed, dbSizes[i], (uint8_t*)vectorsB, (uint8_t*)&mB, (uint8_t*)&cB);
- begin = clock();
- serverComputeQuery(ctx, (uint8_t*)seed, (uint8_t*)&mA, (uint8_t*)&cA, (uint8_t*)proofA, (uint8_t*)ansA);
- elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
- printf("server query time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
- serverComputeQuery(ctx, (uint8_t*)seed, (uint8_t*)&mB, (uint8_t*)&cB, (uint8_t*)proofB, (uint8_t*)ansB);
- pass = 0;
- begin = clock();
- pass = serverVerifyProof((uint8_t*)ansA,(uint8_t*)ansB);
- elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
- printf("server verification time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
- if(pass == 0){
- printf("dpf check verification failed %d\n", i);
- }
- free(proofA);
- free(proofB);
- free(ansA);
- free(ansB);
- }
-
- //riposte
- for(int i = 0; i < 4; i++){ //something went wrong at 4
- outVectorsA = malloc(sizeof(uint128_t)*dbSizes[i]);
- outVectorsB = malloc(sizeof(uint128_t)*dbSizes[i]);
- cValueA = 0;
- cValueB = 0;
- digestA = (uint8_t*) malloc(32);
- digestB = (uint8_t*) malloc(32);
-
-
- begin = clock();
- riposteClientVerify(ctx, *seed, dbSizes[i], vectorsA, vectorsB, &digestA, &digestB);
- elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
- printf("riposte client verification time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
-
- begin = clock();
- riposteServerVerify(ctx, *seed, dbSizes[i], vectorsA, outVectorsA, &cValueA);
- elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
- printf("riposte server verification time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
- riposteServerVerify(ctx, *seed, dbSizes[i], vectorsB, outVectorsB, &cValueB);
-
- pass = 0;
- begin = clock();
- pass = riposteAuditorVerify(digestA, digestB, (uint8_t*)outVectorsA, (uint8_t*)outVectorsB, cValueA, cValueB, dbSizes[i]);
- elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
- printf("riposte auditor verification time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
- if(pass == 0){
- printf("riposte dpf check verification failed %d\n", i);
- }
-
- free(outVectorsA);
- free(outVectorsB);
- free(digestA);
- free(digestB);
- }
-
- free(vectorsA);
- free(vectorsB);
-
- return 0;
- //performance test of the dpf
-
- char *s[10];
-
- s[0] = (char*) malloc(2);
- s[1] = (char*) malloc(16);
- s[2] = (char*) malloc(100);
- s[3] = (char*) malloc(1000);
- s[4] = (char*) malloc(10000);
- s[5] = (char*) malloc(100000);
- s[6] = (char*) malloc(1000000);
- memset(s[0], 'a', 1);
- memset(s[0]+1, '\0', 1);
- memset(s[1], 'a', 15);
- memset(s[1]+15, '\0', 1);
- memset(s[2], 'a', 99);
- memset(s[2]+99, '\0', 1);
- memset(s[3], 'a', 999);
- memset(s[3]+999, '\0', 1);
- memset(s[4], 'a', 9999);
- memset(s[4]+9999, '\0', 1);
- memset(s[5], 'a', 99999);
- memset(s[5]+99999, '\0', 1);
- memset(s[6], 'a', 999999);
- memset(s[6]+999999, '\0', 1);
-
- free(dataShare0);
- free(dataShare1);
- free(recoveredData);
- recoveredData = (uint8_t*) malloc(strlen(s[5])+1);
- dataShare0 = (uint8_t*) malloc(strlen(s[5])+1);
- dataShare1 = (uint8_t*) malloc(strlen(s[5])+1);
-
- for(int j = 2; j < 6; j++){//skip to the sizes we care about
- dataSize = strlen(s[j])+1;
- genDPF(ctx, 128, 300, dataSize, s[j], &k0, &k1);
- res1 = evalDPF(ctx, k0, 12, dataSize, dataShare0);
- res2 = evalDPF(ctx, k1, 12, dataSize, dataShare1);
- for(int i = 0; i < dataSize; i++){
- recoveredData[i] = dataShare0[i] ^ dataShare1[i];
- }
- if(strcmp(recoveredData, s[j]) == 0){
- printf("string %d recovered data for wrong input", j);
- }
- res1 = evalDPF(ctx, k0, 300, dataSize, dataShare0);
- res2 = evalDPF(ctx, k1, 300, dataSize, dataShare1);
- for(int i = 0; i < dataSize; i++){
- recoveredData[i] = dataShare0[i] ^ dataShare1[i];
- }
- if(strcmp(recoveredData, s[j]) != 0){
- printf("string %d recovered incorrect data", j);
- }
- clock_t start = clock(), diff;
- #pragma omp parallel for
- for(int i = 0; i < 1000; i++){
- res1 = evalDPF(ctx, k0, i*((uint128_t)2<<70), dataSize, dataShare0);
- }
- diff = clock() - start;
- int msec = diff * 1000 / CLOCKS_PER_SEC;
- printf("Time taken for string %d, db size 1,000: %d milliseconds\n", j, msec);
-
- start = clock();
- #pragma omp parallel for
- for(int i = 0; i < 10000; i++){
- res1 = evalDPF(ctx, k0, i*((uint128_t)2<<70), dataSize, dataShare0);
- }
- diff = clock() - start;
- msec = diff * 1000 / CLOCKS_PER_SEC;
- printf("Time taken for string %d, db size 10,000: %d milliseconds\n", j, msec);
-
- start = clock();
- #pragma omp parallel for
- for(int i = 0; i < 100000; i++){
- res1 = evalDPF(ctx, k0, i*((uint128_t)2<<70), dataSize, dataShare0);
- }
- diff = clock() - start;
- msec = diff * 1000 / CLOCKS_PER_SEC;
- printf("Time taken for string %d, db size 100,000: %d milliseconds\n", j, msec);
-
- /*
- start = clock();
- #pragma omp parallel for
- for(int i = 0; i < 1000000; i++){
- res1 = evalDPF(ctx, k0, i*((uint128_t)2<<70), dataSize, dataShare0);
- }
- diff = clock() - start;
- msec = diff * 1000 / CLOCKS_PER_SEC;
- printf("Time taken for string %d, db size 1,000,000: %d milliseconds\n", j, msec);
- */
- }
-
- return 0;
- }
|