diff --git a/.gitignore b/.gitignore index a56a1ab20..fee96b6ea 100644 --- a/.gitignore +++ b/.gitignore @@ -391,6 +391,12 @@ /test/small2/merge-ar /test/small2/libmerge.a +#mutual +/test/oblivc/mutual/*.oc.* +/test/oblivc/mutual/*.txt + +*.oc.* + # /ocamlutil /ocamlutil/perfcount.c diff --git a/README.md b/README.md index 50f8f8c97..e246069da 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ Obliv-C Compiler (`oblivcc`) ============================ This readme is still under construction. But there is already a language tutorial at http://goo.gl/TXzxD0 + +This requires libgcrypt to run. this can be downloaded on Ubuntu with `sudo apt-get install libgcrypt` then it also requires libgcrypt11-dev, which can be downlaoded with `sudo apt-get install libgcrypt11-dev`. + Once in the source folder, a simple `./configure && make` should build it all. The compiler is a GCC wrapper script found in `bin/oblivcc`. Example codes are in `test/oblivc` Most of this code was forked from the project CIL (C Intermediate Language). You can diff with the master branch to see which part was added on later. diff --git a/src/ext/oblivc/obliv_bits.c b/src/ext/oblivc/obliv_bits.c index c0faf93a4..decf70aaa 100644 --- a/src/ext/oblivc/obliv_bits.c +++ b/src/ext/oblivc/obliv_bits.c @@ -184,8 +184,8 @@ static int sizeCheckSend(ProtocolTransport* pt,int dest,const void* s,size_t n) { int sent = osend(&((SizeCheckTransportAdapter*)pt)->pd,dest,s,n); if(sent==n) return n; else - { fprintf(stderr,"Was going to send %lu bytes to %d, sent %d\n", - n,dest,sent); + { fprintf(stderr,"Was going to send bytes to %d, sent %d\n", + dest,sent); if(sent<0) fprintf(stderr,"That means %s\n",strerror(sent)); exit(-1); } @@ -195,8 +195,8 @@ static int sizeCheckRecv(ProtocolTransport* pt,int src,void* s,size_t n) { int recv = orecv(&((SizeCheckTransportAdapter*)pt)->pd,src,s,n); if(recv==n) return n; else - { fprintf(stderr,"Was going to recv %lu bytes from %d, received %d\n", - n,src,recv); + { fprintf(stderr,"Was going to recv bytes from %d, received %d\n", + src,recv); if(recv<0) fprintf(stderr,"That means %s\n",strerror(recv)); exit(-1); } diff --git a/src/ext/oblivc/obliv_bits.h b/src/ext/oblivc/obliv_bits.h index 26eb916c4..73355359e 100644 --- a/src/ext/oblivc/obliv_bits.h +++ b/src/ext/oblivc/obliv_bits.h @@ -1,6 +1,6 @@ #ifndef OBLIV_BITS_H #define OBLIV_BITS_H -void* memset(void* s, int c, unsigned long n); // Hack, had to declare memset +//void* memset(void* s, int c, unsigned long n); // Hack, had to declare memset #include // size_t //#include // memset to zero #include diff --git a/test/oblivc/average/average.c b/test/oblivc/average/average.c new file mode 100644 index 000000000..a6ee18c35 --- /dev/null +++ b/test/oblivc/average/average.c @@ -0,0 +1,44 @@ +#include +#include + +#include "average.h" + +int currentParty; + +const char* mySide() +{ + if(currentParty==1) return "Generator"; + else return "Evaluator"; +} + +int main(int argc,char *argv[]) +{ + //these variables are used everytime + ProtocolDesc pd; + protocolIO io; + + //checking that the input has the correct number of variables + if(argc<3) + { if(argc<2) fprintf(stderr,"Party missing\n"); + else fprintf(stderr,"string missing\n"); + fprintf(stderr,"Usage: %s <1|2> \n",argv[0]); + return 1; + } + + //sets the size of the array + io.n = argc-2; + //the the values in the array to the input values + int j; + for(j = 0; j +#include + +#include "average.h" + +void readValues(obliv int* dest, int n, const int* src,int party) +{ + OblivInputs specs[MAXN]; + int i; + for(i=0;in); + n2 = ocBroadcastInt(2, io->n); + readValues(i1, n1, io->i, 1); + readValues(i2, n2, io->i, 2); + //runs the actual algorithm to find average + for(i=0; ires,average,0); +} diff --git a/test/oblivc/highest/README.txt b/test/oblivc/highest/README.txt new file mode 100644 index 000000000..86ab5b554 --- /dev/null +++ b/test/oblivc/highest/README.txt @@ -0,0 +1,9 @@ +Prints out the highest value that is entered by two parties on the command line + +# compile using our GCC wrapper +/path/to/oblivcc highest.c highest.oc -I . +# run: party 1 enters the numbers 1,2, and 3 and party 2 entered the numbers 2,4, and 6 +cycle './a.out 1 1 2 3 | ./a.out 2 2 4 6' +#this result will be 6 + +The cycle command is a handy bash script that you can find at https://github.com/samee/cmd diff --git a/test/oblivc/highest/highest.c b/test/oblivc/highest/highest.c new file mode 100644 index 000000000..3a8716399 --- /dev/null +++ b/test/oblivc/highest/highest.c @@ -0,0 +1,44 @@ +#include +#include + +#include "highest.h" + +int currentParty; + +const char* mySide() +{ + if(currentParty==1) return "Generator"; + else return "Evaluator"; +} + +int main(int argc,char *argv[]) +{ + //these variables are used everytime + ProtocolDesc pd; + protocolIO io; + + //checking that the input has the correct number of variables + if(argc<3) + { if(argc<2) fprintf(stderr,"Party missing\n"); + else fprintf(stderr,"string missing\n"); + fprintf(stderr,"Usage: %s <1|2> \n",argv[0]); + return 1; + } + + //sets the size of the array + io.n = argc-2; + //the the values in the array to the input values + int j; + for(j = 0; j +#include + +#include "highest.h" +//dest is the pointer to the array of obliv ints +//n is the size of the array +//src is where the data is coming from +void readValues(obliv int* dest, int n, const int* src,int party) +{ + OblivInputs specs[MAXN]; + int i; + for( i = 0;in, 1); + n2 = feedOblivInt(io->n, 2); + readValues(i1, MAXN, io->i, 1); + readValues(i2, MAXN, io->i, 2); + //runs the actual algorithm of higher value + obliv int high = i1[0]; + for(k=0; k high) + high = i1[k]; + } + for(j =0; j high) + high = i2[j]; + } + revealOblivInt(&io->res,high,0); +} \ No newline at end of file diff --git a/test/oblivc/mutualfriends/mutual.c b/test/oblivc/mutualfriends/mutual.c new file mode 100644 index 000000000..e86e80346 --- /dev/null +++ b/test/oblivc/mutualfriends/mutual.c @@ -0,0 +1,145 @@ +//mutualfriends file + +#include +#include +#include +#include +#include + +#include "mutual.h" + +int currentParty; + +/* Function to merge the two haves arr[l..m] and arr[m+1..r] of array arr[] */ +void merge(char arr[MAXN][MAXL], int l, int m, int r) +{ + int i, j, k; + int n1 = m - l + 1; + int n2 = r - m; + + /* create temp arrays */ + char L[n1][100], R[n2][100]; + + /* Copy data to temp arrays L[] and R[] */ + for(i = 0; i < n1; i++) + strcpy(L[i], arr[l+i]); + for(j = 0; j < n2; j++) + strcpy(R[j], arr[m+1+j]); + + /* Merge the temp arrays back into arr[l..r]*/ + i = 0; + j = 0; + k = l; + while (i < n1 && j < n2) + { + if (strcmp(L[i],R[j]) < 0) + { + strcpy(arr[k], L[i]); + i++; + } + else + { + strcpy(arr[k], R[j]); + j++; + } + k++; + } + + /* Copy the remaining elements of L[], if there are any */ + while (i < n1) + { + strcpy(arr[k], L[i]); + i++; + k++; + } + + /* Copy the remaining elements of R[], if there are any */ + while (j < n2) + { + strcpy(arr[k], R[j]); + j++; + k++; + } +} + +/* l is for left index and r is right index of the sub-array + of arr to be sorted */ +void mergeSort(char arr[MAXN][MAXL], int l, int r) +{ + if (l < r) + { + int m = l+(r-l)/2; //Same as (l+r)/2, but avoids overflow for large l and h + mergeSort(arr, l, m); + mergeSort(arr, m+1, r); + merge(arr, l, m, r); + } +} + +const char* mySide() +{ + if(currentParty==1) return "Generator"; + else return "Evaluator"; +} + +double wallClock() +{ + struct timespec t; + int i = clock_gettime(CLOCK_REALTIME,&t); + return t.tv_sec+1e-9*t.tv_nsec; +} +double lap; + +int main(int argc,char *argv[]) +{ + //these variables are used everytime + ProtocolDesc pd; + protocolIO io; + + //checking that the input has the correct number of variables + if(argc<3) + { if(argc<2) fprintf(stderr,"Party missing\n"); + else fprintf(stderr,"friends missing\n"); + fprintf(stderr,"Usage: %s <1|2> \n",argv[0]); + return 1; + } + FILE *infile; + infile = fopen(argv[2], "r"); + if(infile==NULL){ + //Error("Unable to open file"); + fprintf(stderr, "ERROR!"); + return 1; + } + //TODO change input file so that it says how many friends there are + int i=0; + char buf[MAXN][MAXL]; + while(fgets(buf[i], MAXL, infile)!=NULL){ + strcpy(io.mine[i], buf[i]); + i++; + } + io.size = i; + mergeSort(io.mine, 0, io.size-1); + fprintf(stderr,"Size: %d\n", io.size); + + fclose(infile); + //standard setup + protocolUseStdio(&pd); + currentParty = (argv[1][0]=='1'?1:2); + setCurrentParty(&pd,currentParty); + setCurrentParty(&pd,currentParty); + lap = wallClock(); + //execYaoProtocol(&pd,mutualFriends, &io); + //execDebugProtocol(&pd,mutualFriends, &io); + execYaoProtocol(&pd,sortMutual, &io); + //execDebugProtocol(&pd,sortMutual, &io); + fprintf(stderr,"%s total time: %lf s\n",mySide(),wallClock()-lap); + fprintf(stderr,"Gate Count: %u\n",yaoGateCount()); + cleanupProtocol(&pd); + + fprintf(stderr, "Result: %d\n", io.commonSize); + for(i=0; i<2*MAXN; i++){ + if(io.common[i][0]!='\0') + // fprintf(stderr, "%s", io.common[i]); + ; + } + return 0; +} diff --git a/test/oblivc/mutualfriends/mutual.h b/test/oblivc/mutualfriends/mutual.h new file mode 100644 index 000000000..7df71f38b --- /dev/null +++ b/test/oblivc/mutualfriends/mutual.h @@ -0,0 +1,21 @@ +//mutualfriends file + +//#prama once +//the maximum length of a name +#define MAXL 11 +//the maximum number of friends +#define MAXN 512 + +typedef char* string; +typedef struct protocolIO{ + char mine[MAXN][MAXL]; + int size; + char common[2*MAXN][MAXL]; + int commonSize; +}protocolIO; + +const char* mySide(); + +void mutualFriends(void* args); + +void sortMutual(void* args); diff --git a/test/oblivc/mutualfriends/mutual.oc b/test/oblivc/mutualfriends/mutual.oc new file mode 100644 index 000000000..7f6ea64b8 --- /dev/null +++ b/test/oblivc/mutualfriends/mutual.oc @@ -0,0 +1,141 @@ +//mutualfriends file + +#include +#include +#include + +#include "mutual.h" + +typedef obliv bool obool; + +typedef obliv int oint; + +int greatestPowerOfTwoLessThan(int n){ + int k = 1; + while(k < n) + k=k*2; + return k / 2; +} + +oint oblivStrCmp(obliv char* s1, obliv char* s2) obliv { + obliv bool afternull = false; + int i; + oint ob = 0; + for( i = 0; i < MAXL; i++) { + obliv if (afternull) { + ; + } else { + obliv char c1 = s1[i]; + obliv char c2 = s2[i]; + obliv if (c1 != c2) { + ob = c1 - c2; + afternull = true; + } + else + obliv if (c1 == '\0') + afternull = true; + } + } + return ob; +} + +void addString(obliv char* src, obliv char* dest) obliv{ + int i; + for(i=0; isize); + size2 = ocBroadcastInt(2, io->size); + for(i=0;imine[i][j], 1); + + for(i=0; imine[i][j], 2); + + for( i=0; icommonSize, commonSize, 0); + for(i=0; icommon[i][j],commonFriends[i][j],0); + } + + +void sortMutual(void* args){ + protocolIO *io = args; + int size1, size2; + int i, j; + size1 = ocBroadcastInt(1, io->size); + size2 = ocBroadcastInt(2, io->size); + obliv char friends[2 * MAXN][MAXL]; + obliv char commonFriends[2 * MAXN][MAXL]; + obliv int commonSize; + + for(i=0;imine[i][j], 1); + } + } + for(i=0; i < size2; i++) + for(j=0; jmine[i][j], 2); + int totalSize = size1 + size2; + int k = greatestPowerOfTwoLessThan(totalSize); + while(k>0){ + for(i=0; i+k0) + swap(friends, i, i+k); + k = greatestPowerOfTwoLessThan(k); + } + + for(i = 0; i < totalSize-1; i++){ + obliv if(oblivStrCmp(friends[i], friends[i + 1])==0){ + commonSize++; + addString(friends[i+1], commonFriends[i+1]); + } + } + + //shuffling + srand(time(NULL)); + int r1, r2; + for(i = 0; i<2*MAXN; i++){ + r1 = rand() % 2*MAXN; + r2 = rand() % 2*MAXN; + swap(commonFriends, r1, r2); + } + revealOblivInt(&io->commonSize, commonSize, 0); + for(i=0; i<2*MAXN; i++) + for(j=0; jcommon[i][j],commonFriends[i][j],0); +}