dpf.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263
  1. #include "dpf.h"
  2. #include <openssl/rand.h>
  3. #include <omp.h>
  4. #include <time.h>
  5. uint128_t dpf_reverse_lsb(uint128_t input){
  6. uint128_t xor = 1;
  7. return input ^ xor;
  8. }
  9. uint128_t dpf_lsb(uint128_t input){
  10. return input & 1;
  11. }
  12. uint128_t dpf_set_lsb_zero(uint128_t input){
  13. int lsb = input & 1;
  14. if(lsb == 1){
  15. return dpf_reverse_lsb(input);
  16. }else{
  17. return input;
  18. }
  19. }
  20. void _output_bit_to_bit(uint128_t input){
  21. for(int i = 0; i < 64; i++)
  22. {
  23. if( (1ll << i) & input)
  24. printf("1");
  25. else
  26. printf("0");
  27. }
  28. }
  29. void print_block(uint128_t input) {
  30. uint64_t *val = (uint64_t *) &input;
  31. //printf("%016lx%016lx\n", val[0], val[1]);
  32. _output_bit_to_bit(val[0]);
  33. _output_bit_to_bit(val[1]);
  34. printf("\n");
  35. }
  36. uint128_t addModP(uint128_t in1, uint128_t in2){
  37. uint128_t out = in1 + in2;
  38. //if we wrapped around, add in the MODP
  39. if(out + MODP < in1 || out > 0-MODP){
  40. out += MODP;
  41. //printf("addModP wrapped\n");
  42. }
  43. return out;
  44. }
  45. uint128_t subModP(uint128_t in1, uint128_t in2){
  46. uint128_t out = in1 - in2;
  47. //if we wrapped around, subtract the MODP
  48. if(in2 > in1){
  49. out -= MODP;
  50. //printf("subModP wrapped\n");
  51. }
  52. //straight-line version?
  53. //out -= (in2 > in1) * MODP;
  54. return out;
  55. }
  56. //performance for this is really bad
  57. //but it gets _much_ better when compiled with -O2
  58. uint128_t multModP(uint128_t in1, uint128_t in2){
  59. uint128_t out = 0;
  60. uint128_t in1high = in1 >> 64;
  61. uint128_t in2high = in2 >> 64;
  62. uint128_t in1low = in1 & (uint128_t)0xffffffffffffffff;
  63. uint128_t in2low = in2 & (uint128_t)0xffffffffffffffff;
  64. //printf("\n");
  65. //print_block(in1high); printf("\n");
  66. //print_block(in2high); printf("\n");
  67. //print_block(in1low); printf("\n");
  68. //print_block(in2low); printf("\n");
  69. //printf("\n");
  70. uint128_t outlow = in1low * in2low;
  71. if(outlow + MODP < in1low || outlow + MODP < in2low|| outlow > 0-MODP) {
  72. outlow += MODP;
  73. //printf("mult wrap\n");
  74. }
  75. //print_block(outlow);
  76. uint128_t outhigh = in1high * in2high;
  77. uint128_t outmid1 = in1high*in2low;
  78. uint128_t outmid2 = in2high*in1low;
  79. //print_block(outhigh);
  80. //print_block(outmid1);
  81. //print_block(outmid2);
  82. //the low part gets the low order bits of the mids
  83. uint128_t outlow1 = addModP(outmid1 << 64, outmid2 << 64);
  84. //uint128_t outlow1 = ((outmid1 & (uint128_t)0xffffffffffffffff) + (outmid2 & (uint128_t)0xffffffffffffffff)) << 64;
  85. //if(outlow1 + MODP < ((outmid1 & (uint128_t)0xffffffffffffffff) << 64)) outlow1 += MODP;
  86. //print_block(outlow1);
  87. out = addModP(outlow, outlow1);
  88. //print_block(out);
  89. //multiply in the wrap for as many times as we wrapped
  90. uint128_t lowWraps = ((outmid1 >> 64) + (outmid2 >> 64)) * MODP;
  91. out = addModP(out, lowWraps);
  92. //print_block(lowWraps);
  93. //now we need to account for wraps caused by outhigh
  94. uint128_t outhighlow = (outhigh & (uint128_t)0xffffffffffffffff) * MODP;
  95. uint128_t outhighhigh = (outhigh >> 64) * MODP;
  96. uint128_t outhighhighlow = outhighhigh << 64;
  97. uint128_t outhighhighhigh = (outhighhigh >> 64) * MODP;
  98. //print_block(outhighlow);
  99. //print_block(outhighhigh);
  100. //print_block(outhighhighlow);
  101. //print_block(outhighhighhigh);
  102. out = addModP(out, addModP(outhighlow, addModP(outhighhighlow, outhighhighhigh)));
  103. //print_block(out);
  104. return out;
  105. }
  106. uint128_t getRandomBlock(){
  107. static uint8_t* randKey = NULL;//(uint8_t*) malloc(16);
  108. static EVP_CIPHER_CTX* randCtx;
  109. static uint128_t counter = 0;
  110. int len = 0;
  111. uint128_t output = 0;
  112. if(!randKey){
  113. randKey = (uint8_t*) malloc(16);
  114. if(!(randCtx = EVP_CIPHER_CTX_new()))
  115. printf("errors occured in creating context\n");
  116. if(!RAND_bytes(randKey, 16)){
  117. printf("failed to seed randomness\n");
  118. }
  119. if(1 != EVP_EncryptInit_ex(randCtx, EVP_aes_128_ecb(), NULL, randKey, NULL))
  120. printf("errors occured in randomness init\n");
  121. EVP_CIPHER_CTX_set_padding(randCtx, 0);
  122. }
  123. if(1 != EVP_EncryptUpdate(randCtx, (uint8_t*)&output, &len, (uint8_t*)&counter, 16))
  124. printf("errors occured in generating randomness\n");
  125. counter++;
  126. return output;
  127. }
  128. //this is the PRG used for the DPF
  129. void dpfPRG(EVP_CIPHER_CTX *ctx, uint128_t input, uint128_t* output1, uint128_t* output2, int* bit1, int* bit2){
  130. input = dpf_set_lsb_zero(input);
  131. int len = 0;
  132. uint128_t stashin[2];
  133. stashin[0] = input;
  134. stashin[1] = dpf_reverse_lsb(input);
  135. uint128_t stash[2];
  136. EVP_CIPHER_CTX_set_padding(ctx, 0);
  137. if(1 != EVP_EncryptUpdate(ctx, (uint8_t*)stash, &len, (uint8_t*)stashin, 32))
  138. printf("errors occured in encrypt\n");
  139. //no need to do this since we're working with exact multiples of the block size
  140. //if(1 != EVP_EncryptFinal_ex(ctx, stash + len, &len))
  141. // printf("errors occured in final\n");
  142. stash[0] = stash[0] ^ input;
  143. stash[1] = stash[1] ^ input;
  144. stash[1] = dpf_reverse_lsb(stash[1]);
  145. *bit1 = dpf_lsb(stash[0]);
  146. *bit2 = dpf_lsb(stash[1]);
  147. *output1 = dpf_set_lsb_zero(stash[0]);
  148. *output2 = dpf_set_lsb_zero(stash[1]);
  149. }
  150. static int getbit(uint128_t x, int n, int b){
  151. return ((uint128_t)(x) >> (n - b)) & 1;
  152. }
  153. void genDPF(EVP_CIPHER_CTX *ctx, int domainSize, uint128_t index, int dataSize, uint8_t* data, unsigned char** k0, unsigned char **k1){
  154. int maxLayer = domainSize;
  155. uint128_t s[maxLayer + 1][2];
  156. int t[maxLayer + 1 ][2];
  157. uint128_t sCW[maxLayer];
  158. int tCW[maxLayer][2];
  159. s[0][0] = getRandomBlock();
  160. s[0][1] = getRandomBlock();
  161. t[0][0] = 0;
  162. t[0][1] = 1;
  163. uint128_t s0[2], s1[2]; // 0=L,1=R
  164. int t0[2], t1[2];
  165. #define LEFT 0
  166. #define RIGHT 1
  167. for(int i = 1; i <= maxLayer; i++){
  168. dpfPRG(ctx, s[i-1][0], &s0[LEFT], &s0[RIGHT], &t0[LEFT], &t0[RIGHT]);
  169. dpfPRG(ctx, s[i-1][1], &s1[LEFT], &s1[RIGHT], &t1[LEFT], &t1[RIGHT]);
  170. int keep, lose;
  171. int indexBit = getbit(index, domainSize, i);
  172. if(indexBit == 0){
  173. keep = LEFT;
  174. lose = RIGHT;
  175. }else{
  176. keep = RIGHT;
  177. lose = LEFT;
  178. }
  179. sCW[i-1] = s0[lose] ^ s1[lose];
  180. tCW[i-1][LEFT] = t0[LEFT] ^ t1[LEFT] ^ indexBit ^ 1;
  181. tCW[i-1][RIGHT] = t0[RIGHT] ^ t1[RIGHT] ^ indexBit;
  182. if(t[i-1][0] == 1){
  183. s[i][0] = s0[keep] ^ sCW[i-1];
  184. t[i][0] = t0[keep] ^ tCW[i-1][keep];
  185. }else{
  186. s[i][0] = s0[keep];
  187. t[i][0] = t0[keep];
  188. }
  189. if(t[i-1][1] == 1){
  190. s[i][1] = s1[keep] ^ sCW[i-1];
  191. t[i][1] = t1[keep] ^ tCW[i-1][keep];
  192. }else{
  193. s[i][1] = s1[keep];
  194. t[i][1] = t1[keep];
  195. }
  196. }
  197. unsigned char *buff0;
  198. unsigned char *buff1;
  199. buff0 = (unsigned char*) malloc(1 + 16 + 1 + 18 * maxLayer + dataSize);
  200. buff1 = (unsigned char*) malloc(1 + 16 + 1 + 18 * maxLayer + dataSize);
  201. //take data, xor it with dataSize bits generated from s_0^n and another dataSize bits generated from s_1^n
  202. //use a counter mode encryption of 0 with each seed as key to get prg output
  203. uint8_t *lastCW = (uint8_t*) malloc(dataSize);
  204. uint8_t *convert0 = (uint8_t*) malloc(dataSize+16);
  205. uint8_t *convert1 = (uint8_t*) malloc(dataSize+16);
  206. uint8_t *zeros = (uint8_t*) malloc(dataSize+16);
  207. memset(zeros, 0, dataSize+16);
  208. memcpy(lastCW, data, dataSize);
  209. int len = 0;
  210. //generate dataSize length prg outputs from the seeds
  211. EVP_CIPHER_CTX *seedCtx0;
  212. EVP_CIPHER_CTX *seedCtx1;
  213. if(!(seedCtx0 = EVP_CIPHER_CTX_new()))
  214. printf("errors occured in creating context\n");
  215. if(!(seedCtx1 = EVP_CIPHER_CTX_new()))
  216. printf("errors occured in creating context\n");
  217. if(1 != EVP_EncryptInit_ex(seedCtx0, EVP_aes_128_ctr(), NULL, (uint8_t*)&s[maxLayer][0], NULL))
  218. printf("errors occured in init of dpf gen\n");
  219. if(1 != EVP_EncryptInit_ex(seedCtx1, EVP_aes_128_ctr(), NULL, (uint8_t*)&s[maxLayer][1], NULL))
  220. printf("errors occured in init of dpf gen\n");
  221. if(1 != EVP_EncryptUpdate(seedCtx0, convert0, &len, zeros, dataSize))
  222. printf("errors occured in encrypt\n");
  223. if(1 != EVP_EncryptUpdate(seedCtx1, convert1, &len, zeros, dataSize))
  224. printf("errors occured in encrypt\n");
  225. for(int i = 0; i < dataSize; i++){
  226. lastCW[i] = lastCW[i] ^ ((uint8_t*)convert0)[i] ^ ((uint8_t*)convert1)[i];
  227. }
  228. if(buff0 == NULL || buff1 == NULL){
  229. printf("Memory allocation failed\n");
  230. exit(1);
  231. }
  232. buff0[0] = domainSize;
  233. memcpy(&buff0[1], &s[0][0], 16);
  234. buff0[17] = t[0][0];
  235. for(int i = 1; i <= maxLayer; i++){
  236. memcpy(&buff0[18 * i], &sCW[i-1], 16);
  237. buff0[18 * i + 16] = tCW[i-1][0];
  238. buff0[18 * i + 17] = tCW[i-1][1];
  239. }
  240. memcpy(&buff0[18 * maxLayer + 18], lastCW, dataSize);
  241. buff1[0] = domainSize;
  242. memcpy(&buff1[18], &buff0[18], 18 * (maxLayer));
  243. memcpy(&buff1[1], &s[0][1], 16);
  244. buff1[17] = t[0][1];
  245. memcpy(&buff1[18 * maxLayer + 18], lastCW, dataSize);
  246. *k0 = buff0;
  247. *k1 = buff1;
  248. free(lastCW);
  249. free(convert0);
  250. free(convert1);
  251. free(zeros);
  252. EVP_CIPHER_CTX_free(seedCtx0);
  253. EVP_CIPHER_CTX_free(seedCtx1);
  254. }
  255. uint128_t evalDPF(EVP_CIPHER_CTX *ctx, unsigned char* k, uint128_t x, int dataSize, uint8_t* dataShare){
  256. //NOTE: if dataSize is not a multiple of 16, the size of dataShare should be
  257. //the next multiple of 16 after dataSize or else there is a memory bug.
  258. //Thanks to Emma Dauterman for pointing this out.
  259. //dataShare is of size dataSize
  260. int n = k[0];
  261. int maxLayer = n;
  262. uint128_t s[maxLayer + 1];
  263. int t[maxLayer + 1];
  264. uint128_t sCW[maxLayer];
  265. int tCW[maxLayer][2];
  266. memcpy(&s[0], &k[1], 16);
  267. t[0] = k[17];
  268. for(int i = 1; i <= maxLayer; i++){
  269. memcpy(&sCW[i-1], &k[18 * i], 16);
  270. tCW[i-1][0] = k[18 * i + 16];
  271. tCW[i-1][1] = k[18 * i + 17];
  272. }
  273. uint128_t sL, sR;
  274. int tL, tR;
  275. for(int i = 1; i <= maxLayer; i++){
  276. dpfPRG(ctx, s[i - 1], &sL, &sR, &tL, &tR);
  277. if(t[i-1] == 1){
  278. sL = sL ^ sCW[i-1];
  279. sR = sR ^ sCW[i-1];
  280. tL = tL ^ tCW[i-1][0];
  281. tR = tR ^ tCW[i-1][1];
  282. }
  283. int xbit = getbit(x, n, i);
  284. if(xbit == 0){
  285. s[i] = sL;
  286. t[i] = tL;
  287. }else{
  288. s[i] = sR;
  289. t[i] = tR;
  290. }
  291. }
  292. //get the data share out
  293. int len = 0;
  294. uint8_t *zeros = (uint8_t*) malloc(dataSize+16);
  295. memset(zeros, 0, dataSize+16);
  296. //use a counter mode encryption of 0 with each seed as key to get prg output
  297. //printf("here\n");
  298. EVP_CIPHER_CTX *seedCtx;
  299. if(!(seedCtx = EVP_CIPHER_CTX_new()))
  300. printf("errors occured in creating context\n");
  301. if(1 != EVP_EncryptInit_ex(seedCtx, EVP_aes_128_ctr(), NULL, (uint8_t*)&s[maxLayer], NULL))
  302. printf("errors occured in init of dpf eval\n");
  303. if(1 != EVP_EncryptUpdate(seedCtx, dataShare, &len, zeros, ((dataSize-1)|15)+1))
  304. printf("errors occured in encrypt\n");
  305. for(int i = 0; i < dataSize; i++){
  306. if(t[maxLayer] == 1){
  307. //xor in correction word
  308. dataShare[i] = dataShare[i] ^ k[18*n+18+i];
  309. //printf("xoring stuff in at index %d\n", i);
  310. }
  311. //printf("%x\n", (*dataShare)[i]);
  312. }
  313. free(zeros);
  314. EVP_CIPHER_CTX_free(seedCtx);
  315. //print_block(s[maxLayer]);
  316. //printf("%x\n", t[maxLayer]);
  317. //use the last seed for dpf checking
  318. return s[maxLayer];
  319. }
  320. //use the correllated randomness so that servers and user pick same randomness
  321. //this is the PRF for dpf checking
  322. void PRF(EVP_CIPHER_CTX *ctx, uint128_t seed, int layer, int count, uint128_t* output){
  323. int len = 0;
  324. uint128_t input = seed;
  325. int tries = 0;
  326. //xor count with 32 bits of input and layer with next 32 bits.
  327. //count = -1 is for determining whether to swap or not when shuffling halves
  328. // if output mod 2 == 1, then user/servers will swap
  329. int* temp;
  330. temp = (int*)&input;
  331. temp[0] = temp[0] ^ count;
  332. temp[1] = temp[1] ^ layer;
  333. uint128_t stash = 0;
  334. do{
  335. temp[2] = temp[2] ^ tries;
  336. uint128_t stashin = input;
  337. if(1 != EVP_EncryptUpdate(ctx, (uint8_t*)&stash, &len, (uint8_t*)&stashin, 16))
  338. printf("errors occured in encrypt\n");
  339. stash = stash ^ input;
  340. tries++;
  341. //drop blocks that are not in Z_p when count is not -1
  342. } while(count != -1 && stash + MODP < stash);
  343. *output = stash;
  344. }
  345. void clientGenProof(EVP_CIPHER_CTX *ctx, uint128_t seed, int index, uint128_t aShare, uint128_t bShare, uint8_t* outputsAIn, uint8_t* outputsBIn){
  346. uint128_t *outputsA = (uint128_t*) outputsAIn;
  347. uint128_t *outputsB = (uint128_t*) outputsBIn;
  348. //outputs will hold the following items in the following order
  349. //this comes out to 10 values
  350. //outputs for server A of the first multiplication proof (cc)
  351. //f0amult1 (index) 0
  352. //g0amult1 1
  353. //h0amult1 2
  354. //h1amult1 3
  355. //h2amult1 4
  356. //outputs for server A of the second multiplication proof (mC)
  357. //f0amult2 5
  358. //g0amult2 6
  359. //h0amult2 7
  360. //h1amult2 8
  361. //h2amult2 9
  362. //all the same things needed for server B as well
  363. //client generates a bunch of randomness and assigns most of the outputs
  364. //whp these are all in the field we're using
  365. for(int i = 0; i < 10; i++){
  366. outputsB[i] = getRandomBlock();
  367. }
  368. outputsA[0] = getRandomBlock();
  369. outputsA[1] = getRandomBlock();
  370. outputsA[5] = getRandomBlock();
  371. outputsA[6] = getRandomBlock();
  372. //find f0,g0 based on randomness generated above
  373. uint128_t f0mult1 = subModP(outputsA[0], outputsB[0]);
  374. uint128_t g0mult1 = subModP(outputsA[1], outputsB[1]);
  375. uint128_t f0mult2 = subModP(outputsA[5], outputsB[5]);
  376. uint128_t g0mult2 = subModP(outputsA[6], outputsB[6]);
  377. //find f1,g1 (shortcut since client knows non-zero index)
  378. uint128_t rvalue;
  379. PRF(ctx, seed, 0, index, &rvalue);
  380. uint128_t f1mult1 = multModP(subModP(aShare, bShare), rvalue);
  381. uint128_t g1mult1 = f1mult1;
  382. uint128_t f1mult2 = subModP(aShare, bShare);
  383. uint128_t g1mult2 = f1mult1;
  384. //printf("value for m on client side"); print_block(f1mult2);
  385. //printf("value for c on client side");print_block(f1mult1);
  386. //calculate h0,h1 values by multiplying
  387. uint128_t h0mult1 = multModP(f0mult1,g0mult1);
  388. uint128_t h0mult2 = multModP(f0mult2,g0mult2);
  389. uint128_t h1mult1 = multModP(f1mult1,g1mult1);
  390. uint128_t h1mult2 = multModP(f1mult2,g1mult2);
  391. //put shares of h0,h1 in output
  392. outputsA[2] = addModP(h0mult1, outputsB[2]);
  393. outputsA[7] = addModP(h0mult2, outputsB[7]);
  394. outputsA[3] = addModP(h1mult1, outputsB[3]);
  395. outputsA[8] = addModP(h1mult2, outputsB[8]);
  396. //find f2,g2
  397. uint128_t two = 2;
  398. uint128_t f2mult1 = evalLinearR(two, f0mult1, f1mult1);
  399. uint128_t g2mult1 = evalLinearR(two, g0mult1, g1mult1);
  400. uint128_t f2mult2 = evalLinearR(two, f0mult2, f1mult2);
  401. uint128_t g2mult2 = evalLinearR(two, g0mult2, g1mult2);
  402. //calculate h2 values by multiplying
  403. uint128_t h2mult1 = multModP(f2mult1,g2mult1);
  404. uint128_t h2mult2 = multModP(f2mult2,g2mult2);
  405. //put shares of h2 in output
  406. outputsA[4] = addModP(h2mult1, outputsB[4]);
  407. outputsA[9] = addModP(h2mult2, outputsB[9]);
  408. /*
  409. //for testing, trying to produce output of proof
  410. //compute f(r), g(r)
  411. uint128_t frmult1 = evalLinearR(10, f0mult1, f1mult1);
  412. uint128_t grmult1 = evalLinearR(10, g0mult1, g1mult1);
  413. uint128_t frmult2 = evalLinearR(10, f0mult2, f1mult2);
  414. uint128_t grmult2 = evalLinearR(10, g0mult2, g1mult2);
  415. //compute h(r)
  416. uint128_t hrmult1 = evalQuadraticR(10, h0mult1, h1mult1, h2mult1);
  417. uint128_t hrmult2 = evalQuadraticR(10, h0mult2, h1mult2, h2mult2);
  418. printf("values: ");
  419. printf("\nf1: ");print_block(frmult1);
  420. printf("\ng1: ");print_block(grmult1);
  421. printf("\nh1: ");print_block(hrmult1);
  422. printf("\nf2: ");print_block(frmult2);
  423. printf("\ng2: ");print_block(grmult2);
  424. printf("\nh2: ");print_block(hrmult2);
  425. */
  426. }
  427. void serverSetupProof(EVP_CIPHER_CTX *ctx, uint8_t *seedIn, int dbSize, uint8_t* vectorsIn, uint8_t* mIn, uint8_t* cIn){
  428. uint128_t* m = (uint128_t*) mIn;
  429. uint128_t* c = (uint128_t*) cIn;
  430. uint128_t* vectors = (uint128_t*) vectorsIn;
  431. uint128_t seed;
  432. memcpy(&seed, seedIn, 16);
  433. uint128_t prfOutput;
  434. uint128_t workingM = 0;
  435. uint128_t workingC = 0;
  436. for(int i = 0; i < dbSize; i++){
  437. PRF(ctx, seed, 0, i, &prfOutput);
  438. workingM = addModP(workingM, vectors[i]);
  439. workingC = addModP(workingC, multModP(vectors[i], prfOutput));
  440. }
  441. memcpy(m, &workingM, 16);
  442. memcpy(c, &workingC, 16);
  443. }
  444. void serverComputeQuery(EVP_CIPHER_CTX *ctx, uint8_t *seedIn, uint8_t* mIn, uint8_t* cIn, uint8_t* proofIn, uint8_t* ansIn){
  445. uint128_t* m = (uint128_t*) mIn;
  446. uint128_t* c = (uint128_t*) cIn;
  447. uint128_t* proof = (uint128_t*) proofIn;
  448. uint128_t* ans = (uint128_t*) ansIn;
  449. uint128_t seed;
  450. memcpy(&seed, seedIn, 16);
  451. //including this just for readability
  452. uint128_t f0mult1 = proof[0];
  453. uint128_t g0mult1 = proof[1];
  454. uint128_t h0mult1 = proof[2];
  455. uint128_t h1mult1 = proof[3];
  456. uint128_t h2mult1 = proof[4];
  457. uint128_t f0mult2 = proof[5];
  458. uint128_t g0mult2 = proof[6];
  459. uint128_t h0mult2 = proof[7];
  460. uint128_t h1mult2 = proof[8];
  461. uint128_t h2mult2 = proof[9];
  462. //generate a random point r from seed
  463. uint128_t r1, r2;
  464. PRF(ctx, seed, 1, 0, &r1);
  465. PRF(ctx, seed, 2, 0, &r2);
  466. //for testing
  467. //r1 = 10;
  468. //r2 = 10;
  469. //compute f(r), g(r)
  470. uint128_t frmult1 = evalLinearR(r1, f0mult1, *c);
  471. uint128_t grmult1 = evalLinearR(r1, g0mult1, *c);
  472. uint128_t frmult2 = evalLinearR(r2, f0mult2, *m);
  473. uint128_t grmult2 = evalLinearR(r2, g0mult2, *c);
  474. //compute h(r)
  475. uint128_t hrmult1 = evalQuadraticR(r1, h0mult1, h1mult1, h2mult1);
  476. uint128_t hrmult2 = evalQuadraticR(r2, h0mult2, h1mult2, h2mult2);
  477. //set the appropriate elements of ans (6 elements)
  478. ans[0] = frmult1;
  479. ans[1] = grmult1;
  480. ans[2] = hrmult1;
  481. ans[3] = frmult2;
  482. ans[4] = grmult2;
  483. ans[5] = hrmult2;
  484. }
  485. int serverVerifyProof(uint8_t* ans1In, uint8_t* ans2In){
  486. uint128_t* ans1 = (uint128_t*) ans1In;
  487. uint128_t* ans2 = (uint128_t*) ans2In;
  488. uint128_t f1 = subModP(ans1[0], ans2[0]);
  489. uint128_t g1 = subModP(ans1[1], ans2[1]);
  490. uint128_t h1 = subModP(ans1[2], ans2[2]);
  491. uint128_t f2 = subModP(ans1[3], ans2[3]);
  492. uint128_t g2 = subModP(ans1[4], ans2[4]);
  493. uint128_t h2 = subModP(ans1[5], ans2[5]);
  494. uint128_t prod1 = multModP(f1, g1);
  495. uint128_t prod2 = multModP(f2, g2);
  496. /*
  497. printf("recovered values: ");
  498. printf("\nf1: ");print_block(f1);
  499. printf("\ng1: ");print_block(g1);
  500. printf("\nh1: ");print_block(h1);
  501. printf("\nf2: ");print_block(f2);
  502. printf("\ng2: ");print_block(g2);
  503. printf("\nh2: ");print_block(h2);
  504. printf("\n\nprod1: ");print_block(prod1);
  505. printf("\nprod2: ");print_block(prod2);
  506. */
  507. int pass = (memcmp(&prod1, &h1, 16) == 0) && (memcmp(&prod2, &h2, 16) == 0);
  508. return pass;
  509. }
  510. uint128_t evalLinearR(uint128_t r, uint128_t p0, uint128_t p1){
  511. uint128_t slope = subModP(p1, p0);
  512. uint128_t pr = addModP(multModP(slope, r), p0);
  513. return pr;
  514. }
  515. uint128_t evalQuadraticR(uint128_t r, uint128_t h0, uint128_t h1, uint128_t h2){
  516. // h(r) = (1/2)(r-1)(r-2)h0 - r(r-2)h1 + (1/2)r(r-1)h2
  517. //(1/2)(r-1)(r-2)h0
  518. uint128_t t0 = 0;
  519. if(r%2 == 0) {
  520. t0 = multModP(h0, multModP(r-1, (r-2)/2));
  521. }
  522. else{
  523. t0 = multModP(h0, multModP((r-1)/2, r-2));
  524. }
  525. //r(r-2)h1
  526. uint128_t t1 = multModP(multModP(r, r-2), h1);
  527. //(1/2)r(r-1)h2
  528. uint128_t t2 = 0;
  529. if(r%2 == 0) {
  530. t2 = multModP(h2, multModP(r-1, r/2));
  531. }
  532. else{
  533. t2 = multModP(h2, multModP((r-1)/2, r));
  534. }
  535. //final sum
  536. uint128_t ret = addModP(subModP(t0, t1), t2);
  537. }
  538. //client check inputs
  539. 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){
  540. uint128_t *nonZeroVectors = (uint128_t*) nonZeroVectorsIn;
  541. //note that index is the actual index, not the virtual address, in our application to oblivious key value stores
  542. //printf("clientVerify\n");
  543. //set bits vector to all zeros
  544. memset(bits, 0, dbLayers);
  545. //#pragma omp parallel for
  546. for(int i = 0; i < dbLayers; i++){
  547. uint128_t whenToSwap;
  548. int newIndex;
  549. int oldIndex;
  550. //set newAlphaIndex
  551. oldIndex = index % (1<<(dbLayers - i));
  552. newIndex = index % (1<<(dbLayers - i - 1));
  553. //if the index has changed, then the nonzero value was in the second half
  554. if(newIndex != oldIndex){
  555. bits[i] = 1;
  556. }
  557. //printf("bits %d before potential flip: %d\n", i, bits[i]);
  558. //check if the halves will be swapped and set the entry of bits
  559. PRF(ctx, seed, i, -1, &whenToSwap);
  560. bits[i] = bits[i] ^ ((uint128_t)whenToSwap % 2);
  561. uint128_t temp;
  562. uint128_t temp2;
  563. //check the mask value and set entry of nonZeroVectors
  564. PRF(ctx, seed, i, oldIndex, &temp);
  565. temp2 = multModP(subModP(aShare, bShare), temp);
  566. memcpy(&nonZeroVectors[i], &temp2, 16);
  567. }
  568. }
  569. //server check inputs
  570. void serverVerify(EVP_CIPHER_CTX *ctx, uint8_t *seedIn, int dbLayers, int dbSize, uint8_t* vectorsIn, uint8_t* outVectorsIn){
  571. //outVectors should be of length 2*dbLayers since there are 2 sums per layer
  572. //printf("serverVerify\n");
  573. //don't modify vectors -- it should be treated as read-only, so make a copy
  574. //uint128_t* vectorsWorkSpace = malloc(dbSize*sizeof(uint128_t));
  575. //memcpy(vectorsWorkSpace, vectors, dbSize*sizeof(uint128_t));
  576. uint128_t *vectors = (uint128_t*) vectorsIn;
  577. uint128_t *outVectors = (uint128_t*) outVectorsIn;
  578. uint128_t seed;
  579. memcpy(&seed, seedIn, 16);
  580. uint128_t* vectorsWorkSpace = vectors;
  581. uint128_t prfOutput;
  582. uint128_t leftSum, rightSum;
  583. int newDbSize = dbSize;
  584. //#pragma omp declare reduction(ADDMODP: uint128_t : omp_out += omp_in + (omp_out + omp_in < omp_out || omp_out+omp_in > 0-MODP)*MODP)
  585. for(int i = 0; i < dbLayers; i++){
  586. leftSum = 0;
  587. rightSum = 0;
  588. //multiply each element by a ``random'' value and add into the appropriate sum
  589. //#pragma omp parallel for \
  590. // default(shared) private(prfOutput) \
  591. // reduction(ADDMODP:rightSum,leftSum)
  592. for(int j = 0; j < newDbSize; j++){
  593. PRF(ctx, seed, i, j, &prfOutput);
  594. if(j >= (1<<(dbLayers - i - 1))){ //if j is in right half
  595. //rightSum = multModP(vectorsWorkSpace[j], prfOutput);
  596. //printf("ladeeda%d\n", j);
  597. //use line commented below when compiling without openmp
  598. //looks like it actually works with openmp too!
  599. rightSum = addModP(rightSum, multModP(vectorsWorkSpace[j], prfOutput));
  600. }
  601. else{ // j is in left half
  602. //leftSum = multModP(vectorsWorkSpace[j], prfOutput);
  603. //printf("ladeedee%d\n", j);
  604. //use line commented below when compiling without openmp
  605. //looks like it actually works with openmp too!
  606. leftSum = addModP(leftSum, multModP(vectorsWorkSpace[j], prfOutput));
  607. }
  608. }
  609. //printf("\n");
  610. //add together left and right halves for next iteration
  611. //#pragma omp parallel for
  612. for(int j = 1<<(dbLayers - i - 1); j < newDbSize; j++){
  613. vectorsWorkSpace[j - (1<<(dbLayers - i - 1))] = addModP(vectorsWorkSpace[j - (1<<(dbLayers - i - 1))], vectorsWorkSpace[j]);
  614. }
  615. //adjust newDbSize for next round
  616. newDbSize = 1 << (dbLayers - (i+1));
  617. //check if the halves will be swapped and place the sums in the appropriate spots
  618. PRF(ctx, seed, i, -1, &prfOutput);
  619. if((uint128_t)prfOutput % 2 == 0){
  620. memcpy(&outVectors[2*i], &leftSum, 16);
  621. memcpy(&outVectors[2*i+1], &rightSum, 16);
  622. }
  623. else{
  624. memcpy(&outVectors[2*i], &rightSum, 16);
  625. memcpy(&outVectors[2*i+1], &leftSum, 16);
  626. }
  627. //print_block(rightSum);
  628. //print_block(leftSum);
  629. }
  630. //free(vectorsWorkSpace);
  631. }
  632. //auditor functionality
  633. int auditorVerify(int dbLayers, uint8_t* bits, uint8_t* nonZeroVectorsIn, uint8_t* outVectorsAIn, uint8_t* outVectorsBIn){
  634. uint128_t *nonZeroVectors = (uint128_t*)nonZeroVectorsIn;
  635. uint128_t *outVectorsA = (uint128_t*)outVectorsAIn;
  636. uint128_t *outVectorsB = (uint128_t*)outVectorsBIn;
  637. //printf("auditorVerify\n");
  638. int pass = 1; //set this to 0 if any check fails
  639. uint128_t zero = 0;
  640. //#pragma omp parallel for
  641. for(int i = 0; i < dbLayers; i++){
  642. uint128_t mergeAB[2];
  643. //merge the output vectors to get the values
  644. mergeAB[0] = subModP(outVectorsA[2*i], outVectorsB[2*i]);
  645. mergeAB[1] = subModP(outVectorsA[2*i+1], outVectorsB[2*i+1]);
  646. //printf("%d %lu, %lu, %lu, %lu\n", i, outVectorsA[2*i], outVectorsA[2*i+1], outVectorsB[2*i], outVectorsB[2*i+1]);
  647. //first check that the appropriate side is 0
  648. //only need to check AB since if it is 0 then so is BA
  649. //then check that the other side is equal to the corresponding nonZeroVectors entry for one direction
  650. if( memcmp(&mergeAB[1-bits[i]], &zero, 16) != 0 || (
  651. memcmp(&mergeAB[bits[i]], &nonZeroVectors[i], 16) != 0
  652. )){
  653. printf("fail conditions in round %d: %d %d \n", i, memcmp(&mergeAB[1-bits[i]], &zero, 16), memcmp(&mergeAB[bits[i]], &nonZeroVectors[i], 16));
  654. printf("auditor expected to see \n");print_block(nonZeroVectors[i]);
  655. printf("but auditor saw \n");print_block(mergeAB[bits[i]]);
  656. printf("difference \n"); print_block(nonZeroVectors[i] - mergeAB[bits[i]]);print_block(mergeAB[bits[i]] - nonZeroVectors[i]);
  657. pass = 0;
  658. }
  659. }
  660. return pass;
  661. }
  662. void digest_message(const unsigned char *message, size_t message_len, unsigned char **digest, unsigned int *digest_len)
  663. {
  664. EVP_MD_CTX *mdctx;
  665. if((mdctx = EVP_MD_CTX_create()) == NULL)
  666. printf("digest error\n");
  667. if(1 != EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL))
  668. printf("digest error\n");
  669. if(1 != EVP_DigestUpdate(mdctx, message, message_len))
  670. printf("digest error\n");
  671. if((*digest = (unsigned char *)OPENSSL_malloc(EVP_MD_size(EVP_sha256()))) == NULL)
  672. printf("digest error\n");
  673. if(1 != EVP_DigestFinal_ex(mdctx, *digest, digest_len))
  674. printf("digest error\n");
  675. EVP_MD_CTX_destroy(mdctx);
  676. }
  677. void riposteClientVerify(EVP_CIPHER_CTX *ctx, uint128_t seed, int dbSize, uint128_t *va, uint128_t *vb, uint8_t **digestA, uint8_t **digestB){
  678. uint128_t *mVectorA = (uint128_t*) malloc(dbSize*16);
  679. uint128_t *mVectorB = (uint128_t*) malloc(dbSize*16);
  680. uint128_t prfOutput;
  681. //#pragma omp parallel for \
  682. //default(shared) private(prfOutput)
  683. for(int i = 0; i < dbSize; i++){
  684. PRF(ctx, seed, 0, i, &prfOutput);
  685. mVectorA[i] = va[i] ^ prfOutput;
  686. mVectorB[i] = vb[i] ^ prfOutput;
  687. }
  688. int len = 0;
  689. digest_message((uint8_t*)mVectorA, dbSize*16, digestA, &len);
  690. digest_message((uint8_t*)mVectorB, dbSize*16, digestB, &len);
  691. free(mVectorA);
  692. free(mVectorB);
  693. }
  694. void riposteServerVerify(EVP_CIPHER_CTX *ctx, uint128_t seed, int dbSize, uint128_t *vector, uint128_t *mVector, uint128_t *cValue){
  695. PRF(ctx, seed, 1, 0, cValue);
  696. uint128_t prfOutput;
  697. //#pragma omp parallel for \
  698. //default(shared) private(prfOutput)
  699. for(int i = 0; i < dbSize; i++){
  700. PRF(ctx, seed, 0, i, &prfOutput);
  701. mVector[i] = vector[i] ^ prfOutput;
  702. }
  703. }
  704. int riposteAuditorVerify(uint8_t *digestA, uint8_t *digestB, uint8_t *ma, uint8_t *mb, uint128_t ca, uint128_t cb, int dbSize){
  705. int pass = 1;
  706. //check that the masked seeds are equal
  707. if(ca != cb){
  708. printf("failed audit, masked seeds unequal\n");
  709. pass = 0;
  710. }
  711. //check that m vectors differ in only 1 place
  712. int differenceCount = 0;
  713. //#pragma omp parallel for
  714. for(int i = 0; i < dbSize; i++) {
  715. if(memcmp(&ma[i*16], &mb[i*16], 16) != 0){
  716. //#pragma omp critical
  717. differenceCount++;
  718. }
  719. }
  720. if(differenceCount != 1){
  721. printf("failed audit, difference count incorrect %d\n", differenceCount);
  722. pass = 0;
  723. }
  724. //check that the digests match their expected values
  725. int len = 0;
  726. uint8_t *newDigestA = (uint8_t*)malloc(32);
  727. uint8_t *newDigestB = (uint8_t*)malloc(32);
  728. digest_message(ma, dbSize*16, &newDigestA, &len);
  729. digest_message(mb, dbSize*16, &newDigestB, &len);
  730. if(memcmp(digestA, newDigestA, 32) != 0 || memcmp(digestB, newDigestB, 32) != 0){
  731. printf("failed audit, digest mismatch %d %d\n", memcmp(digestA, newDigestA, 32), memcmp(digestB, newDigestB, 32) != 0);
  732. pass = 0;
  733. }
  734. free(newDigestA);
  735. free(newDigestB);
  736. return pass;
  737. }
  738. int dpf_tests(){
  739. //int main(){
  740. //pick 2 64-bit values as a fixed aes key
  741. //and use those values to key the aes we will be using as a PRG
  742. EVP_CIPHER_CTX *ctx;
  743. if(!(ctx = EVP_CIPHER_CTX_new()))
  744. printf("errors occured in creating context\n");
  745. unsigned char *aeskey = (unsigned char*) "0123456789123456";
  746. if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, aeskey, NULL))
  747. printf("errors occured in init\n");
  748. EVP_CIPHER_CTX_set_padding(ctx, 0);
  749. //printf("mult test: %d", multModP((uint128_t)5<<125,((uint128_t)6)<<125)); return 0;
  750. //generate DPF keys for a particular query
  751. unsigned char *k0;
  752. unsigned char *k1;
  753. //functionality test for dpf
  754. char* data = "this is the data!";
  755. int dataSize = strlen(data)+1;
  756. //can only test with smaller constants because
  757. //gcc does not support 128 bit constants
  758. genDPF(ctx, 128, 300, dataSize, data, &k0, &k1);
  759. //evaluate dpf
  760. uint128_t res1;
  761. uint128_t res2;
  762. uint8_t* dataShare0 = (uint8_t*) malloc(dataSize+16);
  763. uint8_t* dataShare1 = (uint8_t*) malloc(dataSize+16);
  764. res1 = evalDPF(ctx, k0, 12, dataSize, dataShare0);
  765. res2 = evalDPF(ctx, k1, 12, dataSize, dataShare1);
  766. printf("\nresult evaluated at 12: ");
  767. print_block(res1 ^ res2);
  768. res1 = evalDPF(ctx, k0, 300, dataSize, dataShare0);
  769. res2 = evalDPF(ctx, k1, 300, dataSize, dataShare1);
  770. printf("\nresult evaluated at 300: ");
  771. print_block(res1 ^ res2);
  772. uint8_t* recoveredData = (uint8_t*) malloc(dataSize);
  773. printf("data recovered: ");
  774. for(int i = 0; i < dataSize; i++){
  775. recoveredData[i] = dataShare0[i] ^ dataShare1[i];
  776. printf("%c", recoveredData[i]);
  777. //printf("%x\n", dataShare1[i]);
  778. }
  779. printf("\n");
  780. //return 0;
  781. //now we'll do a simple functionality test of the dpf checking.
  782. //this will in no way be rigorous or even representative of the
  783. //usual use case since all the evaluation points are small
  784. //just a sanity check before moving on to the obliv key val stuff
  785. uint128_t db[] = {4343423, 232132, 465437, 43, 300, 5346643};
  786. int dbSize = 6;
  787. int dbLayers = 3;
  788. uint128_t* seed = malloc(sizeof(uint128_t));
  789. *seed = getRandomBlock();
  790. //allocate the various arrays we will need
  791. uint8_t* bits = malloc(dbLayers);
  792. uint128_t* nonZeroVectors = malloc(sizeof(uint128_t)*dbLayers);
  793. uint128_t* vectorsA = malloc(sizeof(uint128_t)*dbSize);
  794. uint128_t* vectorsB = malloc(sizeof(uint128_t)*dbSize);
  795. uint128_t* outVectorsA = malloc(sizeof(uint128_t)*2*dbLayers);
  796. uint128_t* outVectorsB = malloc(sizeof(uint128_t)*2*dbLayers);
  797. //evaluate the db at each point for each server
  798. //#pragma omp parallel for
  799. for(int i = 0; i < dbSize; i++){
  800. uint128_t res1, res2;
  801. res1 = evalDPF(ctx, k0, db[i], dataSize, dataShare0);
  802. res2 = evalDPF(ctx, k1, db[i], dataSize, dataShare1);
  803. memcpy(&vectorsA[i], &res1, 16);
  804. memcpy(&vectorsB[i], &res2, 16);
  805. }
  806. uint128_t* proofA = (uint128_t*)malloc(sizeof(uint128_t)*10);
  807. uint128_t* proofB = (uint128_t*)malloc(sizeof(uint128_t)*10);
  808. uint128_t* ansA = (uint128_t*)malloc(sizeof(uint128_t)*6);
  809. uint128_t* ansB = (uint128_t*)malloc(sizeof(uint128_t)*6);
  810. uint128_t mA, cA, mB, cB;
  811. //run the dpf verification functions
  812. clientGenProof(ctx, *seed, 4, vectorsA[4], vectorsB[4], (uint8_t*)proofA, (uint8_t*)proofB);
  813. serverSetupProof(ctx, (uint8_t*)seed, dbSize, (uint8_t*) vectorsA, (uint8_t*)&mA, (uint8_t*) &cA);
  814. serverSetupProof(ctx, (uint8_t*)seed, dbSize, (uint8_t*) vectorsB, (uint8_t*)&mB, (uint8_t*) &cB);
  815. //printf("m on server side"); print_block(subModP(mA,mB));
  816. //printf("c on server side");print_block(subModP(cA,cB));
  817. serverComputeQuery(ctx, (uint8_t*)seed, (uint8_t*)&mA, (uint8_t*) &cA, (uint8_t*)proofA, (uint8_t*) ansA);
  818. serverComputeQuery(ctx, (uint8_t*)seed, (uint8_t*)&mB, (uint8_t*) &cB, (uint8_t*)proofB, (uint8_t*) ansB);
  819. int pass = -1;
  820. pass = serverVerifyProof((uint8_t*) ansA, (uint8_t*) ansB);
  821. printf("dpf check verification: %d (should be 1)\n", pass);
  822. //now test the riposte auditing
  823. free(outVectorsA);
  824. free(outVectorsB);
  825. outVectorsA = malloc(sizeof(uint128_t)*dbSize);
  826. outVectorsB = malloc(sizeof(uint128_t)*dbSize);
  827. uint128_t cValueA = 0;
  828. uint128_t cValueB = 0;
  829. uint8_t *digestA = (uint8_t*) malloc(32);
  830. uint8_t *digestB = (uint8_t*) malloc(32);
  831. riposteClientVerify(ctx, *seed, dbSize, vectorsA, vectorsB, &digestA, &digestB);
  832. riposteServerVerify(ctx, *seed, dbSize, vectorsA, outVectorsA, &cValueA);
  833. riposteServerVerify(ctx, *seed, dbSize, vectorsB, outVectorsB, &cValueB);
  834. pass = riposteAuditorVerify(digestA, digestB, (uint8_t*)outVectorsA, (uint8_t*)outVectorsB, cValueA, cValueB, dbSize);
  835. printf("riposte dpf check verification: %d (should be 1)\n", pass);
  836. //tamper with dpf outputs to see if auditor catches it
  837. //memcpy(&outVectorsB[2], &outVectorsA[1], 16);
  838. //pass = riposteAuditorVerify(digestA, digestB, (uint8_t*)outVectorsA, (uint8_t*)outVectorsB, cValueA, cValueB, dbSize);
  839. //printf("riposte dpf check verification: %d (should be 0)\n", pass);
  840. //return 0;
  841. //performance test of dpf verification
  842. int dbSizes[4];
  843. dbSizes[0] = 1000;
  844. dbSizes[1] = 10000;
  845. dbSizes[2] = 100000;
  846. dbSizes[3] = 1000000;
  847. int dbLayer[4];
  848. dbLayer[0] = 10;
  849. dbLayer[1] = 14;
  850. dbLayer[2] = 17;
  851. dbLayer[3] = 20;
  852. clock_t begin, elapsed;
  853. seed = malloc(sizeof(uint128_t));
  854. *seed = getRandomBlock();
  855. vectorsA = malloc(sizeof(uint128_t)*dbSizes[3]);
  856. vectorsB = malloc(sizeof(uint128_t)*dbSizes[3]);
  857. memset(vectorsA,'a',dbSizes[3]*16);
  858. memset(vectorsB,'a',dbSizes[3]*16);
  859. vectorsA[10] = 13;
  860. vectorsB[10] = 12;
  861. /*
  862. void clientGenProof(EVP_CIPHER_CTX *ctx, uint128_t seed, int index, uint128_t aShare, uint128_t bShare, uint8_t* outputsAIn, uint8_t* outputsBIn);
  863. void serverSetupProof(EVP_CIPHER_CTX *ctx, uint8_t *seedIn, int dbSize, uint8_t* vectorsIn, uint8_t* mIn, uint8_t* cIn);
  864. void serverComputeQuery(EVP_CIPHER_CTX *ctx, uint8_t *seedIn, uint8_t* mIn, uint8_t* cIn, uint8_t* proofIn, uint8_t* ansIn);
  865. int serverVerifyProof(uint8_t* ans1In, uint8_t* ans2In);
  866. */
  867. //us
  868. for(int i = 0; i < 4; i++){
  869. proofA = (uint128_t*)malloc(sizeof(uint128_t)*10);
  870. proofB = (uint128_t*)malloc(sizeof(uint128_t)*10);
  871. ansA = (uint128_t*)malloc(sizeof(uint128_t)*6);
  872. ansB = (uint128_t*)malloc(sizeof(uint128_t)*6);
  873. uint128_t mA, cA, mB, cB;
  874. begin = clock();
  875. clientGenProof(ctx, *seed, 10, vectorsA[10], vectorsB[10], (uint8_t*)proofA, (uint8_t*)proofB);
  876. elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
  877. printf("client proof gen time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
  878. begin = clock();
  879. serverSetupProof(ctx, (uint8_t*)seed, dbSizes[i], (uint8_t*)vectorsA, (uint8_t*)&mA, (uint8_t*)&cA);
  880. elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
  881. printf("server prep time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
  882. serverSetupProof(ctx, (uint8_t*)seed, dbSizes[i], (uint8_t*)vectorsB, (uint8_t*)&mB, (uint8_t*)&cB);
  883. begin = clock();
  884. serverComputeQuery(ctx, (uint8_t*)seed, (uint8_t*)&mA, (uint8_t*)&cA, (uint8_t*)proofA, (uint8_t*)ansA);
  885. elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
  886. printf("server query time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
  887. serverComputeQuery(ctx, (uint8_t*)seed, (uint8_t*)&mB, (uint8_t*)&cB, (uint8_t*)proofB, (uint8_t*)ansB);
  888. pass = 0;
  889. begin = clock();
  890. pass = serverVerifyProof((uint8_t*)ansA,(uint8_t*)ansB);
  891. elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
  892. printf("server verification time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
  893. if(pass == 0){
  894. printf("dpf check verification failed %d\n", i);
  895. }
  896. free(proofA);
  897. free(proofB);
  898. free(ansA);
  899. free(ansB);
  900. }
  901. //riposte
  902. for(int i = 0; i < 4; i++){ //something went wrong at 4
  903. outVectorsA = malloc(sizeof(uint128_t)*dbSizes[i]);
  904. outVectorsB = malloc(sizeof(uint128_t)*dbSizes[i]);
  905. cValueA = 0;
  906. cValueB = 0;
  907. digestA = (uint8_t*) malloc(32);
  908. digestB = (uint8_t*) malloc(32);
  909. begin = clock();
  910. riposteClientVerify(ctx, *seed, dbSizes[i], vectorsA, vectorsB, &digestA, &digestB);
  911. elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
  912. printf("riposte client verification time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
  913. begin = clock();
  914. riposteServerVerify(ctx, *seed, dbSizes[i], vectorsA, outVectorsA, &cValueA);
  915. elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
  916. printf("riposte server verification time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
  917. riposteServerVerify(ctx, *seed, dbSizes[i], vectorsB, outVectorsB, &cValueB);
  918. pass = 0;
  919. begin = clock();
  920. pass = riposteAuditorVerify(digestA, digestB, (uint8_t*)outVectorsA, (uint8_t*)outVectorsB, cValueA, cValueB, dbSizes[i]);
  921. elapsed = (clock() - begin) * 1000000 / CLOCKS_PER_SEC;
  922. printf("riposte auditor verification time for db size %d: %ld microseconds\n", dbSizes[i], elapsed);
  923. if(pass == 0){
  924. printf("riposte dpf check verification failed %d\n", i);
  925. }
  926. free(outVectorsA);
  927. free(outVectorsB);
  928. free(digestA);
  929. free(digestB);
  930. }
  931. free(vectorsA);
  932. free(vectorsB);
  933. return 0;
  934. //performance test of the dpf
  935. char *s[10];
  936. s[0] = (char*) malloc(2);
  937. s[1] = (char*) malloc(16);
  938. s[2] = (char*) malloc(100);
  939. s[3] = (char*) malloc(1000);
  940. s[4] = (char*) malloc(10000);
  941. s[5] = (char*) malloc(100000);
  942. s[6] = (char*) malloc(1000000);
  943. memset(s[0], 'a', 1);
  944. memset(s[0]+1, '\0', 1);
  945. memset(s[1], 'a', 15);
  946. memset(s[1]+15, '\0', 1);
  947. memset(s[2], 'a', 99);
  948. memset(s[2]+99, '\0', 1);
  949. memset(s[3], 'a', 999);
  950. memset(s[3]+999, '\0', 1);
  951. memset(s[4], 'a', 9999);
  952. memset(s[4]+9999, '\0', 1);
  953. memset(s[5], 'a', 99999);
  954. memset(s[5]+99999, '\0', 1);
  955. memset(s[6], 'a', 999999);
  956. memset(s[6]+999999, '\0', 1);
  957. free(dataShare0);
  958. free(dataShare1);
  959. free(recoveredData);
  960. recoveredData = (uint8_t*) malloc(strlen(s[5])+1);
  961. dataShare0 = (uint8_t*) malloc(strlen(s[5])+1);
  962. dataShare1 = (uint8_t*) malloc(strlen(s[5])+1);
  963. for(int j = 2; j < 6; j++){//skip to the sizes we care about
  964. dataSize = strlen(s[j])+1;
  965. genDPF(ctx, 128, 300, dataSize, s[j], &k0, &k1);
  966. res1 = evalDPF(ctx, k0, 12, dataSize, dataShare0);
  967. res2 = evalDPF(ctx, k1, 12, dataSize, dataShare1);
  968. for(int i = 0; i < dataSize; i++){
  969. recoveredData[i] = dataShare0[i] ^ dataShare1[i];
  970. }
  971. if(strcmp(recoveredData, s[j]) == 0){
  972. printf("string %d recovered data for wrong input", j);
  973. }
  974. res1 = evalDPF(ctx, k0, 300, dataSize, dataShare0);
  975. res2 = evalDPF(ctx, k1, 300, dataSize, dataShare1);
  976. for(int i = 0; i < dataSize; i++){
  977. recoveredData[i] = dataShare0[i] ^ dataShare1[i];
  978. }
  979. if(strcmp(recoveredData, s[j]) != 0){
  980. printf("string %d recovered incorrect data", j);
  981. }
  982. clock_t start = clock(), diff;
  983. #pragma omp parallel for
  984. for(int i = 0; i < 1000; i++){
  985. res1 = evalDPF(ctx, k0, i*((uint128_t)2<<70), dataSize, dataShare0);
  986. }
  987. diff = clock() - start;
  988. int msec = diff * 1000 / CLOCKS_PER_SEC;
  989. printf("Time taken for string %d, db size 1,000: %d milliseconds\n", j, msec);
  990. start = clock();
  991. #pragma omp parallel for
  992. for(int i = 0; i < 10000; i++){
  993. res1 = evalDPF(ctx, k0, i*((uint128_t)2<<70), dataSize, dataShare0);
  994. }
  995. diff = clock() - start;
  996. msec = diff * 1000 / CLOCKS_PER_SEC;
  997. printf("Time taken for string %d, db size 10,000: %d milliseconds\n", j, msec);
  998. start = clock();
  999. #pragma omp parallel for
  1000. for(int i = 0; i < 100000; i++){
  1001. res1 = evalDPF(ctx, k0, i*((uint128_t)2<<70), dataSize, dataShare0);
  1002. }
  1003. diff = clock() - start;
  1004. msec = diff * 1000 / CLOCKS_PER_SEC;
  1005. printf("Time taken for string %d, db size 100,000: %d milliseconds\n", j, msec);
  1006. /*
  1007. start = clock();
  1008. #pragma omp parallel for
  1009. for(int i = 0; i < 1000000; i++){
  1010. res1 = evalDPF(ctx, k0, i*((uint128_t)2<<70), dataSize, dataShare0);
  1011. }
  1012. diff = clock() - start;
  1013. msec = diff * 1000 / CLOCKS_PER_SEC;
  1014. printf("Time taken for string %d, db size 1,000,000: %d milliseconds\n", j, msec);
  1015. */
  1016. }
  1017. return 0;
  1018. }