From e8c1e8d23cbb5e26820dc67c230a3c265dd1e3a8 Mon Sep 17 00:00:00 2001 From: int-bot Date: Sat, 6 Mar 2021 15:34:12 +0000 Subject: [PATCH 1/5] Server implementation --- c/client.cpp | 44 ++++++++++++ c/main.cpp | 184 ++++++++++++++++++++++++++++++++++----------------- c/socket.cpp | 99 +++++++++++++++++++++++++++ c/socket.hpp | 22 ++++++ 4 files changed, 290 insertions(+), 59 deletions(-) create mode 100644 c/client.cpp create mode 100644 c/socket.cpp create mode 100644 c/socket.hpp diff --git a/c/client.cpp b/c/client.cpp new file mode 100644 index 0000000..20b286a --- /dev/null +++ b/c/client.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "socket.hpp" + +//main driver program +int main(int argc, char *argv[]) { + if (argc!=3) { + std::string cl = argv[0]; + std::string base_filename = cl.substr(cl.find_last_of("/\\") + 1); + std::cout << "Usage: " << base_filename << " > >\n"; + } else { + int hSocket, read_size; + struct sockaddr_in server; + t_witness_msg message; + strcpy(message.inputFile, argv[1]); + strcpy(message.outputFile, argv[2]); + + //Create socket + hSocket = SocketCreate(); + if(hSocket == -1) { + printf("Could not create socket\n"); + return 1; + } + //Connect to remote server + if (SocketConnect(hSocket) < 0) { + perror("connect failed.\n"); + return 1; + } + //Send data to the server, and retry until file created + SocketSend(hSocket, (void *) &message, sizeof(t_witness_msg)); + + close(hSocket); + shutdown(hSocket,0); + shutdown(hSocket,1); + shutdown(hSocket,2); + return 0; + } +} diff --git a/c/main.cpp b/c/main.cpp index 904091d..e6cf574 100644 --- a/c/main.cpp +++ b/c/main.cpp @@ -18,6 +18,10 @@ using json = nlohmann::json; #include "circom.hpp" #include "utils.hpp" +#ifdef SERVER_ENABLE +#include "socket.hpp" +#endif + Circom_Circuit *circuit; @@ -344,78 +348,140 @@ Circom_Circuit *loadCircuit(std::string const &datFileName) { return circuit; } + +void computeWitness(char *inputFile, char *outputFile) { + struct timeval begin, end; + long seconds, microseconds; + double elapsed; + + gettimeofday(&begin,0); + Circom_CalcWit *ctx = new Circom_CalcWit(circuit); + + std::string infilename = inputFile; + gettimeofday(&end,0); + seconds = end.tv_sec - begin.tv_sec; + microseconds = end.tv_usec - begin.tv_usec; + elapsed = seconds + microseconds*1e-6; + + printf("Up to loadJson %.20f\n", elapsed); + + if (hasEnding(infilename, std::string(".bin"))) { + loadBin(ctx, infilename); + } else if (hasEnding(infilename, std::string(".json"))) { + loadJson(ctx, infilename); + } else { + handle_error("Invalid input extension (.bin / .json)"); + } + + ctx->join(); + + // printf("Finished!\n"); + + std::string outfilename = outputFile; + + if (hasEnding(outfilename, std::string(".wtns"))) { + gettimeofday(&end,0); + seconds = end.tv_sec - begin.tv_sec; + microseconds = end.tv_usec - begin.tv_usec; + elapsed = seconds + microseconds*1e-6; + + printf("Up to WriteWtns %.20f\n", elapsed); + writeOutBin(ctx, outfilename); + } else if (hasEnding(outfilename, std::string(".json"))) { + writeOutJson(ctx, outfilename); + } else if (hasEnding(outfilename, std::string(".wshm"))) { + gettimeofday(&end,0); + seconds = end.tv_sec - begin.tv_sec; + microseconds = end.tv_usec - begin.tv_usec; + elapsed = seconds + microseconds*1e-6; + + printf("Up to WriteShmem %.20f\n", elapsed); + writeOutShmem(ctx, outfilename); + } else { + handle_error("Invalid output extension (.bin / .json)"); + } + + delete ctx; + gettimeofday(&end,0); + seconds = end.tv_sec - begin.tv_sec; + microseconds = end.tv_usec - begin.tv_usec; + elapsed = seconds + microseconds*1e-6; + + printf("Total %.20f\n", elapsed); +#ifndef SERVER_ENABLE + exit(EXIT_SUCCESS); +#endif +} + int main(int argc, char *argv[]) { + struct timeval begin, end; + long seconds, microseconds; + double elapsed; + + gettimeofday(&begin,0); +#ifndef SERVER_ENABLE if (argc!=3) { std::string cl = argv[0]; std::string base_filename = cl.substr(cl.find_last_of("/\\") + 1); std::cout << "Usage: " << base_filename << " > >\n"; } else { - - struct timeval begin, end; - long seconds, microseconds; - double elapsed; - - gettimeofday(&begin,0); - std::string datFileName = argv[0]; datFileName += ".dat"; circuit = loadCircuit(datFileName); - // open output - Circom_CalcWit *ctx = new Circom_CalcWit(circuit); - - std::string infilename = argv[1]; - gettimeofday(&end,0); - seconds = end.tv_sec - begin.tv_sec; - microseconds = end.tv_usec - begin.tv_usec; - elapsed = seconds + microseconds*1e-6; - - printf("Up to loadJson %.20f\n", elapsed); - - if (hasEnding(infilename, std::string(".bin"))) { - loadBin(ctx, infilename); - } else if (hasEnding(infilename, std::string(".json"))) { - loadJson(ctx, infilename); - } else { - handle_error("Invalid input extension (.bin / .json)"); - } - - ctx->join(); - - // printf("Finished!\n"); - - std::string outfilename = argv[2]; - - if (hasEnding(outfilename, std::string(".wtns"))) { - gettimeofday(&end,0); - seconds = end.tv_sec - begin.tv_sec; - microseconds = end.tv_usec - begin.tv_usec; - elapsed = seconds + microseconds*1e-6; + gettimeofday(&end,0); + seconds = end.tv_sec - begin.tv_sec; + microseconds = end.tv_usec - begin.tv_usec; + elapsed = seconds + microseconds*1e-6; - printf("Up to WriteWtns %.20f\n", elapsed); - writeOutBin(ctx, outfilename); - } else if (hasEnding(outfilename, std::string(".json"))) { - writeOutJson(ctx, outfilename); - } else if (hasEnding(outfilename, std::string(".wshm"))) { - gettimeofday(&end,0); - seconds = end.tv_sec - begin.tv_sec; - microseconds = end.tv_usec - begin.tv_usec; - elapsed = seconds + microseconds*1e-6; - - printf("Up to WriteShmem %.20f\n", elapsed); - writeOutShmem(ctx, outfilename); - } else { - handle_error("Invalid output extension (.bin / .json)"); - } + printf("Up to computeWitness %.20f\n", elapsed); + // open output + computeWitness(argv[1], argv[2]); - delete ctx; - gettimeofday(&end,0); - seconds = end.tv_sec - begin.tv_sec; - microseconds = end.tv_usec - begin.tv_usec; - elapsed = seconds + microseconds*1e-6; +#else + { + std::string datFileName = argv[0]; + datFileName += ".dat"; - printf("Total %.20f\n", elapsed); - exit(EXIT_SUCCESS); + int circuitInit=0; + t_witness_msg message; + + if (!ServerInit()) { + exit(1); + } + + while(1) { + int sock; + sock = ReceiveMsg((void *) &message, sizeof(t_witness_msg)); + if (!sock) { + continue; + } + std::cout << " Output file " << message.outputFile << "\n"; + std::cout << " Input file " << message.inputFile << "\n"; + + if (!circuitInit) { + std::cout << " Load Circuit " << datFileName << "\n"; + circuit = loadCircuit(datFileName); + circuitInit=1; + + gettimeofday(&end,0); + seconds = end.tv_sec - begin.tv_sec; + microseconds = end.tv_usec - begin.tv_usec; + elapsed = seconds + microseconds*1e-6; + + printf("Up to computeWitness %.20f\n", elapsed); + } + + if (circuitInit) { + std::cout << " Compute Witness " << message.outputFile << "\n"; + computeWitness(message.inputFile, message.outputFile); + } + + SocketClose(sock); + sleep(1); + } +#endif } } + diff --git a/c/socket.cpp b/c/socket.cpp new file mode 100644 index 0000000..a83b925 --- /dev/null +++ b/c/socket.cpp @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include +#include "socket.hpp" + +static int SocketDesc; + +//Create a Socket for server communication +short SocketCreate(void) { + short hSocket; + hSocket = socket(AF_INET, SOCK_STREAM, 0); + return hSocket; +} + +int SocketConnect(int hSocket) { + int iRetval=-1; + int ServerPort = SERVER_PORT; + struct sockaddr_in remote= {0}; + remote.sin_addr.s_addr = inet_addr("127.0.0.1"); //Local Host + remote.sin_family = AF_INET; + remote.sin_port = htons(ServerPort); + iRetval = connect(hSocket,(struct sockaddr *)&remote,sizeof(struct sockaddr_in)); + return iRetval; +} + +// Send the data to the server and set the timeout of 20 seconds +int SocketSend(int hSocket,void* Rqst,short lenRqst) { + int shortRetval = -1; + struct timeval tv; + tv.tv_sec = 20; /* 20 Secs Timeout */ + tv.tv_usec = 0; + if(setsockopt(hSocket,SOL_SOCKET,SO_SNDTIMEO,(char *)&tv,sizeof(tv)) < 0) + { + printf("Time Out\n"); + return -1; + } + shortRetval = send(hSocket, Rqst, lenRqst, 0); + return shortRetval; +} + +int BindCreatedSocket(int hSocket) { + int iRetval=-1; + int ClientPort = SERVER_PORT; + struct sockaddr_in remote= {0}; + /* Internet address family */ + remote.sin_family = AF_INET; + /* Any incoming interface */ + remote.sin_addr.s_addr = htonl(INADDR_ANY); + remote.sin_port = htons(ClientPort); /* Local port */ + iRetval = bind(hSocket,(struct sockaddr *)&remote,sizeof(remote)); + return iRetval; +} + + +int ServerInit() { + //Create socket + SocketDesc = SocketCreate(); + if (SocketDesc == -1) { + printf("Could not create socket"); + return 0; + } + //Bind + if( BindCreatedSocket(SocketDesc) < 0) { + //print the error message + perror("bind failed."); + return 0; + } + //Listen + listen(SocketDesc, 3); + + return 1; +} + +int ReceiveMsg(void *message, int len) { + int sock, clientLen; + struct sockaddr_in client; + printf("Waiting for incoming connections...\n"); + clientLen = sizeof(struct sockaddr_in); + //accept connection from an incoming client + sock = accept(SocketDesc,(struct sockaddr *)&client,(socklen_t*)&clientLen); + if (sock < 0) { + perror("accept failed"); + return 0; + } + printf("Connection accepted\n"); + //Receive a reply from the client + if( recv(sock, message, sizeof(t_witness_msg), 0) < 0) { + printf("recv failed"); + return 0; + } + return sock; +} + +void SocketClose(int socket) { + close(socket); +} diff --git a/c/socket.hpp b/c/socket.hpp new file mode 100644 index 0000000..e8c049c --- /dev/null +++ b/c/socket.hpp @@ -0,0 +1,22 @@ + +#ifndef __SOCKET_H__ +#define __SOCKET_H__ + +#define FILE_LEN (1000) +#define SERVER_PORT (90190) + +typedef struct { + char inputFile[FILE_LEN]; + char outputFile[FILE_LEN]; + +}t_witness_msg; + +short SocketCreate(void); +int SocketConnect(int hSocket); +int SocketSend(int hSocket,void* Rqst,short lenRqst); +int BindCreatedSocket(int hSocket); +int ServerInit(); +int ReceiveMsg(void *message, int len); +void SocketClose(int socket); + +#endif From faef00a1359d16d8300d8049867142dd766da2db Mon Sep 17 00:00:00 2001 From: int-bot Date: Sat, 6 Mar 2021 15:38:13 +0000 Subject: [PATCH 2/5] Update README --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index e1d71d0..a852fa9 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,25 @@ This is the code needed to calculate the witness by a circuit compiled with [circom](https://github.com/iden3/circom). +## Server +To compile server implementation: +- Compile Server +``` +g++ -O3 -std=c++17 -DSERVER_ENABLE -fopenmp -pthread calcwit.cpp main.cpp utils.cpp fr.cpp fr.o socket.cpp circuit-1960-32-256-64.cpp -o circuit-1960-32-256-64 -lgmp +``` +- Compile Client +``` +g++ -std=c++17 client.cpp socket.cpp -o client +``` +- Launch Server +``` +./circuit-1960-32-256-64 +``` +- Launch Client +``` +./client input-1960-32-256-64.json circuit-1960-32-256-64_w.wshm +``` + ## License From 0b596ed87385df69919f76cba8fbf5bce9df8f5a Mon Sep 17 00:00:00 2001 From: int-bot Date: Tue, 9 Mar 2021 10:20:53 +0000 Subject: [PATCH 3/5] Add extra space to witness in shmem --- c/main.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/c/main.cpp b/c/main.cpp index e6cf574..738fc85 100644 --- a/c/main.cpp +++ b/c/main.cpp @@ -29,6 +29,10 @@ Circom_Circuit *circuit; do { perror(msg); exit(EXIT_FAILURE); } while (0) #define SHMEM_WITNESS_KEY (123456) +#define FAST_LOG2(x) (sizeof(unsigned long)*8 - 1 - __builtin_clzl((unsigned long)(x))) +#define FAST_LOG2_UP(x) (((x) - (1 << FAST_LOG2(x))) ? FAST_LOG2(x) + 1 : FAST_LOG2(x)) + + // assumptions // 1) There is only one key assigned for shared memory. This means @@ -86,18 +90,19 @@ void writeOutShmem(Circom_CalcWit *ctx, std::string filename) { u64 idSection2length = n8*circuit->NVars; fwrite(&idSection2length, 8, 1, write_ptr); + u64 nElems = (1 << (FAST_LOG2_UP(nVars)+1)) + 8; // generate key key_t key = SHMEM_WITNESS_KEY; fwrite(&key, sizeof(key_t), 1, write_ptr); // Setup shared memory - if ((shmid = shmget(key, circuit->NVars * Fr_N64 * sizeof(u64), IPC_CREAT | 0666)) < 0) { + if ((shmid = shmget(key, nElems * Fr_N64 * sizeof(u64), IPC_CREAT | 0666)) < 0) { // preallocated shared memory segment is too small => Retrieve id by accesing old segment // Delete old segment and create new with corret size shmid = shmget(key, 4, IPC_CREAT | 0666); shmctl(shmid, IPC_RMID, NULL); - if ((shmid = shmget(key, circuit->NVars * Fr_N64 * sizeof(u64), IPC_CREAT | 0666)) < 0){ + if ((shmid = shmget(key, nElems * Fr_N64 * sizeof(u64), IPC_CREAT | 0666)) < 0){ status = -1; fwrite(&status, sizeof(status), 1, write_ptr); fclose(write_ptr); From 6d0760cffc0bfe43551c34c546815a5252fc5396 Mon Sep 17 00:00:00 2001 From: int-bot Date: Tue, 9 Mar 2021 11:32:23 +0000 Subject: [PATCH 4/5] client waits for response --- c/client.cpp | 5 ++++- c/main.cpp | 2 ++ c/socket.cpp | 24 ++++++++++++++++++++++++ c/socket.hpp | 2 ++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/c/client.cpp b/c/client.cpp index 20b286a..d1655fb 100644 --- a/c/client.cpp +++ b/c/client.cpp @@ -15,7 +15,7 @@ int main(int argc, char *argv[]) { std::string base_filename = cl.substr(cl.find_last_of("/\\") + 1); std::cout << "Usage: " << base_filename << " > >\n"; } else { - int hSocket, read_size; + int hSocket, read_size, server_reply; struct sockaddr_in server; t_witness_msg message; strcpy(message.inputFile, argv[1]); @@ -34,6 +34,9 @@ int main(int argc, char *argv[]) { } //Send data to the server, and retry until file created SocketSend(hSocket, (void *) &message, sizeof(t_witness_msg)); + + //Received the data from the server + SocketReceive(hSocket, (void *) &server_reply, sizeof(int)); close(hSocket); shutdown(hSocket,0); diff --git a/c/main.cpp b/c/main.cpp index 738fc85..73cfe20 100644 --- a/c/main.cpp +++ b/c/main.cpp @@ -481,8 +481,10 @@ int main(int argc, char *argv[]) { if (circuitInit) { std::cout << " Compute Witness " << message.outputFile << "\n"; computeWitness(message.inputFile, message.outputFile); + SendConfirmation(sock); } + SocketClose(sock); sleep(1); } diff --git a/c/socket.cpp b/c/socket.cpp index a83b925..047277a 100644 --- a/c/socket.cpp +++ b/c/socket.cpp @@ -74,6 +74,22 @@ int ServerInit() { return 1; } +//receive the data from the server +int SocketReceive(int hSocket,void* Rsp,short RvcSize) +{ + int shortRetval = -1; + struct timeval tv; + tv.tv_sec = 20; /* 20 Secs Timeout */ + tv.tv_usec = 0; + if(setsockopt(hSocket, SOL_SOCKET, SO_RCVTIMEO,(char *)&tv,sizeof(tv)) < 0) + { + printf("Time Out\n"); + return -1; + } + shortRetval = recv(hSocket, Rsp, RvcSize, 0); + return shortRetval; +} + int ReceiveMsg(void *message, int len) { int sock, clientLen; struct sockaddr_in client; @@ -97,3 +113,11 @@ int ReceiveMsg(void *message, int len) { void SocketClose(int socket) { close(socket); } + +int SendConfirmation(int sock) { + int reply = 1; + if( send(sock, (void *) &reply , sizeof(int), 0) < 0) { + return 0; + } + return 1; +} diff --git a/c/socket.hpp b/c/socket.hpp index e8c049c..9591e7c 100644 --- a/c/socket.hpp +++ b/c/socket.hpp @@ -14,9 +14,11 @@ typedef struct { short SocketCreate(void); int SocketConnect(int hSocket); int SocketSend(int hSocket,void* Rqst,short lenRqst); +int SocketReceive(int hSocket,void * Rsp,short RvcSize); int BindCreatedSocket(int hSocket); int ServerInit(); int ReceiveMsg(void *message, int len); void SocketClose(int socket); +int SendConfirmation(int socket); #endif From 0b5badc8a680f90421be8182e624ef4412c4e096 Mon Sep 17 00:00:00 2001 From: int-bot Date: Tue, 9 Mar 2021 15:19:30 +0000 Subject: [PATCH 5/5] Wait until outout file is generated --- c/client.cpp | 8 ++++++-- c/main.cpp | 2 -- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/c/client.cpp b/c/client.cpp index d1655fb..700dab0 100644 --- a/c/client.cpp +++ b/c/client.cpp @@ -35,8 +35,12 @@ int main(int argc, char *argv[]) { //Send data to the server, and retry until file created SocketSend(hSocket, (void *) &message, sizeof(t_witness_msg)); - //Received the data from the server - SocketReceive(hSocket, (void *) &server_reply, sizeof(int)); + while (1) { + if (access(message.outputFile, F_OK) == 0) { + break; + } + sleep(1); + } close(hSocket); shutdown(hSocket,0); diff --git a/c/main.cpp b/c/main.cpp index 73cfe20..738fc85 100644 --- a/c/main.cpp +++ b/c/main.cpp @@ -481,10 +481,8 @@ int main(int argc, char *argv[]) { if (circuitInit) { std::cout << " Compute Witness " << message.outputFile << "\n"; computeWitness(message.inputFile, message.outputFile); - SendConfirmation(sock); } - SocketClose(sock); sleep(1); }