This commit is contained in:
h 2024-11-06 14:44:39 -05:00
commit bc68c15d11
34 changed files with 1126 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.o
.ccls-cache/
slows

17
Makefile Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,6 @@
#ifndef H_PARSE
#define H_PARSE
int parse(int argc, char **argv);
#endif

85
pre.c Normal file
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,2 @@
p0
p1 8001 127.0.0.1 8010

2
test0/hcfg2 Normal file
View File

@ -0,0 +1,2 @@
p1
p0 8010 127.0.0.1 8001

8
test0/pcfg1 Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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)