From bc68c15d118c7b607c26a672a558b5e93e817ec3 Mon Sep 17 00:00:00 2001 From: h Date: Wed, 6 Nov 2024 14:44:39 -0500 Subject: [PATCH] slows --- .gitignore | 3 + Makefile | 17 +++++ arith.c | 68 ++++++++++++++++++++ arith.h | 38 +++++++++++ circ.c | 155 +++++++++++++++++++++++++++++++++++++++++++++ circ.h | 33 ++++++++++ client.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++ com.c | 31 +++++++++ com.h | 16 +++++ hosts.c | 88 ++++++++++++++++++++++++++ hosts.h | 17 +++++ msg.c | 77 ++++++++++++++++++++++ msg.h | 33 ++++++++++ online.c | 85 +++++++++++++++++++++++++ online.h | 14 ++++ parse.c | 50 +++++++++++++++ parse.h | 6 ++ pre.c | 85 +++++++++++++++++++++++++ pre.h | 25 ++++++++ test0/ccfg1 | 10 +++ test0/ccfg2 | 10 +++ test0/hcfg1 | 2 + test0/hcfg2 | 2 + test0/pcfg1 | 8 +++ test0/pcfg2 | 8 +++ test1/ccfg1 | 10 +++ test1/ccfg2 | 10 +++ test1/ccfg3 | 10 +++ test1/hcfg1 | 3 + test1/hcfg2 | 3 + test1/hcfg3 | 3 + test1/pcfg1 | 9 +++ test1/pcfg2 | 9 +++ test1/pcfg3 | 9 +++ 34 files changed, 1126 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 arith.c create mode 100644 arith.h create mode 100644 circ.c create mode 100644 circ.h create mode 100644 client.c create mode 100644 com.c create mode 100644 com.h create mode 100644 hosts.c create mode 100644 hosts.h create mode 100644 msg.c create mode 100644 msg.h create mode 100644 online.c create mode 100644 online.h create mode 100644 parse.c create mode 100644 parse.h create mode 100644 pre.c create mode 100644 pre.h create mode 100644 test0/ccfg1 create mode 100644 test0/ccfg2 create mode 100644 test0/hcfg1 create mode 100644 test0/hcfg2 create mode 100644 test0/pcfg1 create mode 100644 test0/pcfg2 create mode 100644 test1/ccfg1 create mode 100644 test1/ccfg2 create mode 100644 test1/ccfg3 create mode 100644 test1/hcfg1 create mode 100644 test1/hcfg2 create mode 100644 test1/hcfg3 create mode 100644 test1/pcfg1 create mode 100644 test1/pcfg2 create mode 100644 test1/pcfg3 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8a90096 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +.ccls-cache/ +slows diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..578d85e --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +CC=gcc +CFLAGS=-Wall -Wextra -ggdb -std=gnu99 +SRC=arith.c circ.c client.c hosts.c parse.c pre.c online.c msg.c com.c +OBJ=$(SRC:.c=.o) +LIBS=-lcrypto + +all: client + +.SUFFIXES: .c .o +.c.o: + $(CC) -c $(CFLAGS) $*.c + +client: $(OBJ) + $(CC) $(LIBS) -o slows $(OBJ) + +clean: + rm -f *.o slows diff --git a/arith.c b/arith.c new file mode 100644 index 0000000..1b72f1e --- /dev/null +++ b/arith.c @@ -0,0 +1,68 @@ +#include "arith.h" +#include +#include + +// Field: 18446744073709551557 + +const uint64_t MOD = 18446744073709551557ULL; + +fp *rand_fp() { + uint64_t v = ((uint64_t)rand() << 32) | ((uint64_t)rand()); + v = v % MOD; + fp *x = malloc(sizeof(fp)); + x->val = v; + return x; +} + +fp *from(uint64_t v) { + fp *x = malloc(sizeof(fp)); + x->val = v % MOD; + return x; +} + +fp *add(fp *a, fp *b) { + fp *x = malloc(sizeof(fp)); + x->val = (a->val + b->val); + if (x->val > MOD || (x->val < a->val && x->val < b->val)) { + x->val -= MOD; + } + x->val %= MOD; + return x; +} + +fp *mul(fp *a, fp *b) { + uint64_t v = b->val; + uint64_t r = a->val; + uint64_t o = 0; + while (v > 0) { + if (v % 2 == 1) { + uint64_t tmp = o + r; + if (tmp > MOD || (tmp < o && tmp < r)) { + tmp -= MOD; + } + o = tmp % MOD; + } + // r + r + uint64_t tmp = r + r; + if (tmp > MOD || (tmp < r)) { + tmp -= MOD; + } + r = tmp % MOD; + + v >>= 1; + } + o = o % MOD; + fp *x = malloc(sizeof(fp)); + x->val = o; + return x; +} + +fp *neg(fp *a) { + fp *x = malloc(sizeof(fp)); + x->val = MOD - a->val; + return x; +} + +int is_zero(fp *x) { return (x->val == 0); } + +uint64_t get_output(fp *x) { return x->val; } diff --git a/arith.h b/arith.h new file mode 100644 index 0000000..63b0de5 --- /dev/null +++ b/arith.h @@ -0,0 +1,38 @@ +#ifndef H_ARITH +#define H_ARITH + +#include + +// Field element (invariant: val <= MOD) +typedef struct { + uint64_t val; +} fp; + +// An authenticated share: consists of linear shares of (x, Delta * x) +struct share { + fp *s; + fp *s_mac; +}; + +// Generate a fully random field element +fp *rand_fp(); + +// Convert a uint to a Fp +fp *from(uint64_t v); + +// Add two field elements together +fp *add(fp *a, fp *b); + +// Multiply two field elements together +fp *mul(fp *a, fp *b); + +// Negate a field element (-x) +fp *neg(fp *a); + +// Check if a field element is zero. +int is_zero(fp *x); + +// Produce a printable uint64 from the field element. +uint64_t get_output(fp *o); + +#endif diff --git a/circ.c b/circ.c new file mode 100644 index 0000000..e2f5ba9 --- /dev/null +++ b/circ.c @@ -0,0 +1,155 @@ +#include "circ.h" +#include +#include +#include + +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) + +struct wires *g_wires; + +void init_circuit(char *file) { + + char *line = NULL; + size_t len = 0; + ssize_t read; + + g_wires = NULL; + + FILE *fp = fopen(file, "r"); + if (fp == NULL) { + printf("Circuit file not found.\n"); + exit(1); + } + + while ((read = getline(&line, &len, fp)) != -1) { + char *wname = malloc(200 * sizeof(char)); + char op[4]; + char *in1 = malloc(200 * sizeof(char)); + char *in2 = malloc(200 * sizeof(char)); + int ret = sscanf(line, "%200s = %3s %200s %200s", wname, op, in1, in2); + if (ret == 4) { + if (strcmp(op, "inp") == 0) { + struct wire *w = malloc(sizeof(struct wire)); + w->wname = wname; + w->operation = 2; + w->val = from(atoi(in2)); + w->depth = 0; + w->in1 = NULL; + w->in2 = NULL; + w->is_output = 0; + w->input_name = in1; + struct wires *cur = malloc(sizeof(struct wires)); + cur->w = w; + cur->next = g_wires; + g_wires = cur; + } else if (strcmp(op, "add") == 0) { + struct wire *inw1; + struct wire *inw2; + struct wires *a; + for (a = g_wires; a != NULL; a = a->next) { + if (strcmp(a->w->wname, in1) == 0) { + inw1 = a->w; + } + if (strcmp(a->w->wname, in2) == 0) { + inw2 = a->w; + } + } + + struct wire *w = malloc(sizeof(struct wire)); + w->wname = wname; + w->operation = 0; + w->val = 0; + w->depth = MAX(inw1->depth, inw2->depth) + 1; + w->in1 = inw1; + w->in2 = inw2; + w->is_output = 0; + struct wires *cur = malloc(sizeof(struct wires)); + cur->w = w; + cur->next = g_wires; + g_wires = cur; + + } else if (strcmp(op, "mul") == 0) { + struct wire *inw1; + struct wire *inw2; + struct wires *a; + for (a = g_wires; a != NULL; a = a->next) { + if (strcmp(a->w->wname, in1) == 0) { + inw1 = a->w; + } + if (strcmp(a->w->wname, in2) == 0) { + inw2 = a->w; + } + } + struct wire *w = malloc(sizeof(struct wire)); + w->wname = wname; + w->operation = 1; + w->val = 0; + w->depth = MAX(inw1->depth, inw2->depth) + 1; + w->in1 = inw1; + w->in2 = inw2; + w->is_output = 0; + struct wires *cur = malloc(sizeof(struct wires)); + cur->w = w; + cur->next = g_wires; + g_wires = cur; + } + } else if (ret == 3) { + if (strcmp(op, "inp") == 0) { + + struct wire *w = malloc(sizeof(struct wire)); + w->wname = wname; + w->operation = 2; + w->val = 0; + w->depth = 0; + w->in1 = NULL; + w->in2 = NULL; + w->is_output = 0; + w->input_name = in1; + struct wires *cur = malloc(sizeof(struct wires)); + cur->w = w; + cur->next = g_wires; + g_wires = cur; + } else if (strcmp(op, "con") == 0) { + struct wire *w = malloc(sizeof(struct wire)); + w->wname = wname; + w->operation = 3; + w->val = from(atoi(in1)); + w->depth = 0; + w->in1 = NULL; + w->in2 = NULL; + w->is_output = 0; + struct wires *cur = malloc(sizeof(struct wires)); + cur->w = w; + cur->next = g_wires; + g_wires = cur; + } + } else { + char *wwname = malloc(200 * sizeof(char)); + int nret = sscanf(line, "out %200s", wwname); + if (nret == 1) { + struct wire *inw1; + struct wires *a; + for (a = g_wires; a != NULL; a = a->next) { + if (strcmp(a->w->wname, wwname) == 0) { + inw1 = a->w; + } + } + inw1->is_output = 1; + } + // otherwise ignore the command + } + } + + struct wires *cur = g_wires; + struct wires *prev = NULL; + struct wires *next; + + while (cur != NULL) { + next = cur->next; + cur->next = prev; + prev = cur; + cur = next; + } + + g_wires = prev; +} diff --git a/circ.h b/circ.h new file mode 100644 index 0000000..4df216c --- /dev/null +++ b/circ.h @@ -0,0 +1,33 @@ +#ifndef H_CIRC +#define H_CIRC + +#include "arith.h" + +// A wire value. +struct wire { + char *wname; // wire name + struct wire *in1; // input value 1 into gate + struct wire *in2; // input value 2 into gate + int depth; // the circuit forms a DAG -> this is the DAG depth. It is *not + // necessary* to use this. + fp *val; // IF constant, this is the constant value on the wire + // IF input (for this party), this is the value for that input + int operation; + // 0 for addition, 1 for multiplication, 2 for input, 3 for constant + // if its an input wire or constant wire, in1 and in2 are null. + + int is_output; // If the wire is an output wire. + char *input_name; // name of user who provides input if wire is input wire + + struct share *share; // TODO: fill this in when evaluating the circuit +}; + +// A linked list of wires; this holds the wires ready in evaluation order. +struct wires { + struct wires *next; + struct wire *w; +}; + +void init_circuit(char *file); + +#endif diff --git a/client.c b/client.c new file mode 100644 index 0000000..ec6f5ea --- /dev/null +++ b/client.c @@ -0,0 +1,179 @@ +#include "circ.h" +#include "hosts.h" +#include "online.h" +#include "parse.h" +#include "pre.h" +#include +#include +#include +#include +#include +#include + +extern char *f_host; // host filename (ignore) +extern char *f_circ; // circuit filename (ignore) +extern char *f_pre; // preprocess filename (ignore) + +extern struct host *conns[1024]; // external connections to other parties +extern int num_conns; // number of total connections +extern char *glob_name; // global ident for this party + +extern fp *delta; + +extern struct wires *g_wires; // circuit wires stored linearly (order matters!) + +extern struct randv *auth_rand; // authenticated randomness (ie; malicious + // secret shares of random values) +extern struct triple *auth_triples; // authenticated triples (ie; malicious + // secret shares of a, b, ab) + +void initialize() { + init_hosts(f_host); + init_circuit(f_circ); + init_preprocess(f_pre); + + printf("\n\n\n --- CONNECTIONS --- \n\n"); + for (int i = 0; i < num_conns; i++) { + printf("Connected with %s:%d at %d\n", conns[i]->name, conns[i]->c_port, + conns[i]->h_port); + } + + printf("\n --- PREPROCESSING --- \n\n"); + + printf("GLOBAL MAC SHARE: [%lu]\n", delta->val); + + struct triple *t; + for (t = auth_triples; t != NULL; t = t->next) { + printf("TRIPLE [a] = (%lu %lu) [b] = (%lu %lu) [c] = (%lu %lu)\n", + t->a->s->val, t->a->s_mac->val, t->b->s->val, t->b->s_mac->val, + t->ab->s->val, t->ab->s_mac->val); + } + + struct randv *r; + + for (r = auth_rand; r != NULL; r = r->next) { + printf("RAND [r] = (%lu %lu)", r->s->s->val, r->s->s_mac->val); + if (r->value != NULL) { + printf(" (r = %lu)\n", r->value->val); + } else { + printf("\n"); + } + } + + printf("\n --- WIRES --- \n\n"); + + struct wires *a; + + for (a = g_wires; a != NULL; a = a->next) { + if (a->w->operation == 2) { + printf("INPUT WIRE BY [%s] ", a->w->input_name); + if (strcmp(a->w->input_name, glob_name) == 0) { + printf("(i = %lu)\n", a->w->val->val); + } else { + printf("\n"); + } + } + } +} + +uint8_t check_arr(uint8_t *ready, int len) { + for (int i = 0; i < len; i++) { + if (((ready[i] & 1) == 0) || ((ready[i] & 2) == 0)) { + return 0; + } + } + return 1; +} + +void wait_for_connections() { + + printf("\n\n\n --- PHASE 1 --- \n\n\n"); + + printf("Waiting for connections...\n"); + + struct pollfd *fds = malloc(sizeof(struct pollfd) * num_conns); + + uint8_t *is_ready = malloc(sizeof(uint8_t) * num_conns); + for (int i = 0; i < num_conns; i++) { + is_ready[i] = 0; + } + + while (check_arr(is_ready, num_conns) == 0) { + int numfds = 0; + // send out a ping to all hosts, and wait 10 seconds for an ack + char pepega[4] = {'p', 'i', 'n', 'g'}; + for (int i = 0; i < num_conns; i++) { + if ((is_ready[i] & 1) == 0) { + printf("Pinging %s\n", conns[i]->name); + sendto(conns[i]->sockfd, pepega, 4, 0, + (const struct sockaddr *)&conns[i]->conn, + sizeof(conns[i]->conn)); + fds[numfds].fd = conns[i]->sockfd; + fds[numfds].events = POLLIN; + fds[numfds].revents = 0; + numfds += 1; + } else if ((is_ready[i] & 2) == 0) { + fds[numfds].fd = conns[i]->sockfd; + fds[numfds].events = POLLIN; + fds[numfds].revents = 0; + numfds += 1; + } + } + + int out = poll(fds, numfds, 10000); + + if (out > 0) { + for (int i = 0; i < numfds; i++) { + if (fds[i].revents > 0) { + int connid = 0; + for (int j = 0; j < num_conns; j++) { + if (conns[j]->sockfd == fds[i].fd) { + connid = j; + } + } + + unsigned char buf[4] = {0}; + socklen_t len = sizeof(conns[connid]->conn); + recvfrom(fds[i].fd, buf, 4, 0, + (struct sockaddr *)&(conns[connid]->conn), &len); + + if (buf[0] == 'p' && buf[1] == 'i' && buf[2] == 'n' && + buf[3] == 'g') { + printf("Received ping from %s, acking\n", conns[connid]->name); + char omega[4] = {'a', 'c', 'k', 'n'}; + sendto(fds[i].fd, omega, 4, 0, + (const struct sockaddr *)&conns[connid]->conn, + sizeof(conns[connid]->conn)); + is_ready[connid] |= 2; + } else if (buf[0] == 'a' && buf[1] == 'c' && buf[2] == 'k' && + buf[3] == 'n') { + printf("Received ack from %s\n", conns[connid]->name); + is_ready[connid] |= 1; + } + } + } + } + } + + free(is_ready); + + sleep(5); +} + +int main(int argc, char **argv) { + srand(time(NULL)); + parse(argc, argv); + + printf("Got host file: %s\n", f_host); + printf("Got circuit file: %s\n", f_circ); + printf("Got preprocessing file: %s\n\n\n", f_pre); + + initialize(); + + wait_for_connections(); + + printf("\n\n\n --- PHASE 2 ---\n\n\n"); + + spdz_online(conns, num_conns, glob_name, delta, g_wires, auth_rand, + auth_triples); +} diff --git a/com.c b/com.c new file mode 100644 index 0000000..f664fbf --- /dev/null +++ b/com.c @@ -0,0 +1,31 @@ + +#include "arith.h" +#include +#include +#include + +char *commit(fp *data, fp *random) { + char inp_data[16]; + char *outbuf = malloc(32 * sizeof(char)); + for (int i = 0; i < 32; i++) { + outbuf[i] = 0; + } + ((uint64_t *)inp_data)[0] = data->val; + ((uint64_t *)inp_data)[1] = random->val; + SHA256((unsigned char *)inp_data, 8, (unsigned char *)outbuf); + return outbuf; +}; + +void check_open(fp *data, fp *random, char *commitment) { + char inp_data[16]; + char *outbuf = malloc(32 * sizeof(char)); + for (int i = 0; i < 32; i++) { + outbuf[i] = 0; + } + ((uint64_t *)inp_data)[0] = data->val; + ((uint64_t *)inp_data)[1] = random->val; + SHA256((unsigned char *)inp_data, 8, (unsigned char *)outbuf); + for (int i = 0; i < 32; i++) { + assert(outbuf[i] == commitment[i]); + } +}; diff --git a/com.h b/com.h new file mode 100644 index 0000000..48bb06b --- /dev/null +++ b/com.h @@ -0,0 +1,16 @@ + +#ifndef H_COM +#define H_COM + +#include "arith.h" +#include + +// Produces a char[32] 32 byte array with the commitment contained within. +// NOTE: IT IS 32 BYTES EXACTLY. +char *commit(fp *data, fp *random); + +// Checks the opening of a 32 byte commitment (makes commitment correctly bound +// data). +char *check_open(fp *data, fp *random, char *commitment); + +#endif diff --git a/hosts.c b/hosts.c new file mode 100644 index 0000000..a02d89c --- /dev/null +++ b/hosts.c @@ -0,0 +1,88 @@ +#include "hosts.h" +#include +#include +#include +#include +#include +#include + +struct host *conns[1024]; +int num_conns = 0; +char *glob_name; + +int init_conn(int h_port) { + + int sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + + if (sock_fd < 0) { + printf("Socket initialization failed."); + exit(1); + } + + struct sockaddr_in serv_addr; + + memset(&serv_addr, 0, sizeof(serv_addr)); + + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(h_port); + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + if (bind(sock_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { + printf("Failed to bind socket.\n"); + exit(1); + } + + return sock_fd; +} + +void init_hosts(char *file) { + + char *line = NULL; + size_t len = 0; + ssize_t read; + + FILE *fp = fopen(file, "r"); + if (fp == NULL) { + printf("Host file not found.\n"); + exit(1); + } + + int name = 1; + + while ((read = getline(&line, &len, fp)) != -1) { + if (name == 1) { + glob_name = malloc(sizeof(char) * (strlen(line) + 1)); + strcpy(glob_name, line); + glob_name[strcspn(glob_name, "\n")] = 0; + printf("Name: %s", glob_name); + name = 0; + } else { + char *cname = malloc(200 * sizeof(char)); + char *addr = malloc(32 * sizeof(char)); + int c_port; + int h_port; + int ret = sscanf(line, "%200s %d %32s %d", cname, &h_port, addr, &c_port); + if (ret != 4) { + printf("Could not parse host file.\n"); + exit(1); + } + struct host *h = malloc(sizeof(struct host)); + h->name = cname; + h->h_port = h_port; + h->c_port = c_port; + h->sockfd = init_conn(h_port); + + struct sockaddr_in conn_addr; + + memset(&conn_addr, 0, sizeof(conn_addr)); + + conn_addr.sin_family = AF_INET; + conn_addr.sin_port = htons(c_port); + conn_addr.sin_addr.s_addr = inet_addr(addr); + free(addr); + h->conn = conn_addr; + conns[num_conns] = h; + num_conns += 1; + } + } +} diff --git a/hosts.h b/hosts.h new file mode 100644 index 0000000..3b0e644 --- /dev/null +++ b/hosts.h @@ -0,0 +1,17 @@ +#ifndef H_HOST +#define H_HOST + +#include + +// A connection. +struct host { + char *name; + int sockfd; + struct sockaddr_in conn; + int h_port; + int c_port; +}; + +void init_hosts(char *file); + +#endif diff --git a/msg.c b/msg.c new file mode 100644 index 0000000..069f22f --- /dev/null +++ b/msg.c @@ -0,0 +1,77 @@ +#include "msg.h" +#include "hosts.h" +#include +#include +#include +#include +#include + +fp *packet_to_fp(packet *p) { + fp *f = malloc(sizeof(fp)); + f->val = be64toh(((uint64_t *)p->data)[0]); + return f; +} + +packet *fp_to_packet(fp *elem) { + uint64_t *buf = malloc(sizeof(char) * 8); + buf[0] = htobe64(elem->val); + packet *p = malloc(sizeof(packet)); + p->data = (uint8_t *)buf; + p->len = 8; + return p; +} + +packet *to_packet(uint8_t *data, uint8_t len) { + packet *p = malloc(sizeof(packet)); + p->data = data; + p->len = len; + return p; +} + +void broadcast(struct host **conns, int num_conns, packet *data) { + + char *transmit = malloc(sizeof(char) * data->len + 1); + transmit[0] = (char)data->len; + memcpy((transmit + 1), data->data, data->len); + for (int i = 0; i < num_conns; i++) { + sendto(conns[i]->sockfd, transmit, data->len + 1, 0, + (const struct sockaddr *)&conns[i]->conn, sizeof(conns[i]->conn)); + } + free(transmit); +} + +packet *recv_broadcasts(struct host **conns, int num_conns) { + + packet *packets = malloc(sizeof(packet) * num_conns); + + for (int i = 0; i < num_conns; i++) { + packets[i].data = NULL; + packets[i].len = 0; + } + + for (int i = 0; i < num_conns; i++) { + uint8_t *buf = malloc(sizeof(uint8_t) * 64); + socklen_t len = sizeof(conns[i]->conn); + recvfrom(conns[i]->sockfd, buf, 64, 0, (struct sockaddr *)&(conns[i]->conn), + &len); + uint8_t size = buf[0]; + packets[i].data = (buf + 1); + packets[i].len = size; + } + + return packets; +} + +packet *recv_single_broadcast(struct host *con) { + packet *p = malloc(sizeof(packet)); + p->data = NULL; + p->len = 0; + uint8_t *buf = malloc(sizeof(uint8_t) * 64); + socklen_t len = sizeof(con->conn); + recvfrom(con->sockfd, buf, 64, 0, (struct sockaddr *)&(con->conn), &len); + uint8_t size = buf[0]; + p->data = (buf + 1); + p->len = size; + + return p; +} diff --git a/msg.h b/msg.h new file mode 100644 index 0000000..4288df1 --- /dev/null +++ b/msg.h @@ -0,0 +1,33 @@ +#ifndef H_MSG +#define H_MSG + +#include "arith.h" +#include "hosts.h" +#include + +typedef struct { + uint8_t *data; + uint8_t len; +} packet; + +// Convert a packet (recieved on the network) into a field element. +fp *packet_to_fp(packet *p); + +// Convert a field element to a packet. +packet *fp_to_packet(fp *elem); + +// Convert a char [len] array into a packet. +// Note: this is necessary for the commitments sent. +packet *to_packet(uint8_t *data, uint8_t len); + +// Broadcast to all connections a packet. +void broadcast(struct host **conns, int num_conns, packet *data); + +// Recieve from all connections a packet. +packet *recv_broadcasts(struct host **conns, int num_conns); + +// Recieve from a single connection a packet. (Can use it for recieving the +// initial input opening for wires). +packet *recv_single_broadcast(struct host *con); + +#endif diff --git a/online.c b/online.c new file mode 100644 index 0000000..7e35cfc --- /dev/null +++ b/online.c @@ -0,0 +1,85 @@ +#include "online.h" +#include "arith.h" +#include "circ.h" +#include "com.h" +#include "hosts.h" +#include "msg.h" +#include "pre.h" +#include +#include +#include +#include + +// here we want to open a share: +// to do this, players +// 1. broadcast openings to plain shares +// 2. commit to mac candidate differences +// 3. open commitments +// 4. check the commitments; if they don't verify abort +// 5. if the sum is not 0, abort +fp *secure_open(struct host **conns, int num_conns, fp *delta, + struct share *s) { + + // TODO: implement this +}; + +// Add a constant to a shared value [x] -> [x + c] +// a single arbitrary party should do the s -> s + c update: you may assume this +// party is named "p0" everyone updates macs! +struct share *const_add(struct share *s, fp *constant, fp *delta, + char *glob_name) { + // TODO: implement this + +}; + +// Multiply a constant to a shared value [x] -> [cx] +struct share *const_mul(struct share *s, fp *constant) { + // TODO: implement this +}; + +// Do a local share add ([x], [y]) -> [x + y] +struct share *local_add(struct share *s1, struct share *s2) { + // TODO: implement this +}; + +// Do a local share sub ([x], [y]) -> [x - y] +struct share *local_sub(struct share *s1, struct share *s2) { + // TODO: implement this + // (not strictly necessary, but useful for mult) +}; + +// Use the opening and a triple to do a multiplication +// Do a multiplication ([x], [y]) -> [xy] +struct share *multiply(struct host **conns, int num_conns, fp *delta, + char *glob_name, struct share *s1, struct share *s2, + struct triple *t) { + // TODO: implement this +}; + +// Arguments: +// 1. conns is the list of connections. [ This is for broadcasting ]. +// 2. num_conns is the number of connections. [ For broadcasting ] +// 3. glob_name is the global name of you (the party). [ For const add ].. +// 4. delta is the SPDZ global mac share. +// 5. g_wires is the global linked list of wires in eval order. +// 6. auth_rand is a list of random shares [r] (along with input vals) +// 7. auth_triples is a list of beaver triples [a], [b], [ab]. +// Proceed through g_wires and evaluate each wire until you hit the end. +void spdz_online(struct host **conns, int num_conns, char *glob_name, fp *delta, + struct wires *g_wires, struct randv *auth_rand, + struct triple *auth_triples) { + + // 1. loop through all the wires in the g_wires linked list + // + // 2. Check what operation is the wire from: do the operation (multiply, add) + // dont forget the edge case when one of the input wires is a + // constant! + // + // 3. (within the previous check): if the wire is input, use up an auth_rand + // random share and produce shares of the input + // 4. (within the previous check): if the wire is output, calculate it and + // then at the end do a secure opening to find the output value. + + // NOTE: don't worry about freeing or managing stuff, we don't care about + // memory leaks or anything lol this aint a C class +} diff --git a/online.h b/online.h new file mode 100644 index 0000000..107a2c7 --- /dev/null +++ b/online.h @@ -0,0 +1,14 @@ + +#ifndef H_ONL +#define H_ONL + +#include "arith.h" +#include "circ.h" +#include "hosts.h" +#include "pre.h" + +void spdz_online(struct host **conns, int num_conns, char *glob_name, + fp *mac_share, struct wires *g_wires, struct randv *auth_rand, + struct triple *auth_triples); + +#endif diff --git a/parse.c b/parse.c new file mode 100644 index 0000000..0e9f77c --- /dev/null +++ b/parse.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include + +extern char *optarg; +char *f_pre; +char *f_host; +char *f_circ; + +int parse(int argc, char **argv) { + char opt; + bool h; + bool c; + bool p; + + while ((opt = getopt(argc, argv, "h:c:p:")) != EOF) { + switch (opt) { + case 'h': + f_host = optarg; + h = true; + break; + case 'c': + f_circ = optarg; + c = true; + break; + case 'p': + f_pre = optarg; + p = true; + break; + } + } + + if (!h) { + printf("Please provide all arguments.\n"); + exit(1); + } + + if (!c) { + printf("Please provide all arguments.\n"); + exit(1); + } + + if (!p) { + printf("Please provide all arguments.\n"); + exit(1); + } + + return optind; +} diff --git a/parse.h b/parse.h new file mode 100644 index 0000000..b1c757d --- /dev/null +++ b/parse.h @@ -0,0 +1,6 @@ +#ifndef H_PARSE +#define H_PARSE + +int parse(int argc, char **argv); + +#endif diff --git a/pre.c b/pre.c new file mode 100644 index 0000000..580b976 --- /dev/null +++ b/pre.c @@ -0,0 +1,85 @@ +#include "pre.h" +#include "circ.h" +#include +#include +#include +#include +#include + +struct randv *auth_rand; +struct triple *auth_triples; + +fp *delta; + +void init_preprocess(char *file) { + char *line = NULL; + size_t len = 0; + ssize_t read; + + auth_rand = NULL; + auth_triples = NULL; + + FILE *fp = fopen(file, "r"); + if (fp == NULL) { + printf("Preprocessing file not found.\n"); + exit(1); + } + + while ((read = getline(&line, &len, fp)) != -1) { + char *wname = malloc(200 * sizeof(char)); + uint64_t share; + uint64_t share_mac; + uint64_t val; + int ret = sscanf(line, "rand %200s (%lu, %lu) %lu", wname, &share, + &share_mac, &val); + if (ret == 4) { + struct randv *rand_value = malloc(sizeof(struct randv)); + rand_value->wname = wname; + rand_value->next = auth_rand; + rand_value->s = malloc(sizeof(struct share)); + rand_value->s->s = from(share); + rand_value->s->s_mac = from(share_mac); + rand_value->value = from(val); + auth_rand = rand_value; + } else if (ret == 3) { + struct randv *rand_value = malloc(sizeof(struct randv)); + rand_value->wname = wname; + rand_value->next = auth_rand; + rand_value->s = malloc(sizeof(struct share)); + rand_value->s->s = from(share); + rand_value->s->s_mac = from(share_mac); + rand_value->value = NULL; + auth_rand = rand_value; + } else { + uint64_t share_a; + uint64_t share_mac_a; + uint64_t share_b; + uint64_t share_mac_b; + uint64_t share_ab; + uint64_t share_mac_ab; + int ret = sscanf(line, "triple (%lu, %lu) (%lu, %lu) (%lu, %lu)", + &share_a, &share_mac_a, &share_b, &share_mac_b, + &share_ab, &share_mac_ab); + if (ret == 6) { + struct triple *tp = malloc(sizeof(struct triple)); + tp->next = auth_triples; + tp->a = malloc(sizeof(struct share)); + tp->a->s = from(share_a); + tp->a->s_mac = from(share_mac_a); + tp->b = malloc(sizeof(struct share)); + tp->b->s = from(share_b); + tp->b->s_mac = from(share_mac_b); + tp->ab = malloc(sizeof(struct share)); + tp->ab->s = from(share_ab); + tp->ab->s_mac = from(share_mac_ab); + auth_triples = tp; + } else { + uint64_t macv; + int mac = sscanf(line, "mac %lu", &macv); + if (mac == 1) { + delta = from(macv); + } + } + } + } +} diff --git a/pre.h b/pre.h new file mode 100644 index 0000000..b1ef0a2 --- /dev/null +++ b/pre.h @@ -0,0 +1,25 @@ +#ifndef H_PRE +#define H_PRE + +#include "arith.h" + +// A linked list of Beaver triples [a], [b], [ab] +struct triple { + struct triple *next; + struct share *a; + struct share *b; + struct share *ab; +}; + +// A linked list of authenticated maliciously secure random shares [r], each +// associated with a wire. This should be used for generating shares of input. +struct randv { + struct randv *next; + char *wname; // name of associated wire + struct share *s; // authenticated share + fp *value; // r (if applicable; ie wire is the user's input) +}; + +void init_preprocess(char *file); + +#endif diff --git a/test0/ccfg1 b/test0/ccfg1 new file mode 100644 index 0000000..c4ccdaa --- /dev/null +++ b/test0/ccfg1 @@ -0,0 +1,10 @@ +w1 = inp p0 34 +w2 = inp p1 +w3 = inp p1 +w4 = inp p0 22 + +w5 = mul w1 w3 +w6 = add w4 w2 +w7 = add w5 w6 + +out w7 diff --git a/test0/ccfg2 b/test0/ccfg2 new file mode 100644 index 0000000..81bb09e --- /dev/null +++ b/test0/ccfg2 @@ -0,0 +1,10 @@ +w1 = inp p0 +w2 = inp p1 38 +w3 = inp p1 11 +w4 = inp p0 + +w5 = mul w1 w3 +w6 = add w4 w2 +w7 = add w5 w6 + +out w7 diff --git a/test0/hcfg1 b/test0/hcfg1 new file mode 100644 index 0000000..fe18012 --- /dev/null +++ b/test0/hcfg1 @@ -0,0 +1,2 @@ +p0 +p1 8001 127.0.0.1 8010 diff --git a/test0/hcfg2 b/test0/hcfg2 new file mode 100644 index 0000000..95e2b14 --- /dev/null +++ b/test0/hcfg2 @@ -0,0 +1,2 @@ +p1 +p0 8010 127.0.0.1 8001 diff --git a/test0/pcfg1 b/test0/pcfg1 new file mode 100644 index 0000000..eb630f5 --- /dev/null +++ b/test0/pcfg1 @@ -0,0 +1,8 @@ +mac 5 + +rand w1 (30, 73) 33 +rand w2 (9, 109) +rand w3 (11, 223) +rand w4 (33, 50) 50 + +triple (129, 4431) (33, 999) (26805, 475214) diff --git a/test0/pcfg2 b/test0/pcfg2 new file mode 100644 index 0000000..27af214 --- /dev/null +++ b/test0/pcfg2 @@ -0,0 +1,8 @@ +mac 8 + +rand w1 (3, 356) +rand w2 (10, 138) 19 +rand w3 (21, 193) 32 +rand w4 (17, 600) + +triple (328, 1510) (87, 561) (28035, 237706) diff --git a/test1/ccfg1 b/test1/ccfg1 new file mode 100644 index 0000000..8236dfa --- /dev/null +++ b/test1/ccfg1 @@ -0,0 +1,10 @@ +w1 = inp p0 34 +w2 = inp p1 +w3 = inp p1 +w4 = inp p2 + +w5 = mul w1 w2 +w6 = mul w3 w4 +w7 = add w5 w6 + +out w7 diff --git a/test1/ccfg2 b/test1/ccfg2 new file mode 100644 index 0000000..e6ee67a --- /dev/null +++ b/test1/ccfg2 @@ -0,0 +1,10 @@ +w1 = inp p0 +w2 = inp p1 38 +w3 = inp p1 11 +w4 = inp p2 + +w5 = mul w1 w2 +w6 = mul w3 w4 +w7 = add w5 w6 + +out w7 diff --git a/test1/ccfg3 b/test1/ccfg3 new file mode 100644 index 0000000..cc308bf --- /dev/null +++ b/test1/ccfg3 @@ -0,0 +1,10 @@ +w1 = inp p0 +w2 = inp p1 +w3 = inp p1 +w4 = inp p2 18 + +w5 = mul w1 w2 +w6 = mul w3 w4 +w7 = add w5 w6 + +out w7 diff --git a/test1/hcfg1 b/test1/hcfg1 new file mode 100644 index 0000000..d721ce5 --- /dev/null +++ b/test1/hcfg1 @@ -0,0 +1,3 @@ +p0 +p1 8000 127.0.0.1 8010 +p2 8001 127.0.0.1 8020 diff --git a/test1/hcfg2 b/test1/hcfg2 new file mode 100644 index 0000000..fa6e02f --- /dev/null +++ b/test1/hcfg2 @@ -0,0 +1,3 @@ +p1 +p0 8010 127.0.0.1 8000 +p2 8011 127.0.0.1 8021 diff --git a/test1/hcfg3 b/test1/hcfg3 new file mode 100644 index 0000000..952334e --- /dev/null +++ b/test1/hcfg3 @@ -0,0 +1,3 @@ +p2 +p0 8020 127.0.0.1 8001 +p1 8021 127.0.0.1 8011 diff --git a/test1/pcfg1 b/test1/pcfg1 new file mode 100644 index 0000000..38ecba8 --- /dev/null +++ b/test1/pcfg1 @@ -0,0 +1,9 @@ +mac 8 + +rand w1 (30, 1000) 115 +rand w2 (9, 231) +rand w3 (11, 223) +rand w4 (10, 400) + +triple (722, 187202) (363, 6006) (667401, 6189301) +triple (218331, 183634) (4398, 4313) (300405, 2821) diff --git a/test1/pcfg2 b/test1/pcfg2 new file mode 100644 index 0000000..4f3b77b --- /dev/null +++ b/test1/pcfg2 @@ -0,0 +1,9 @@ +mac 10 + +rand w1 (3, 200) +rand w2 (10, 458) 50 +rand w3 (21, 111) 40 +rand w4 (17, 600) + +triple (9469, 87813) (109, 5125) (9135512, 37765626) +triple (855730, 12895925) (7, 5387) (3245747137, 89995070763) diff --git a/test1/pcfg3 b/test1/pcfg3 new file mode 100644 index 0000000..815e9ba --- /dev/null +++ b/test1/pcfg3 @@ -0,0 +1,9 @@ +mac 2 + +rand w1 (82, 1100) +rand w2 (31, 311) +rand w3 (8, 466) +rand w4 (33, 200) 60 + +triple (5089, 30585) (170, 1709) (6847, 152240273) +triple (353, 8408721) (42, 79240) (1531871516, 5563307576)