slows
This commit is contained in:
commit
bc68c15d11
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
*.o
|
||||
.ccls-cache/
|
||||
slows
|
17
Makefile
Normal file
17
Makefile
Normal file
|
@ -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
|
68
arith.c
Normal file
68
arith.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include "arith.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// 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; }
|
38
arith.h
Normal file
38
arith.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#ifndef H_ARITH
|
||||
#define H_ARITH
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// 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
|
155
circ.c
Normal file
155
circ.c
Normal file
|
@ -0,0 +1,155 @@
|
|||
#include "circ.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
33
circ.h
Normal file
33
circ.h
Normal file
|
@ -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
|
179
client.c
Normal file
179
client.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
#include "circ.h"
|
||||
#include "hosts.h"
|
||||
#include "online.h"
|
||||
#include "parse.h"
|
||||
#include "pre.h"
|
||||
#include <poll.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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);
|
||||
}
|
31
com.c
Normal file
31
com.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
#include "arith.h"
|
||||
#include <assert.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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]);
|
||||
}
|
||||
};
|
16
com.h
Normal file
16
com.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
#ifndef H_COM
|
||||
#define H_COM
|
||||
|
||||
#include "arith.h"
|
||||
#include <openssl/sha.h>
|
||||
|
||||
// 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
|
88
hosts.c
Normal file
88
hosts.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
#include "hosts.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
17
hosts.h
Normal file
17
hosts.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef H_HOST
|
||||
#define H_HOST
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
// A connection.
|
||||
struct host {
|
||||
char *name;
|
||||
int sockfd;
|
||||
struct sockaddr_in conn;
|
||||
int h_port;
|
||||
int c_port;
|
||||
};
|
||||
|
||||
void init_hosts(char *file);
|
||||
|
||||
#endif
|
77
msg.c
Normal file
77
msg.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include "msg.h"
|
||||
#include "hosts.h"
|
||||
#include <poll.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
33
msg.h
Normal file
33
msg.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef H_MSG
|
||||
#define H_MSG
|
||||
|
||||
#include "arith.h"
|
||||
#include "hosts.h"
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
85
online.c
Normal file
85
online.c
Normal file
|
@ -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 <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// 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
|
||||
}
|
14
online.h
Normal file
14
online.h
Normal file
|
@ -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
|
50
parse.c
Normal file
50
parse.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
6
parse.h
Normal file
6
parse.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef H_PARSE
|
||||
#define H_PARSE
|
||||
|
||||
int parse(int argc, char **argv);
|
||||
|
||||
#endif
|
85
pre.c
Normal file
85
pre.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
#include "pre.h"
|
||||
#include "circ.h"
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
pre.h
Normal file
25
pre.h
Normal file
|
@ -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
|
10
test0/ccfg1
Normal file
10
test0/ccfg1
Normal file
|
@ -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
|
10
test0/ccfg2
Normal file
10
test0/ccfg2
Normal file
|
@ -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
|
2
test0/hcfg1
Normal file
2
test0/hcfg1
Normal file
|
@ -0,0 +1,2 @@
|
|||
p0
|
||||
p1 8001 127.0.0.1 8010
|
2
test0/hcfg2
Normal file
2
test0/hcfg2
Normal file
|
@ -0,0 +1,2 @@
|
|||
p1
|
||||
p0 8010 127.0.0.1 8001
|
8
test0/pcfg1
Normal file
8
test0/pcfg1
Normal file
|
@ -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)
|
8
test0/pcfg2
Normal file
8
test0/pcfg2
Normal file
|
@ -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)
|
10
test1/ccfg1
Normal file
10
test1/ccfg1
Normal file
|
@ -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
|
10
test1/ccfg2
Normal file
10
test1/ccfg2
Normal file
|
@ -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
|
10
test1/ccfg3
Normal file
10
test1/ccfg3
Normal file
|
@ -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
|
3
test1/hcfg1
Normal file
3
test1/hcfg1
Normal file
|
@ -0,0 +1,3 @@
|
|||
p0
|
||||
p1 8000 127.0.0.1 8010
|
||||
p2 8001 127.0.0.1 8020
|
3
test1/hcfg2
Normal file
3
test1/hcfg2
Normal file
|
@ -0,0 +1,3 @@
|
|||
p1
|
||||
p0 8010 127.0.0.1 8000
|
||||
p2 8011 127.0.0.1 8021
|
3
test1/hcfg3
Normal file
3
test1/hcfg3
Normal file
|
@ -0,0 +1,3 @@
|
|||
p2
|
||||
p0 8020 127.0.0.1 8001
|
||||
p1 8021 127.0.0.1 8011
|
9
test1/pcfg1
Normal file
9
test1/pcfg1
Normal file
|
@ -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)
|
9
test1/pcfg2
Normal file
9
test1/pcfg2
Normal file
|
@ -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)
|
9
test1/pcfg3
Normal file
9
test1/pcfg3
Normal file
|
@ -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)
|
Loading…
Reference in New Issue
Block a user