int main(int c, char **a) { OE oe = OperatingEnvironment_LinuxNew(); init_polynomial(); if (oe) { MR mr = 0; int i = 0; MiniMacs mm = setup_generic_minimacs(oe, a[1]); if (!mm) return -42; mm->get_id(); mr = mm->connect("127.0.0.1",2020); mm->init_heap(6); C(mm->secret_input(0,0,0)); C(mm->open(0)); C(mm->secret_input(0,1,Data_shallow("\001\001",1))); C(mm->secret_input(0,2,Data_shallow("\002\002",1))); for(i = 0; i < 256;++i) C(mm->mul(3,2,1)); C(mm->add(3,3,3)); C(mm->open(3)); oe->p(mm->heap_get(0)->codeword); _p("Mul res", mm->heap_get(3)->codeword,8,8); } failure: return 0; }
static XORcommitResult xor_commit(OE oe, Rnd rnd, CommitmentScheme cs, byte * circuit_string, uint lcircuit_string) { XORcommitResult res = oe->getmem(sizeof(*res)); uint i = 0; Data m0cmt = 0, m1cmt = 0; res->m0 = oe->getmem(lcircuit_string); res->m1 = oe->getmem(lcircuit_string); rnd->rand(res->m0,lcircuit_string); UserReport(oe,"m0 at random: "); print_bit_string(oe,Data_shallow(res->m0,lcircuit_string)); res->lm0 = lcircuit_string; res->lm1 = lcircuit_string; for(i = 0; i < lcircuit_string; ++i) { res->m1[i] = circuit_string[i] ^ res->m0[i]; } // white box usage of commit we use 64 bits per commitment (sha512 with random value of length 16 bytes) res->commitment = oe->getmem(128); res->lcommitment = 128; m0cmt = cs->commit(Data_shallow(res->m0,res->lm0)); m1cmt = cs->commit(Data_shallow(res->m1,res->lm1)); mcpy(m0cmt->data,res->commitment,m0cmt->ldata > 64 ? 64 : m0cmt->ldata); mcpy(m1cmt->data,res->commitment+64,m1cmt->ldata > 64 ? 64 : m1cmt->ldata); xor_commit_end: Data_destroy(oe,&m0cmt); Data_destroy(oe,&m1cmt); return res; }
int main(int c, char **a) { OE oe = OperatingEnvironment_New(); InitStats(oe); init_polynomial(); if (oe) { MR mr = 0; int i = 0; MiniMacs mm = setup_generic_minimacs(oe, a[1]); if (mm == 0) { printf("Uable to create MiniMacs Instance, leaving\n"); return 42; } printf("Inviting 1 party to computate on port 2020\n"); mm->invite(1,2020); mm->init_heap(6); C(mm->secret_input(0,0,Data_shallow("Rasmus",7))); C(mm->open(0)); C(mm->secret_input(0,1,Data_shallow("\001",1))); C(mm->secret_input(0,2,Data_shallow("\001",1))); C(mm->mul(3,1,2)); C(mm->open(3)); SymmetricMiniMacs_destroy( & mm ); } PrintMeasurements(oe); failure: return 0; }
static void mission_control_bang(MpcPeer mission_control) { byte _bang[256] = {0}; Data bang = Data_shallow(_bang,sizeof(_bang)); if (mission_control) { mission_control->receive(bang); } }
static void mission_control_stop(MpcPeer mission_control, uint myid) { byte raw_pid[256] = {0}; Data _pid = Data_shallow(raw_pid, sizeof(raw_pid)); uint pid = getpid(); i2b(pid, _pid->data); i2b(myid, _pid->data+4); if (mission_control) { mission_control->send(_pid); } }
static inline void replica_public_input(byte val, uint dst, MiniMacs mm) { uint rep = mm->get_ltext(); uint i = 0; byte * r = malloc(rep); for(i = 0;i < rep;++i) { r[i] = val; } mm->public_input( dst, Data_shallow(r,rep)); free(r); }
static int run(char * ip, uint myid, uint count, OE oe, MiniMacs mm) { CArena mc = CArena_new(oe); MpcPeer mission_control = 0; if (mc->connect("87.104.238.146", 65000).rc != 0) { oe->syslog(OSAL_LOGLEVEL_FATAL,"Failed to connect to the performance monitor."); return -1; }; mission_control = mc->get_peer(0); if (!mission_control) { oe->p("Failed connection to mission control. aborting.\n"); return -1; } if (mm->get_id() == 0) { if (mm->invite(1,2020+myid) != 0) { byte d[256] = {0}; char m[128] = {0}; osal_sprintf(m,"Failed to invite %u peers on port %u",1,2020+myid); oe->p(m); i2b(myid, d); osal_sprintf(d+4,"error"); mission_control->send(Data_shallow(d,128)); return 0; } } else { if (mm->connect(ip,2020+myid) != 0) { char m[128] = {0}; osal_sprintf(m,"Failed to connect to peer %s:%u",ip,2020+myid); oe->p(m); return 0; } } { byte key[128] = {0}; byte ptxt[128] = {0}; mpc_aes(mm,ptxt, key,myid,count,mission_control); CArena_destroy(&mc); } PrintMeasurements(oe); return 0; }
static inline replica_private_input(byte val, uint dst, MiniMacs mm) { uint rep = mm->get_ltext(); uint i = 0; byte * r = malloc(rep); uint player = 0; uint nplayers = mm->get_no_peers()+1; printf("ltext = %u\n", mm->get_ltext()); for(i = 0;i < rep;++i) { r[i] = val; } for(player = 0; player < nplayers;++player) { mm->secret_input(player,128,Data_shallow(r,rep)); mm->add(dst,128,dst); } free(r); }
int main(int c, char **a) { OE oe = OperatingEnvironment_LinuxNew(); init_polynomial(); if (oe) { MR mr = 0; MiniMacs mm = setup_generic_minimacs(oe, a[1]); printf("Inviting 1 party to computate on port 2020\n"); mm->invite(1,2020); mm->init_heap(6); // test secret input and open { MiniMacsRep rep = 0; byte data[85] = {0}; uint i = 0; for(i = 0;i < 85;++i) { data[i] = (byte)((i*101+65537)%255); } C(mm->secret_input(0,0,Data_shallow(data,85))); C(mm->open(0)); rep = mm->heap_get(0); if (!rep) { printf("Nothing to open\n"); return -1; } for(i = 0;i < 85;++i) { if (rep->codeword[i] != data[i]) { printf("Failure at possition %u\n",i); return -1; } } printf("Secret Input Done\n"); } // test multiply { byte data1[85] = {0}; byte data2[85] = {0}; byte p[85] = {0}; MiniMacsRep rep = 0; uint i = 0; for(i = 0; i < 85;++i) { data1[i] = (i*101+65537) % 255; data2[i] = (i*31+257) % 255; p[i] = multiply(multiply(data1[i], data2[i]), 42); } C(mm->secret_input(0,0,Data_shallow(data1,85))); C(mm->secret_input(0,1,Data_shallow(data2,85))); memset(data1,42,85); C(mm->secret_input(0,2,Data_shallow(data1,85))); C(mm->mul(3,0,1)); C(mm->mul(4,2,3)); C(mm->open(4)); rep = mm->heap_get(4); if (!rep) { printf("Rep is null.\n"); return -1; } for(i = 0;i < 85;++i) { if (rep->codeword[i] != p[i]) { printf("Failed at pos %u expected 0x04 got %u\n",i,rep->codeword[i]); return -1; } } } GenericMiniMacs_destroy( & mm ); } failure: return 0; }
/* * ] Connect to the monitor * * ] Listen for clients with ids greater than this client. * * ] Connect to clients with ids less than this client. (in this way * client 1 connects to no one and listens for every one, vice verse * client N connects to everyone and listens for no one.) * * ] Execute mpc_aes with the connected peers * * ] Destroy the CArena connected to comm with the monitor and leave. */ static int run(char * ip, uint myid, uint count, OE oe, MiniMacs mm) { CArena mc = CArena_new(oe); MpcPeer mission_control = 0; // connect to monitor if (mc->connect(bitlab, 65000).rc != 0) { oe->syslog(OSAL_LOGLEVEL_FATAL,"Failed to connect to the performance monitor."); return -1; }; mission_control = mc->get_peer(0); if (!mission_control) { oe->p("Failed connection to mission control. aborting.\n"); return -1; } // listen for all parties with id greater than mm->myid { byte msg[92] = {0}; uint port = 2020+100*mm->get_id(); uint wait4=mm->get_no_players()-(mm->get_id()+1); osal_sprintf(msg,"Waiting for %u players to connect.",wait4); oe->p(msg); if (wait4 > 0) { if (mm->invite(wait4,port) != 0) { byte d[256] = {0}; char m[128] = {0}; osal_sprintf(m,"Failed to invite %u peers on port %u",wait4,2020+myid); oe->syslog(OSAL_LOGLEVEL_FATAL,m); i2b(myid, d); osal_sprintf(d+4,"error"); mission_control->send(Data_shallow(d,128)); return 0; }; } } // connect to all parties with id less than mm->myid { int id = 0; for(id = mm->get_id()-1;id >= 0;--id) { byte address[16] = {0}; byte msg[92] = {0}; uint port = 2020+100*id; osal_sprintf(msg,"connecting to %u ...",port); oe->p(msg); osal_sprintf(address,"10.11.82.%d",id+1); if (mm->connect(address,port) != 0) { byte d[256] = {0}; char m[128] = {0}; osal_sprintf(m,"Failed to connect to %s peers on port %u",address,port); oe->syslog(OSAL_LOGLEVEL_FATAL,m); i2b(myid, d); osal_sprintf(d+4,"error"); mission_control->send(Data_shallow(d,128)); return 0; } } } // invoke AES circuit with zero plaintext and zero key { byte key[128] = {0}; byte ptxt[128] = {0}; mpc_aes(mm,ptxt, key,myid,count,mission_control); CArena_destroy(&mc); } // print time measurements if compiled in PrintMeasurements(oe); return 0; }
COO_DEF(Rtz14,bool,executeProof, List circuit, byte * witness, char * ip, uint port) { Rtz14Impl impl = (Rtz14Impl)this->impl; OE oe = impl->oe; Map input_gates = 0; CircuitVisitor emitter = 0; // TODO(rwz): take the igv as constructor argument. CircuitVisitor igv = 0; EmiterResult emitter_res = 0; byte * emitted_circuit = 0; CArena conn = 0; CircuitVisitor proof_task_builder = 0; List proof_tasks = 0; CircuitVisitor gpam = 0; CircuitVisitor poc = 0; CircuitVisitor ogv = 0; List output_gates = 0; Rnd rnd = 0; GPam gpam_res = 0; DateTime d = DateTime_New(oe); ull start = d->getMilliTime(); uint no_inputs = 0; _Bool accept = 0; ProofTask check_out_bit = (ProofTask)oe->getmem(sizeof(*check_out_bit)); // create and call helper strategies // TODO(rwz): strategies should be given as constructor arguments instead // of being created here. (for testability and maintainability) // default one address is 0, however it can be set during create of // RTZ14. poc = PatchOneConstants_New(oe,impl->address_of_one); if (!poc) return False; // patch addresses. poc->visit(circuit); // compute map mapping addresses to input igv = InputGateVisitor_New(oe); if (!igv) return False; input_gates = igv->visit(circuit); if (!input_gates) return False; no_inputs = input_gates->size(); ogv = OutputGateVisitor_New(oe); if (!ogv) return False; output_gates = ogv->visit(circuit); if (!output_gates) { return False; } if (output_gates->size() != 1) { oe->syslog(OSAL_LOGLEVEL_FATAL,"The provided circuit does not have one unique output."); return False; } check_out_bit->indicies[0] = output_gates->get_element(0); check_out_bit->indicies[1] = impl->address_of_one; check_out_bit->indicies[2] = impl->address_of_one; OutputGateVisitor_Destroy(&ogv); SingleLinkedList_destroy(&output_gates); // go online conn = CArena_new(oe); if (!conn) return False; if (ip == 0) { // ----------------------------- // ----------- Prover ---------- // ----------------------------- MpcPeer verifier = 0; byte and_challenge[1] = {0}; Data challenge_commitment = Data_new(oe,80); XORcommitResult xom = 0; Data epsilon = Data_new(oe,1); Data delta = 0; Data judgement = Data_new(oe,8); // The message containing the evaluated circuit, input bits (witness) // and the auxiliary informations for each and-gate. Data message = 0; if (witness == 0) { oe->syslog(OSAL_LOGLEVEL_FATAL,"No witness !"); return False; } UserReport(oe,"Prover preparing ... "); // compute evaluated circuit emitter = EvaluationStringEmitter_New(oe, input_gates, witness); if (!emitter) return False; emitter_res = emitter->visit(circuit); if (!emitter_res) return False; // generate random permutations and majority tests rnd = LibcWeakRandomSource_New(oe); if (!rnd) return False; gpam = GeneratePermuationsAndMajorities_New(oe,rnd, emitter_res->emitted_string, impl->address_of_one); if (!gpam) return False; gpam_res = gpam->visit(circuit); if (!gpam_res) return False; // create message { uint bit_i = 0; uint aux_bit_len = gpam_res->no_ands*3; uint emitted_string_bit_len = circuit->size() + no_inputs; uint bit_l = emitted_string_bit_len + aux_bit_len; message = Data_new(oe,(bit_l+7)/8); for(bit_i = 0; bit_i < bit_l;++bit_i) { if (bit_i < emitted_string_bit_len) { set_bit(message->data,bit_i,get_bit(emitter_res->emitted_string,bit_i)); } else { set_bit(message->data,bit_i,get_bit(gpam_res->aux,bit_i-emitted_string_bit_len)); } } } UserReport(oe, "Bit String Committed to: "); print_bit_string(oe,message); // inform the user what is happening UserReport(oe,"[%lums] Prover is Online and ready, awaiting Verifier to connect ... ",d->getMilliTime()-start); conn->listen_wait(1,port); oe->p("Verifier connected ... "); verifier = conn->get_peer(0); if (verifier == 0) { oe->syslog(OSAL_LOGLEVEL_FATAL,"Establishing listening socket or connection failed upon connection. Please check the given port is free and try again. "); return False; } // --------------------------------------------- // The Rtz14 protocol starts here for the prover // --------------------------------------------- UserReport(oe, "Starting proof"); start = d->getMilliTime(); // receive commitment to challenge from verifier. verifier->receive(challenge_commitment); oe->p("Verifier is committed to his challenges"); UserReport(oe,"[%lums] %s",d->getMilliTime()-start,"Verifier has committed to his challenge"); // build xor commit to the emitted string xom = xor_commit(oe,impl->rnd,impl->cs,message->data, message->ldata); UserReport(oe,"[%lums] %s",d->getMilliTime()-start,"[Prover] XOR Commitment prepared"); print_bit_string(oe,Data_shallow(xom->m0,xom->lm0)); print_bit_string(oe,Data_shallow(xom->m1,xom->lm1)); // send the emitted string verifier->send(Data_shallow(xom->commitment,xom->lcommitment)); // receive and and_challenge b verifier->receive(Data_shallow(and_challenge,1)); UserReport(oe,"[%lums] %s",d->getMilliTime()-start,"Received and challenge"); // send permutation or majority tests if (and_challenge[0] == 0) { check_out_bit->value = 3; verifier->send(Data_shallow(gpam_res->permutations,(gpam_res->no_ands*3+7)/8)); proof_task_builder = ProofTaskBuilder_New(oe,and_challenge[0],gpam_res->permutations,(gpam_res->no_ands*3+7)/8,no_inputs, impl->address_of_one); } else { verifier->send(Data_shallow(gpam_res->majority,(gpam_res->no_ands*2+7)/8)); proof_task_builder = ProofTaskBuilder_New(oe,and_challenge[0],gpam_res->majority,(gpam_res->no_ands*2+7)/8,no_inputs,impl->address_of_one); check_out_bit->value = 2; } UserReport(oe, "[%lums", d->getMilliTime()-start); // build linear proof tasks proof_tasks = proof_task_builder->visit(circuit); proof_tasks->add_element(check_out_bit); UserReport(oe,"[%lums] %u %s",d->getMilliTime()-start,proof_tasks->size(), "Proof Tasks computed ..."); // build delta string delta = build_delta_string(oe,proof_tasks,xom,and_challenge[0]); print_bit_string(oe,delta); // send delta string to verifier UserReport(oe,"[%lums] Sending delta string (%lu)",d->getMilliTime()-start,delta->ldata); verifier->send(delta); Data_destroy(oe,&delta); // challenge for the linear tests UserReport(oe,"[%lums] waiting for challenge (epsilon %u) ... ", d->getMilliTime()-start,epsilon->ldata); verifier->receive(epsilon); UserReport(oe,"[%lums] %s", d->getMilliTime()-start,"Delta string sent and challenge opened receive."); // send the m_epsilon string to the verifier if (epsilon->data[0] == 0) { UserReport(oe,"Sending m0 = %u",xom->lm0); verifier->send(Data_shallow(xom->m0,xom->lm0)); } else { UserReport(oe,"Sending m1 = %u",xom->lm0); verifier->send(Data_shallow(xom->m1,xom->lm1)); } // receive the string accept/reject from the verifier verifier->receive(judgement); UserReport(oe,"[%lums] %s",d->getMilliTime()-start,"Proof complete."); // tell result to prover. oe->p("The verifier says: "); oe->p((char *)judgement->data); if (judgement->data[0] == 'a') { accept = True; } else { accept = False; } //TODO(rwz): clean up /* Data_destroy(oe,&judgement); Data_destroy(oe,&message); Circuit_Destroy(oe, &circuit); GPam_Destroy(oe,&gpam); EvaluationStringEmitter_Destroy(&emitter); */ } else { // ----------------------------- // ---------- Verifier --------- // ----------------------------- // ---- The Rtz protocol starts here for the verifier --- MpcPeer prover = 0; Data challenge_commitment = 0; Data challenge = Data_new(oe,64); Data commitment_to_circuit = 0; Data and_challenge = Data_new(oe,1); Data permajor = 0; Data delta = 0; Data m_challenge = 0; uint i = 0, no_ands = 0; ull proto_time = 0; // generate random challenges and commit to them impl->rnd->rand(challenge->data,challenge->ldata); challenge->data[0] = challenge->data[0] % 2; challenge_commitment = impl->cs->commit(challenge); // generate random and-challenge (permutations or majority tests) impl->rnd->rand(and_challenge->data,and_challenge->ldata); and_challenge->data[0] = (and_challenge->data[0] % 2); UserReport(oe,"[%lums] %s", d->getMilliTime()-start,"Verifier connecting to Prover ... "); // connect to the prover conn->connect(ip,port); prover = conn->get_peer(0); if (!prover) { oe->p("No prover sorry, leaving."); return -2; } // send challenge commitment prover->send(challenge_commitment); UserReport(oe,"[%lums] %s %u bytes", d->getMilliTime()-start,"Commitment to challenge sent",challenge_commitment->ldata); // receive the xor-commitment to the circuit commitment_to_circuit = Data_new(oe,128); prover->receive(commitment_to_circuit); UserReport(oe,"[%lums] %s", d->getMilliTime()-start,"Circuit XOM commitments received."); proto_time = d->getMilliTime(); // send the and challenge prover->send(and_challenge); UserReport(oe,"[%lums] %s", d->getMilliTime()-start,"And challenge sent"); // count number of ands to anticipate size permajor for(i = 0; i < circuit->size();++i) { Gate g = circuit->get_element(i); if (g->type == G_AND) no_ands ++; } // allocate permajor if (and_challenge->data[0] == 0) { // permutations permajor = Data_new(oe,(3*no_ands+7)/8); } else { // majority permajor = Data_new(oe,(2*no_ands+7)/8); } // receive permutation or majority tests prover->receive(permajor); UserReport(oe,"[%lums] %s", d->getMilliTime()-start,"Received permutations/majority tests"); // compute proof tasks the prover must do proof_task_builder = ProofTaskBuilder_New(oe,and_challenge->data[0], permajor->data,permajor->ldata, no_inputs, impl->address_of_one); proof_tasks = proof_task_builder->visit(circuit); UserReport(oe,"[%lums] %u %s", d->getMilliTime()-start,proof_tasks->size(), "Proof Tasks built..."); if (and_challenge->data[0] == 0) { check_out_bit->value = 3; proof_tasks->add_element(check_out_bit); } else { check_out_bit->value = 2; } // --- Do linear proofs --- // --- Receive Delta --- delta = Data_new(oe,(proof_tasks->size()+7)/8); UserReport(oe, "[%lums] %s delta->size %lu", d->getMilliTime()-start,"Waiting for delta string",delta->ldata); prover->receive(delta); UserReport(oe,"[%lums] %s", d->getMilliTime()-start,"Received deltas from Prover..."); // send the committed to challenge from the beginning challenge->ldata =1; prover->send(challenge); // receive m_{challange} m_challenge = Data_new(oe,(input_gates->size() + circuit->size()+no_ands*3+7)/8); prover->receive(m_challenge); UserReport(oe,"[%lums] %s", d->getMilliTime()-start,"Received XOM partial opening, checking linear relations ..."); UserReport(oe,"%lums] %s", d->getMilliTime()-start, "Delta:"); print_bit_string(oe,delta); UserReport(oe,"m_challenge = %u",m_challenge->ldata); print_bit_string(oe,m_challenge); accept = True; for(i = 0; i < proof_tasks->size();++i) { byte xor = 0; byte b = 0; uint j = 0; ProofTask cur = proof_tasks->get_element(i); uint * indicies = (uint *)&cur->indicies; uint lindicies = cur->value >> 1; b = (cur->value & 0x01); for(j = 0;j < lindicies;++j) { uint index_j = (uint)indicies[j]; xor ^= get_bit(m_challenge->data,index_j); } if (xor != ((byte)get_bit(delta->data,i) ^ (challenge->data[0] & b))) { accept = False; UserReport(oe,"Proof Task %u failed [{%u,%u,%u},%u].",i,cur->indicies[0],cur->indicies[1],cur->indicies[2],cur->value); } } UserReport(oe, " PROTOCOL TOOK: %llu ms", d->getMilliTime() - proto_time); if (accept) { prover->send(Data_shallow((byte*)"accept ",8)); oe->p("Verifier accepted proof."); accept = True; } else { prover->send(Data_shallow((byte*)"reject ",8)); oe->p("Verifier rejected proof"); accept = 0; } UserReport(oe,"[%lums] %s", d->getMilliTime()-start,"Verifier Done."); } { byte aes[] = {0x66,0xE9,0x4B,0xD4,0xEF,0x8A,0x2C,0x3B,0x88,0x4C,0xFA,0x59,0xCA,0x34,0x2B,0x2E}; UserReport(oe,"These are the bits we are looking for !"); print_bit_string(oe,Data_shallow(aes,sizeof(aes))); } // close all connections. CArena_destroy(&conn); return accept; error: return accept; }}