BOOL ALSZOTExtSnd::CheckConsistency(queue<alsz_snd_check_t>* check_buf_q, channel* check_chan) { uint8_t *rcvhashbufptr, *seedbufsrvptr, *rcvbufsrvptr, *rcvhashbuf; uint32_t ida, idb, receiver_hashes = 4; uint64_t checkbytelen= receiver_hashes * OWF_BYTES, tmpid, tmpnblocks, seedhashcli, rcvhashcli; uint8_t* rcvbuf = check_chan->blocking_receive_id_len(&rcvhashbuf, &tmpid, &tmpnblocks); uint8_t ca, cb; alsz_snd_check_t check_buf = check_buf_q->front(); check_buf_q->pop(); //Should be fine since the blocks are handled sequentially - but recheck anyway assert(check_buf.otid == tmpid); assert(check_buf.numblocks == tmpnblocks); uint32_t blockoffset = ceil_divide(check_buf.otid, NUMOTBLOCKS * m_nBlockSizeBytes); uint32_t offset = 0 ;//m_nBaseOTs * blockoffset;//TODO, put offset in again when 3-stop ot is implemented rcvhashbufptr = rcvhashbuf; seedbufsrvptr = check_buf.seed_chk_buf; rcvbufsrvptr = check_buf.rcv_chk_buf; for(uint32_t i = 0, j; i < m_nChecks; i++, rcvhashbufptr+=checkbytelen) { ida = check_buf.perm[i].ida; idb = check_buf.perm[i].idb; assert(ida < m_nBaseOTs && idb < m_nBaseOTs); ca = m_vU.GetBit(ida + offset); cb = m_vU.GetBit(idb + offset); //check that ida+idb == seedbufcheck and (!ida) + (!idb) == rcvbufcheck for(j = 0; j < ceil_divide(OWF_BYTES,sizeof(uint64_t)); j++, seedbufsrvptr+=sizeof(uint64_t), rcvbufsrvptr+=sizeof(uint64_t)) { seedhashcli = *(((uint64_t*) rcvhashbufptr) + (2*ca+cb)*2 + j); rcvhashcli = *(((uint64_t*) rcvhashbufptr) + (2*(ca^1)+(cb^1))*2 + j); if(seedhashcli != *((uint64_t*) seedbufsrvptr) || rcvhashcli != *((uint64_t*) rcvbufsrvptr)) { #ifdef DEBUG_ALSZ_CHECKS cout << "Error in " << i <<"-th consistency check between " << ida << " and " << idb <<" : " << endl; cout << "Receiver seed = " << (hex) << ((uint64_t*) (rcvhashbufptr+((2*ca+cb) * OWF_BYTES)))[0] << ((uint64_t*) (rcvhashbufptr+((2*ca+cb) * OWF_BYTES) + j))[1] << ", my seed: " << ((uint64_t*) seedbufsrvptr)[0] << ((uint64_t*) seedbufsrvptr)[1] << (dec) << endl; cout << "Receiver sndval = " << (hex) << ((uint64_t*) (rcvhashbufptr+((2*(ca^1)+(cb^1)) * OWF_BYTES) + j))[0] << ((uint64_t*) (rcvhashbufptr+((2*(ca^1)+(cb^1)) * OWF_BYTES) + j))[1] << ", my snd val = " << ((uint64_t*) rcvbufsrvptr)[0] << ((uint64_t*) rcvbufsrvptr)[1] << (dec) << endl; #endif return false; } } } //free the receive buffer free(rcvbuf); free(check_buf.perm); free(check_buf.rcv_chk_buf); free(check_buf.seed_chk_buf); return TRUE; }
void prime_field::init(seclvl sp, uint8_t* seed) { mpz_t rnd_seed; //TODO: change to inits if working correctly mpz_init(p); mpz_init(g); mpz_init(q); mpz_init(rnd_seed); secparam = sp; mpz_import(rnd_seed, secparam.symbits, 1, sizeof((seed)[0]), 0, 0, seed); if (secparam.ifcbits == ST.ifcbits) { mpz_set_str(p, ifcp1024, 16); mpz_set_str(g, ifcg1024, 16); mpz_set_str(q, ifcq1024, 16); } else if (secparam.ifcbits == MT.ifcbits) { mpz_set_str(p, ifcp2048, 16); mpz_set_str(g, ifcg2048, 16); mpz_set_str(q, ifcq2048, 16); } else if (secparam.ifcbits == LT.ifcbits) { mpz_set_str(p, ifcp3072, 10); mpz_set_str(g, ifcg3072, 10); mpz_set_str(q, ifcq3072, 10); } else //Long term security { mpz_set_str(p, ifcp3072, 10); mpz_set_str(g, ifcg3072, 10); mpz_set_str(q, ifcq1024, 10); } gmp_randinit_default(rnd_state); gmp_randseed(rnd_state, rnd_seed); fe_bytelen = ceil_divide(secparam.ifcbits, 8); }
//Initialize and start numThreads OTSenderThread BOOL OTExtSnd::start_send(uint32_t numThreads) { if (m_nOTs == 0) return true; if(numThreads * m_nBlockSizeBits > m_nOTs && numThreads > 1) { cerr << "Decreasing nthreads from " << numThreads << " to " << max(m_nOTs / m_nBlockSizeBits, (uint64_t) 1) << " to fit window size" << endl; numThreads = max(m_nOTs / m_nBlockSizeBits, (uint64_t) 1); } //The total number of OTs that is performed has to be a multiple of numThreads*Z_REGISTER_BITS uint32_t wd_size_bits = m_nBlockSizeBits;//pad_to_power_of_two(m_nBaseOTs);//1 << (ceil_log2(m_nBaseOTs)); //uint64_t numOTs = ceil_divide(PadToMultiple(m_nOTs, wd_size_bits), numThreads); uint64_t internal_numOTs = PadToMultiple(ceil_divide(m_nOTs, numThreads), wd_size_bits); vector<OTSenderThread*> sThreads(numThreads); for (uint32_t i = 0; i < numThreads; i++) { sThreads[i] = new OTSenderThread(i, internal_numOTs, this); sThreads[i]->Start(); } for (uint32_t i = 0; i < numThreads; i++) { sThreads[i]->Wait(); } m_nCounter += m_nOTs; for (uint32_t i = 0; i < numThreads; i++) { delete sThreads[i]; } #ifdef VERIFY_OT verifyOT(m_nOTs); #endif return true; }
void ALSZOTExtSnd::genRandomPermutation(linking_t* outperm, uint32_t nids, uint32_t nperms) { uint32_t rndbits = m_nSymSecParam * nperms; uint64_t bitsint = (8*sizeof(uint32_t)); uint32_t rnditers = ceil_divide(m_cCrypt->get_seclvl().symbits, bitsint); CBitVector rndstring; rndstring.Create((uint64_t) rnditers * nperms, bitsint, m_cCrypt); uint64_t tmpval = 0, tmprnd; for(uint32_t i = 0, rndctr=0, j; i < nperms; i++) { outperm[i].ida = i % nids; //if(outperm[i].ida == 0) outperm[i].ida++; /*for(j = 0; j < rnditers; j++, rndctr++) { tmprnd = rndstring.Get<uint32_t>(rndctr); tmpval = ((uint64_t) (tmpval << bitsint) | tmprnd); tmpval = tmpval % nids; }*/ m_cCrypt->gen_rnd_uniform(&outperm[i].idb, nids); //outperm[i].idb = 0; //if(outperm[i].idb == 0) outperm[i].idb++; //cout << "Permutation " << i << ": " << outperm[i].ida << " <-> " << outperm[i].idb << endl; } rndstring.delCBitVector(); }
alsz_snd_check_t ALSZOTExtSnd::UpdateCheckBuf(uint8_t* tocheckseed, uint8_t* tocheckrcv, uint64_t otid, uint64_t numblocks, channel* check_chan) { uint64_t rowbytelen = m_nBlockSizeBytes * numblocks; uint8_t* hash_buf = (uint8_t*) malloc(SHA512_DIGEST_LENGTH); //uint8_t* tmpbuf = (uint8_t*) malloc(rowbytelen); uint8_t** tmpbuf = (uint8_t**) malloc(2 * sizeof(uint8_t*)); uint8_t *idaptr, *idbptr; alsz_snd_check_t check_buf; check_buf.rcv_chk_buf = (uint8_t*) malloc(m_nChecks * OWF_BYTES); check_buf.seed_chk_buf = (uint8_t*) malloc(m_nChecks * OWF_BYTES); uint8_t *seedcheckbufptr = check_buf.seed_chk_buf, *rcvcheckbufptr = check_buf.rcv_chk_buf; uint32_t iters = rowbytelen/sizeof(uint64_t); for(uint32_t i = 0; i < 2; i++) { tmpbuf[i] = (uint8_t*) malloc(rowbytelen); } check_buf.otid = otid; check_buf.numblocks = numblocks; check_buf.perm = (linking_t*) malloc(sizeof(linking_t*) * m_nChecks); genRandomPermutation(check_buf.perm, m_nBaseOTs, m_nChecks); //right now the rowbytelen needs to be a multiple of AES_BYTES assert(ceil_divide(rowbytelen, OWF_BYTES) * OWF_BYTES == rowbytelen); #ifdef DEBUG_ALSZ_CHECKS cout << "rowbytelen = " << rowbytelen << endl; m_vU.PrintHex(); #endif uint8_t *pas, *pbs, *par, *pbr; for(uint64_t i = 0; i < m_nChecks; i++, seedcheckbufptr+=OWF_BYTES, rcvcheckbufptr+=OWF_BYTES) { //memset(tmpbuf, 0, rowbytelen); #ifdef DEBUG_ALSZ_CHECKS cout << i << "-th check between " << check_buf.perm[i].ida << " and " << check_buf.perm[i].idb << ": " << endl; #endif pas = tocheckseed + check_buf.perm[i].ida * rowbytelen; pbs = tocheckseed + check_buf.perm[i].idb * rowbytelen; par = tocheckrcv + check_buf.perm[i].ida * rowbytelen; pbr = tocheckrcv + check_buf.perm[i].idb * rowbytelen; for(uint64_t j = 0; j < iters; j++) { ((uint64_t*) tmpbuf[0])[j] = ((uint64_t*) pas)[j] ^ ((uint64_t*) pbs)[j]; ((uint64_t*) tmpbuf[1])[j] = ((uint64_t*) tmpbuf[0])[j] ^ ((uint64_t*) par)[j] ^ ((uint64_t*) pbr)[j]; } sha512_hash(seedcheckbufptr, OWF_BYTES, tmpbuf[0], rowbytelen, hash_buf); sha512_hash(rcvcheckbufptr, OWF_BYTES, tmpbuf[1], rowbytelen, hash_buf); /*XORandOWF(tocheckseed + check_buf.perm[i].ida * rowbytelen, tocheckseed + check_buf.perm[i].idb * rowbytelen, rowbytelen, tmpbuf, seedcheckbufptr, hash_buf); XORandOWF(tocheckrcv + check_buf.perm[i].ida * rowbytelen, tocheckrcv + check_buf.perm[i].idb * rowbytelen, rowbytelen, tmpbuf, rcvcheckbufptr, hash_buf);*/ } for(uint32_t i = 0; i < 2; i++) free(tmpbuf[i]); free(tmpbuf); //free(tmpbuf); free(hash_buf); //Send the permutation over to the receiver check_chan->send_id_len((uint8_t*) check_buf.perm, sizeof(linking_t) * m_nChecks, otid, numblocks); return check_buf; }
BOOL OTExtSnd::verifyOT(uint64_t NumOTs) { cout << "Verifying OT" << endl; uint64_t processedOTBlocks, OTsPerIteration; uint32_t bytelen = ceil_divide(m_nBitLength, 8); uint64_t nSnd; uint8_t* resp; channel* chan = new channel(0, m_cRcvThread, m_cSndThread); for (uint64_t i = 0; i < NumOTs; i += OTsPerIteration) { processedOTBlocks = min((uint64_t) NUMOTBLOCKS, ceil_divide(NumOTs - i, AES_BITS)); OTsPerIteration = min(processedOTBlocks * AES_BITS, NumOTs - i); nSnd = ceil_divide(OTsPerIteration * m_nBitLength, 8); chan->send_id_len(m_vValues[0].GetArr() + bits_in_bytes(i * m_nBitLength), nSnd, i, OTsPerIteration); chan->send_id_len(m_vValues[1].GetArr() + bits_in_bytes(i * m_nBitLength), nSnd, i, OTsPerIteration); //sndthread->add_snd_task_start_len(0, nSnd, m_vValues[0].GetArr() + bits_in_bytes(i * m_nBitLength), i, OTsPerIteration); //sndthread->add_snd_task_start_len(0, nSnd, m_vValues[1].GetArr() + bits_in_bytes(i * m_nBitLength), i, OTsPerIteration); //cout << "Waiting for reply" << endl; resp = chan->blocking_receive(); //rcvev->Wait(); //resp = *rcvqueue->front(); //rcvqueue->pop(); //cout << "Got reply with " << (uint32_t) resp << endl; if (*resp == 0x00) { cout << "OT verification unsuccessful" << endl; free(resp); chan->synchronize_end(); return false; } free(resp); } //cout << "signalling end" << endl, //sndthread->signal_end(0); cout << "OT Verification successful" << flush << endl; chan->synchronize_end(); return true; }
void *gen_cuckoo_entries(void *ctx_void) { cuckoo_entry_gen_ctx* ctx = (cuckoo_entry_gen_ctx*) ctx_void; hs_t* hs = ctx->hs; uint32_t i, inbytelen = ceil_divide(hs->inbitlen, 8); uint8_t* eleptr = ctx->elements + inbytelen * ctx->startpos; //generate the cuckoo entries for all elements for(i = ctx->startpos; i < ctx->endpos; i++, eleptr+=inbytelen) { gen_cuckoo_entry(eleptr, ctx->cuckoo_entries + i, hs, i); } }
BaseMPSIParty::BaseMPSIParty(uint32_t partyId, ConfigFile &config, boost::asio::io_service &ioService) : MultiPartyPlayer(partyId,config,ioService) { LoadConfiguration(); m_elements.reset(new uint8_t[m_setSize*ceil_divide(m_elementSizeInBits,8)]); PRINT_PARTY(m_partyId) << "is receiving elements" << std::endl; m_serverSocket.Receive(reinterpret_cast<byte *>(m_elements.get()), m_setSize*ceil_divide(m_elementSizeInBits,8)); m_seedBuf.reset(new uint8_t[m_seedSize]); m_serverSocket.Receive(m_seedBuf.get(), m_seedSize*sizeof(uint8_t)); m_crypt.reset(initializeCrypto()); uint64_t rnd; m_crypt->gen_rnd((uint8_t*) &rnd, sizeof(uint64_t)); srand((unsigned)rnd+time(0)); m_parameters.m_statSecParameter = m_crypt->get_seclvl().statbits; m_crypt->init_prf_state(&m_prfState, m_seedBuf.get()); }
uint32_t naivepsi(role_type role, uint32_t neles, uint32_t pneles, task_ctx ectx, crypto* crypt_env, CSocket* sock, uint32_t ntasks, uint32_t* matches) { uint32_t i, intersect_size, maskbytelen; //task_ctx_naive ectx; CSocket* tmpsock = sock; uint32_t* perm; uint8_t *hashes, *phashes; maskbytelen = ceil_divide(crypt_env->get_seclvl().statbits + ceil_log2(neles) + ceil_log2(pneles), 8); hashes = (uint8_t*) malloc(sizeof(uint8_t) * neles * maskbytelen); perm = (uint32_t*) malloc(sizeof(uint32_t) * neles); /* Generate the random permutation the elements */ crypt_env->gen_rnd_perm(perm, neles); /* Hash and permute elements */ #ifdef DEBUG cout << "Hashing my elements" << endl; #endif //ectx.eles.input = permeles; //ectx.eles.inbytelen = elebytelen; ectx.eles.outbytelen = maskbytelen, ectx.eles.nelements = neles; ectx.eles.output = hashes; ectx.eles.perm = perm; ectx.sctx.symcrypt = crypt_env; run_task(ntasks, ectx, psi_hashing_function); phashes = (uint8_t*) malloc(sizeof(uint8_t) * pneles * maskbytelen); #ifdef DEBUG cout << "Exchanging hashes" << endl; #endif snd_and_rcv(hashes, neles * maskbytelen, phashes, pneles * maskbytelen, tmpsock); /*cout << "Hashes of my elements: " << endl; for(i = 0; i < neles; i++) { for(uint32_t j = 0; j < maskbytelen; j++) { cout << (hex) << (uint32_t) hashes[i * maskbytelen + j] << (dec); } cout << endl; } cout << "Hashes of partner elements: " << endl; for(i = 0; i < pneles; i++) { for(uint32_t j = 0; j < maskbytelen; j++) { cout << (hex) << (uint32_t) phashes[i * maskbytelen + j] << (dec); } cout << endl; }*/ #ifdef DEBUG cout << "Finding intersection" << endl; #endif intersect_size = find_intersection(hashes, neles, phashes, pneles, maskbytelen, perm, matches); #ifdef DEBUG cout << "Free-ing allocated memory" << endl; #endif free(perm); free(hashes); //free(permeles); free(phashes); return intersect_size; }
BOOL ALSZOTExtRec::receiver_routine(uint32_t id, uint64_t myNumOTs) { uint64_t myStartPos = id * myNumOTs; uint64_t wd_size_bits = m_nBlockSizeBits; uint64_t internal_numOTs = std::min(myNumOTs + myStartPos, m_nOTs) - myStartPos; uint64_t lim = myStartPos + internal_numOTs; uint64_t processedOTBlocks = std::min(num_ot_blocks, ceil_divide(internal_numOTs, wd_size_bits)); uint64_t OTsPerIteration = processedOTBlocks * wd_size_bits; uint64_t OTwindow = num_ot_blocks * wd_size_bits; uint64_t** rndmat; bool use_mat_chan = (m_eSndOTFlav == Snd_GC_OT || m_bUseMinEntCorRob); uint32_t nchans = 2; if(use_mat_chan) { nchans = 3; } channel* ot_chan = new channel(OT_BASE_CHANNEL+nchans*id, m_cRcvThread, m_cSndThread); channel* check_chan = new channel(OT_BASE_CHANNEL+nchans*id+1, m_cRcvThread, m_cSndThread); channel* mat_chan; if(use_mat_chan) { mat_chan = new channel(nchans*id+2, m_cRcvThread, m_cSndThread); } // A temporary part of the T matrix CBitVector T(wd_size_bits * OTsPerIteration); // The send buffer CBitVector vSnd(m_nBaseOTs * OTsPerIteration); // A temporary buffer that stores the resulting seeds from the hash buffer //TODO: Check for some maximum size CBitVector seedbuf(OTwindow * m_cCrypt->get_aes_key_bytes() * 8); uint64_t otid = myStartPos; std::queue<alsz_rcv_check_t> check_buf; std::queue<mask_block*> mask_queue; CBitVector maskbuf; maskbuf.Create(m_nBitLength * OTwindow); //these two values are only required for the min entropy correlation robustness assumption alsz_rcv_check_t check_tmp; CBitVector Ttmp(wd_size_bits * OTsPerIteration); OT_AES_KEY_CTX* tmp_base_keys; uint64_t base_ot_block_ctr = otid / (myNumOTs); //TODO only do when successfull checks if(m_eSndOTFlav == Snd_GC_OT) { initRndMatrix(&rndmat, m_nBitLength, m_nBaseOTs); } #ifdef OTTiming double totalMtxTime = 0, totalTnsTime = 0, totalHshTime = 0, totalRcvTime = 0, totalSndTime = 0, totalChkTime = 0, totalMaskTime = 0, totalEnqueueTime = 0, totalOutputSetTime = 0; timespec tempStart, tempEnd; #endif while (otid < lim) { processedOTBlocks = std::min(num_ot_blocks, ceil_divide(lim - otid, wd_size_bits)); OTsPerIteration = processedOTBlocks * wd_size_bits; //nSize = bits_in_bytes(m_nBaseOTs * OTsPerIteration); tmp_base_keys = m_tBaseOTKeys[base_ot_block_ctr]; //m_tBaseOTQ.pop(); #ifdef OTTiming clock_gettime(CLOCK_MONOTONIC, &tempStart); #endif BuildMatrices(&T, &vSnd, otid, processedOTBlocks, tmp_base_keys); #ifdef OTTiming clock_gettime(CLOCK_MONOTONIC, &tempEnd); totalMtxTime += getMillies(tempStart, tempEnd); clock_gettime(CLOCK_MONOTONIC, &tempStart); #endif check_buf.push(EnqueueSeed(T.GetArr(), vSnd.GetArr(), otid, processedOTBlocks)); #ifdef OTTiming clock_gettime(CLOCK_MONOTONIC, &tempEnd); totalEnqueueTime += getMillies(tempStart, tempEnd); clock_gettime(CLOCK_MONOTONIC, &tempStart); #endif MaskBaseOTs(&T, &vSnd, otid, processedOTBlocks); #ifdef OTTiming clock_gettime(CLOCK_MONOTONIC, &tempEnd); totalMaskTime += getMillies(tempStart, tempEnd); clock_gettime(CLOCK_MONOTONIC, &tempStart); #endif SendMasks(&vSnd, ot_chan, otid, OTsPerIteration); //ot_chan->send_id_len(vSnd.GetArr(), nSize, otid, OTsPerIteration); #ifdef OTTiming clock_gettime(CLOCK_MONOTONIC, &tempEnd); totalSndTime += getMillies(tempStart, tempEnd); clock_gettime(CLOCK_MONOTONIC, &tempStart); #endif ReceiveAndFillMatrix(rndmat, mat_chan); if(!m_bUseMinEntCorRob) { T.Transpose(wd_size_bits, OTsPerIteration); #ifdef OTTiming clock_gettime(CLOCK_MONOTONIC, &tempEnd); totalTnsTime += getMillies(tempStart, tempEnd); clock_gettime(CLOCK_MONOTONIC, &tempStart); #endif HashValues(&T, &seedbuf, &maskbuf, otid, std::min(lim - otid, OTsPerIteration), rndmat); #ifdef OTTiming clock_gettime(CLOCK_MONOTONIC, &tempEnd); totalHshTime += getMillies(tempStart, tempEnd); clock_gettime(CLOCK_MONOTONIC, &tempStart); #endif } if(check_chan->data_available()) { if(m_bUseMinEntCorRob) { check_tmp = check_buf.front(); Ttmp.Copy(check_tmp.T0, 0, check_tmp.numblocks * m_nBlockSizeBytes); } ComputeOWF(&check_buf, check_chan); if(m_bUseMinEntCorRob) { ReceiveAndXORCorRobVector(&Ttmp, check_tmp.numblocks * wd_size_bits, mat_chan); Ttmp.Transpose(wd_size_bits, OTsPerIteration); HashValues(&Ttmp, &seedbuf, &maskbuf, check_tmp.otid, std::min(lim - check_tmp.otid, check_tmp.numblocks * wd_size_bits), rndmat); } #ifdef OTTiming clock_gettime(CLOCK_MONOTONIC, &tempEnd); totalChkTime += getMillies(tempStart, tempEnd); clock_gettime(CLOCK_MONOTONIC, &tempStart); #endif } SetOutput(&maskbuf, otid, OTsPerIteration, &mask_queue, ot_chan); otid += std::min(lim - otid, OTsPerIteration); base_ot_block_ctr++; #ifdef OTTiming clock_gettime(CLOCK_MONOTONIC, &tempEnd); totalOutputSetTime += getMillies(tempStart, tempEnd); #endif //free(tmp_base_keys); //free(tmp_baseots); vSnd.Reset(); T.Reset(); } while(!check_buf.empty()) { if(check_chan->data_available()) { if(m_bUseMinEntCorRob) { check_tmp = check_buf.front(); Ttmp.Copy(check_tmp.T0, 0, check_tmp.numblocks * m_nBlockSizeBytes); } #ifdef OTTiming clock_gettime(CLOCK_MONOTONIC, &tempStart); #endif ComputeOWF(&check_buf, check_chan); #ifdef OTTiming clock_gettime(CLOCK_MONOTONIC, &tempEnd); totalChkTime += getMillies(tempStart, tempEnd); #endif if(m_bUseMinEntCorRob) { ReceiveAndXORCorRobVector(&Ttmp, check_tmp.numblocks * wd_size_bits, mat_chan); Ttmp.Transpose(wd_size_bits, OTsPerIteration); HashValues(&Ttmp, &seedbuf, &maskbuf, check_tmp.otid, std::min(lim - check_tmp.otid, check_tmp.numblocks * wd_size_bits), rndmat); } } } if(m_eSndOTFlav != Snd_R_OT) { //finevent->Wait(); #ifdef ABY_OT while(!(mask_queue.empty())) { #else while(ot_chan->is_alive() && !(mask_queue.empty())) { #endif #ifdef OTTiming clock_gettime(CLOCK_MONOTONIC, &tempStart); #endif ReceiveAndUnMask(ot_chan, &mask_queue); #ifdef OTTiming clock_gettime(CLOCK_MONOTONIC, &tempEnd); totalOutputSetTime += getMillies(tempStart, tempEnd); #endif } } ot_chan->synchronize_end(); check_chan->synchronize_end(); delete ot_chan; delete check_chan; T.delCBitVector(); vSnd.delCBitVector(); seedbuf.delCBitVector(); maskbuf.delCBitVector(); Ttmp.delCBitVector(); if(use_mat_chan) { mat_chan->synchronize_end(); delete mat_chan; } if(m_eSndOTFlav==Snd_GC_OT) { freeRndMatrix(rndmat, m_nBaseOTs); } #ifdef OTTiming std::cout << "Receiver time benchmark for performing " << internal_numOTs << " OTs on " << m_nBitLength << " bit strings" << std::endl; std::cout << "Time needed for: " << std::endl; std::cout << "\t Matrix Generation:\t" << totalMtxTime << " ms" << std::endl; std::cout << "\t Enqueuing Seeds:\t" << totalEnqueueTime << " ms" << std::endl; std::cout << "\t Base OT Masking:\t" << totalMaskTime << " ms" << std::endl; std::cout << "\t Sending Matrix:\t" << totalSndTime << " ms" << std::endl; std::cout << "\t Transposing Matrix:\t" << totalTnsTime << " ms" << std::endl; std::cout << "\t Hashing Matrix:\t" << totalHshTime << " ms" << std::endl; std::cout << "\t Receiving Values:\t" << totalRcvTime << " ms" << std::endl; std::cout << "\t Checking OWF: \t" << totalChkTime << " ms" << std::endl; std::cout << "\t Setting Output:\t" << totalOutputSetTime << " ms" << std::endl; #endif return TRUE; } void ALSZOTExtRec::ReceiveAndFillMatrix(uint64_t** rndmat, channel* mat_chan) { if(m_eSndOTFlav == Snd_GC_OT) { uint8_t* rnd_seed = mat_chan->blocking_receive(); //initRndMatrix(&rndmat, m_nBitLength, m_nBaseOTs); fillRndMatrix(rnd_seed, rndmat, m_nBitLength, m_nBaseOTs, m_cCrypt); free(rnd_seed); } } alsz_rcv_check_t ALSZOTExtRec::EnqueueSeed(uint8_t* T0, uint8_t* T1, uint64_t otid, uint64_t numblocks) { uint64_t expseedbytelen = m_nBaseOTs * numblocks * m_nBlockSizeBytes; alsz_rcv_check_t seedstr; seedstr.otid = otid; seedstr.numblocks = numblocks; seedstr.T0 = (uint8_t*) malloc(expseedbytelen); seedstr.T1 = (uint8_t*) malloc(expseedbytelen); memcpy(seedstr.T0, T0, expseedbytelen); memcpy(seedstr.T1, T1, expseedbytelen); return seedstr; }
BOOL NNOBOTExtSnd::sender_routine(uint32_t id, uint64_t myNumOTs) { uint64_t myStartPos = id * myNumOTs; uint64_t wd_size_bits = m_nBlockSizeBits; uint64_t processedOTBlocks = min((uint64_t) NUMOTBLOCKS, ceil_divide(myNumOTs, wd_size_bits)); uint64_t OTsPerIteration = processedOTBlocks * wd_size_bits; uint64_t tmpctr, tmpotlen; uint32_t nchans = 2; bool use_mat_chan = (m_eSndOTFlav == Snd_GC_OT || m_bUseMinEntCorRob); if(use_mat_chan) { nchans = 3; } channel* ot_chan = new channel(nchans*id, m_cRcvThread, m_cSndThread); channel* check_chan = new channel(nchans*id + 1, m_cRcvThread, m_cSndThread); channel* mat_chan; if(use_mat_chan) { mat_chan = new channel(nchans*id+2, m_cRcvThread, m_cSndThread); } myNumOTs = min(myNumOTs + myStartPos, m_nOTs) - myStartPos; uint64_t lim = myStartPos + myNumOTs; uint64_t** rndmat; // The vector with the received bits CBitVector vRcv(m_nBaseOTs * OTsPerIteration); vRcv.Reset(); // Holds the reply that is sent back to the receiver uint32_t numsndvals = 2; CBitVector* vSnd; CBitVector* seedbuf = new CBitVector[m_nSndVals]; for (uint32_t u = 0; u < m_nSndVals; u++) seedbuf[u].Create(OTsPerIteration * m_cCrypt->get_aes_key_bytes() * 8); #ifdef ZDEBUG cout << "seedbuf size = " <<OTsPerIteration * AES_KEY_BITS << endl; #endif vSnd = new CBitVector[numsndvals]; for (uint32_t i = 0; i < numsndvals; i++) { vSnd[i].Create(OTsPerIteration * m_nBitLength); } // Contains the parts of the V matrix CBitVector Q(wd_size_bits * OTsPerIteration); mask_buf_t tmpmaskbuf; uint64_t OT_ptr = myStartPos; uint8_t *rcvbuftmpptr, *rcvbufptr; queue<nnob_snd_check_t> check_queue; queue<mask_buf_t> mask_queue; uint32_t startpos = 0; if(m_eRecOTFlav==Rec_R_OT) { startpos = 1; } if(m_eSndOTFlav == Snd_GC_OT) { initRndMatrix(&rndmat, m_nBitLength, m_nBaseOTs); } #ifdef OTTiming double totalMtxTime = 0, totalTnsTime = 0, totalHshTime = 0, totalRcvTime = 0, totalSndTime = 0, totalUnMaskTime = 0, totalHashCheckTime = 0; timeval tempStart, tempEnd; #endif while (OT_ptr < lim) //do while there are still transfers missing { processedOTBlocks = min((uint64_t) NUMOTBLOCKS, ceil_divide(lim - OT_ptr, wd_size_bits)); OTsPerIteration = processedOTBlocks * wd_size_bits; #ifdef ZDEBUG cout << "Processing block " << nProgress << " with length: " << OTsPerIteration << ", and limit: " << lim << endl; #endif #ifdef OTTiming gettimeofday(&tempStart, NULL); #endif rcvbufptr = ot_chan->blocking_receive_id_len(&rcvbuftmpptr, &tmpctr, &tmpotlen); //vRcv.AttachBuf(rcvbuftmpptr, bits_in_bytes(m_nBaseOTs * OTsPerIteration)); vRcv.SetBytes(rcvbuftmpptr, bits_in_bytes(OTsPerIteration*startpos), bits_in_bytes((m_nBaseOTs-startpos)*OTsPerIteration)); free(rcvbufptr); //vRcv.PrintHex(); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalRcvTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif BuildQMatrix(Q, OT_ptr, processedOTBlocks); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalMtxTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif check_queue.push(UpdateCheckBuf(Q.GetArr(), vRcv.GetArr(), OT_ptr, processedOTBlocks, check_chan)); FillAndSendRandomMatrix(rndmat, mat_chan); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalHashCheckTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif UnMaskBaseOTs(Q, vRcv, processedOTBlocks); GenerateSendAndXORCorRobVector(Q, OTsPerIteration, mat_chan); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalUnMaskTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif Q.Transpose(wd_size_bits, OTsPerIteration); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalTnsTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif HashValues(Q, seedbuf, vSnd, OT_ptr, min(lim - OT_ptr, OTsPerIteration), rndmat); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalHshTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif //TODO: outsource into method tmpmaskbuf.otid = OT_ptr; tmpmaskbuf.otlen = min(lim - OT_ptr, OTsPerIteration); tmpmaskbuf.maskbuf = new CBitVector[numsndvals]; for(uint32_t i = 0; i < numsndvals; i++) tmpmaskbuf.maskbuf[i].Copy(vSnd[i]); mask_queue.push(tmpmaskbuf); if(check_chan->data_available()) { assert(CheckConsistency(&check_queue, check_chan));//TODO assert tmpmaskbuf = mask_queue.front(); mask_queue.pop(); MaskAndSend(tmpmaskbuf.maskbuf, tmpmaskbuf.otid, tmpmaskbuf.otlen, ot_chan); } #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalSndTime += getMillies(tempStart, tempEnd); #endif OT_ptr += min(lim - OT_ptr, OTsPerIteration); Q.Reset(); //free(rcvbufptr); } while(!check_queue.empty()) { if(check_chan->data_available()) { assert(CheckConsistency(&check_queue, check_chan));//TODO assert tmpmaskbuf = mask_queue.front(); mask_queue.pop(); MaskAndSend(tmpmaskbuf.maskbuf, tmpmaskbuf.otid, tmpmaskbuf.otlen, ot_chan); } } //vRcv.delCBitVector(); ot_chan->synchronize_end(); check_chan->synchronize_end(); Q.delCBitVector(); for (uint32_t u = 0; u < m_nSndVals; u++) seedbuf[u].delCBitVector(); for (uint32_t i = 0; i < numsndvals; i++) vSnd[i].delCBitVector(); if (numsndvals > 0) free(vSnd); if(use_mat_chan) { mat_chan->synchronize_end(); } if(m_eSndOTFlav == Snd_GC_OT) { freeRndMatrix(rndmat, m_nBaseOTs); } #ifdef OTTiming cout << "Sender time benchmark for performing " << myNumOTs << " OTs on " << m_nBitLength << " bit strings" << endl; cout << "Time needed for: " << endl; cout << "\t Matrix Generation:\t" << totalMtxTime << " ms" << endl; cout << "\t BaseOT Unmasking:\t" << totalUnMaskTime << " ms" << endl; cout << "\t Check Hashing:\t" << totalHashCheckTime << " ms" << endl; cout << "\t Sending Matrix:\t" << totalSndTime << " ms" << endl; cout << "\t Transposing Matrix:\t" << totalTnsTime << " ms" << endl; cout << "\t Hashing Matrix:\t" << totalHshTime << " ms" << endl; cout << "\t Receiving Values:\t" << totalRcvTime << " ms" << endl; #endif delete ot_chan; delete check_chan; return TRUE; }
nnob_snd_check_t NNOBOTExtSnd::UpdateCheckBuf(uint8_t* tocheckseed, uint8_t* tocheckrcv, uint64_t otid, uint64_t numblocks, channel* check_chan) { uint64_t rowbytelen = m_nBlockSizeBytes * numblocks; uint64_t checkbytelen = min(rowbytelen, bits_in_bytes(m_nOTs - otid)); uint8_t* hash_buf = (uint8_t*) malloc(SHA512_DIGEST_LENGTH); uint8_t* tmpbuf = (uint8_t*) malloc(rowbytelen); uint8_t *idaptr, *idbptr; nnob_snd_check_t check_buf; //check_buf.rcv_chk_buf = (uint8_t*) malloc(m_nChecks * OWF_BYTES); check_buf.chk_buf = (uint8_t*) malloc(m_nChecks * OWF_BYTES); uint8_t *chk_buf_ptr = check_buf.chk_buf; uint8_t *idatmpbuf = (BYTE*) malloc(sizeof(BYTE) * rowbytelen); uint8_t *idbtmpbuf = (BYTE*) malloc(sizeof(BYTE) * rowbytelen); uint8_t *seedptr, *rcvptr; //uint32_t blockoffset = ceil_divide(otid, NUMOTBLOCKS * m_nBlockSizeBits); uint32_t blockid = 0; //TODO bring in as soon as 3-step OT is implemented check_buf.otid = otid; check_buf.numblocks = numblocks; check_buf.perm = (linking_t*) malloc(sizeof(linking_t*) * m_nChecks); check_buf.permchoicebits = (BYTE*) malloc(sizeof(uint8_t) * m_nChecks); genRandomMapping(check_buf.perm, m_nBaseOTs); for(uint32_t i = 0; i < m_nChecks; i++) { check_buf.permchoicebits[i] = m_vU.GetBit(blockid * m_nBaseOTs + check_buf.perm[i].ida) ^ m_vU.GetBit(blockid * m_nBaseOTs + check_buf.perm[i].idb); } //right now the checkbytelen needs to be a multiple of AES_BYTES assert(ceil_divide(rowbytelen, OWF_BYTES) * OWF_BYTES == rowbytelen); #ifdef DEBUG_NNOB_CHECKS m_vU.PrintHex(); #endif for(uint64_t i = 0; i < m_nChecks; i++, chk_buf_ptr+=OWF_BYTES) { if(m_vU.GetBit(blockid * m_nBaseOTs + check_buf.perm[i].ida) == 0) { memcpy(idatmpbuf, tocheckseed + check_buf.perm[i].ida * rowbytelen, rowbytelen); } else { seedptr = tocheckseed + check_buf.perm[i].ida * rowbytelen; rcvptr = tocheckrcv + check_buf.perm[i].ida * rowbytelen; for(int j = 0; j < rowbytelen/sizeof(uint64_t); j++) { ((uint64_t*) idatmpbuf)[j] = ((uint64_t*) seedptr)[j] ^ ((uint64_t*) rcvptr)[j]; } } if(m_vU.GetBit(blockid * m_nBaseOTs + check_buf.perm[i].idb) == 0) { memcpy(idbtmpbuf, tocheckseed + check_buf.perm[i].idb * rowbytelen, rowbytelen); } else { seedptr = tocheckseed + check_buf.perm[i].idb * rowbytelen; rcvptr = tocheckrcv + check_buf.perm[i].idb * rowbytelen; for(int j = 0; j < rowbytelen/sizeof(uint64_t); j++) { ((uint64_t*) idbtmpbuf)[j] = ((uint64_t*) seedptr)[j] ^ ((uint64_t*) rcvptr)[j]; } } /*#ifdef DEBUG_NNOB_CHECKS cout << "seedA: " << (hex) << ((uint64_t*) (tocheckseed + check_buf.perm[i].ida * rowbytelen))[0] << ", rcvA: " << ((uint64_t*) (tocheckrcv + check_buf.perm[i].ida * rowbytelen))[0] << (dec) << endl; cout << "seedB: " << (hex) << ((uint64_t*) (tocheckseed + check_buf.perm[i].idb * rowbytelen))[0] << ", rcvB: " << ((uint64_t*) (tocheckrcv + check_buf.perm[i].idb * rowbytelen))[0] << (dec) << endl; cout << "input to owf " << (hex) << ((uint64_t*) idatmpbuf)[0] << ", " << ((uint64_t*) idbtmpbuf)[0] << (dec) << endl; #endif*/ memset(tmpbuf, 0, rowbytelen); for(uint64_t j = 0; j < rowbytelen/sizeof(uint64_t); j++) { ((uint64_t*) tmpbuf)[j] = ((uint64_t*) tmpbuf)[j] ^ ((uint64_t*) idatmpbuf)[j] ^ ((uint64_t*) idbtmpbuf)[j]; } #ifdef DEBUG_NNOB_CHECKS_INPUT cout << "XOR-OWF Input:\t" << (hex); for(uint32_t t = 0; t < checkbytelen; t++) { cout << setw(2) << setfill('0') << (uint32_t) tmpbuf[t]; } cout << (dec) << endl; #endif #ifdef AES_OWF owf(&aesowfkey, rowbytelen, tmpbuf, resbuf); #else //m_cCrypt->hash_buf(chk_buf_ptr, OWF_BYTES, tmpbuf, checkbytelen, hash_buf);//hash_buf, rowbytelen, tmpbuf, resbuf, hash_buf); sha512_hash(chk_buf_ptr, OWF_BYTES, tmpbuf, checkbytelen, hash_buf); #endif #ifdef DEBUG_NNOB_CHECKS_OUTPUT cout << "XOR-OWF Output:\t" << (hex); for(uint32_t t = 0; t < OWF_BYTES; t++) { cout << (uint32_t) chk_buf_ptr[t]; } cout << (dec) << endl; #endif //XORandOWF(idatmpbuf, idbtmpbuf, checkbytelen, tmpbuf, chk_buf_ptr, hash_buf); } /* for(uint64_t i = 0; i < m_nChecks; i++, seedcheckbufptr+=OWF_BYTES, rcvcheckbufptr+=OWF_BYTES) { memset(tmpbuf, 0, rowbytelen); #ifdef DEBUG_ALSZ_CHECKS cout << i << "-th check between " << check_buf.perm[i].ida << " and " << check_buf.perm[i].idb << ": " << endl; #endif XORandOWF(tocheckseed + check_buf.perm[i].ida * rowbytelen, tocheckseed + check_buf.perm[i].idb * rowbytelen, rowbytelen, tmpbuf, seedcheckbufptr, hash_buf); XORandOWF(tocheckrcv + check_buf.perm[i].ida * rowbytelen, tocheckrcv + check_buf.perm[i].idb * rowbytelen, rowbytelen, tmpbuf, rcvcheckbufptr, hash_buf); }*/ free(tmpbuf); free(hash_buf); free(idatmpbuf); free(idbtmpbuf); //Send the permutation and the XORed bits over to the receiver check_chan->send_id_len((uint8_t*) check_buf.perm, sizeof(linking_t) * m_nChecks, otid, numblocks); check_chan->send(check_buf.permchoicebits, m_nChecks); return check_buf; }
void KKOTExtSnd::KKHashValues(CBitVector &Q, CBitVector *seedbuf, CBitVector *snd_buf, uint64_t OT_ptr, uint64_t OT_len, uint64_t **mat_mul) { uint64_t numhashiters = ceil_divide(m_nBitLength, m_cCrypt->get_hash_bytes()); uint32_t rowbytelen = bits_in_bytes(m_nBaseOTs); uint32_t hashinbytelen = rowbytelen + sizeof(uint64_t); uint32_t hashoutbitlen = ceil_log2(m_nSndVals); uint64_t wd_size_bytes = m_nBlockSizeBytes; // 1 << (ceil_log2(m_nBaseOTs) - 3); uint32_t u; uint32_t aes_key_bytes = m_cCrypt->get_aes_key_bytes(); uint32_t choicebitlen = ceil_log2(m_nSndVals); uint64_t *Qptr = (uint64_t *)Q.GetArr(); uint8_t **sbp = (uint8_t **)malloc(sizeof(uint8_t *) * m_nSndVals); uint8_t *inbuf = (uint8_t *)calloc(hashinbytelen, 1); uint8_t *resbuf = (uint8_t *)calloc(m_cCrypt->get_hash_bytes(), 1); uint8_t *hash_buf = (uint8_t *)calloc(m_cCrypt->get_hash_bytes(), 1); uint64_t *tmpbuf = (uint64_t *)calloc( PadToMultiple(bits_in_bytes(m_nBitLength), sizeof(uint64_t)), 1); uint8_t *tmpbufb = (uint8_t *)calloc(bits_in_bytes(m_nBitLength), 1); uint64_t global_OT_ptr = OT_ptr + m_nCounter; CBitVector mask(m_nCodeWordBits); for (u = 0; u < m_nSndVals; u++) { sbp[u] = seedbuf[u].GetArr(); } for (uint64_t i = 0; i < OT_len; global_OT_ptr++, i++, Qptr += 2) { for (u = 0; u < m_nSndVals; u++) { mask.Copy(m_vU, 0, rowbytelen); mask.ANDBytes((uint8_t *)m_vCodeWords[u], 0, rowbytelen); mask.XORBytes(Q.GetArr() + i * rowbytelen, rowbytelen); #ifdef DEBUG_OT_HASH_IN cout << "Hash-In for i = " << global_OT_ptr << ", u = " << u << ": " << (hex); for (uint32_t p = 0; p < rowbytelen; p++) cout << setw(2) << setfill('0') << (uint32_t)mask.GetArr()[p]; cout << (dec) << endl; // cout << "Using codeword " << (hex) << m_vCodeWords[u][0] << // m_vCodeWords[u][1] << (hex) << m_vCodeWords[u][2] << m_vCodeWords[u][3] << // (dec) << endl; #endif if (m_eSndOTFlav != Snd_GC_OT) { #ifdef FIXED_KEY_AES_HASHING FixedKeyHashing(m_kCRFKey, sbp[u], (BYTE *)Qptr, hash_buf, i, hashinbytelen, m_cCrypt); #else memcpy(inbuf, &global_OT_ptr, sizeof(uint64_t)); // memcpy(inbuf+sizeof(uint64_t), Q.GetArr() + i * // wd_size_bytes, rowbytelen); memcpy(inbuf + sizeof(uint64_t), mask.GetArr(), rowbytelen); m_cCrypt->hash_buf(resbuf, aes_key_bytes, inbuf, hashinbytelen, hash_buf); memcpy(sbp[u], resbuf, aes_key_bytes); // snd_buf[u].SetBits(resbuf, i * hashoutbitlen, hashoutbitlen); } else { // TODO: mecr has not been tested with KK-OT!! BitMatrixMultiplication(tmpbufb, bits_in_bytes(hashoutbitlen), mask.GetArr(), m_nBaseOTs, mat_mul, tmpbuf); // BitMatrixMultiplication(tmpbufb, bits_in_bytes(m_nBitLength), // Q.GetArr() + i * wd_size_bytes, m_nBaseOTs, mat_mul, tmpbuf); // m_vValues[u].SetBits(tmpbufb, (OT_ptr + i)* m_nBitLength, // m_nBitLength); snd_buf[u].SetBits(tmpbufb, i * hashoutbitlen, hashoutbitlen); // m_vTempOTMasks.SetBytes(tmpbufb, (uint64_t) (OT_ptr + i) * // aes_key_bytes, (uint64_t) aes_key_bytes); // m_vValues[u].SetBytes(Q.GetArr() + i * wd_size_bytes, (OT_ptr // + i)* wd_size_bytes, rowbytelen); } #endif #ifdef DEBUG_OT_HASH_OUT cout << "Hash-Out for i = " << global_OT_ptr << ", u = " << u << ": " << (hex); for (uint32_t p = 0; p < aes_key_bytes; p++) cout << setw(2) << setfill('0') << (uint32_t)sbp[u][p]; cout << (dec) << endl; #endif sbp[u] += m_cCrypt->get_aes_key_bytes(); } } // TODO: difference is in here!! (could be solved by giving the // bit-length as parameter in the function call) for (uint32_t u = 0; u < m_nSndVals; u++) { m_fMaskFct->expandMask(&snd_buf[u], seedbuf[u].GetArr(), 0, OT_len, m_nBitLength * choicebitlen, m_cCrypt); // cout << "Mask " << u << ": "; // snd_buf[u].PrintHex(); } // m_vValues[0].PrintHex(); // m_vValues[1].PrintHex(); free(resbuf); free(inbuf); free(sbp); free(hash_buf); free(tmpbuf); free(tmpbufb); }
BOOL KKOTExtSnd::sender_routine(uint32_t id, uint64_t myNumOTs) { uint32_t choicecodebitlen = ceil_log2(m_nSndVals); uint64_t myStartPos = id * myNumOTs; uint64_t myStartPos1ooN = ceil_divide(myStartPos, choicecodebitlen); uint64_t wd_size_bits = m_nBlockSizeBits; uint64_t processedOTBlocks = min((uint64_t)NUMOTBLOCKS, ceil_divide(myNumOTs, wd_size_bits)); uint64_t OTsPerIteration = processedOTBlocks * wd_size_bits; channel *chan = new channel(id, m_cRcvThread, m_cSndThread); uint64_t tmpctr, tmpotlen; uint64_t **rndmat; uint64_t processedOTs; myNumOTs = min(myNumOTs + myStartPos, m_nOTs) - myStartPos; // TODO some re-formating of myNumOTs due to 1ooN OT uint64_t lim = myStartPos1ooN + ceil_divide(myNumOTs, choicecodebitlen); if (myStartPos1ooN * choicecodebitlen > m_nOTs) { cerr << "Thread " << id << " not doing any work to align to window size " << endl; return true; } // The vector with the received bits #ifdef GENERATE_T_EXPLICITELY CBitVector vRcv(2 * m_nBaseOTs * OTsPerIteration); #else CBitVector vRcv(m_nBaseOTs * OTsPerIteration); #endif // Holds the reply that is sent back to the receiver CBitVector *vSnd; CBitVector *seedbuf = new CBitVector[m_nSndVals]; for (uint32_t u = 0; u < m_nSndVals; u++) { seedbuf[u].Create(OTsPerIteration * m_cCrypt->get_aes_key_bytes() * 8); } #ifdef ZDEBUG cout << "seedbuf size = " << OTsPerIteration *AES_KEY_BITS << endl; #endif vSnd = new CBitVector[m_nSndVals]; for (uint32_t i = 0; i < m_nSndVals; i++) { vSnd[i].Create(OTsPerIteration * choicecodebitlen * m_nBitLength); } // Contains the parts of the V matrix CBitVector Q(wd_size_bits * OTsPerIteration); uint64_t otid = myStartPos1ooN; uint8_t *rcvbuftmpptr, *rcvbufptr; #ifdef OTTiming double totalMtxTime = 0, totalTnsTime = 0, totalHshTime = 0, totalRcvTime = 0, totalSndTime = 0, totalUnMaskTime = 0; timeval tempStart, tempEnd; #endif if (m_eSndOTFlav == Snd_GC_OT) { uint8_t *rnd_seed = (uint8_t *)malloc(m_nSymSecParam); m_cCrypt->gen_rnd(rnd_seed, m_nSymSecParam); chan->send(rnd_seed, m_nSymSecParam); initRndMatrix(&rndmat, m_nBitLength, m_nBaseOTs); fillRndMatrix(rnd_seed, rndmat, m_nBitLength, m_nBaseOTs, m_cCrypt); free(rnd_seed); } while (otid < lim) // do while there are still transfers missing { processedOTBlocks = min((uint64_t)NUMOTBLOCKS, ceil_divide(lim - otid, wd_size_bits)); OTsPerIteration = processedOTBlocks * wd_size_bits; processedOTs = min(lim - otid, OTsPerIteration); #ifdef ZDEBUG cout << "Processing block " << nProgress << " with length: " << OTsPerIteration << ", and limit: " << lim << endl; #endif #ifdef OTTiming gettimeofday(&tempStart, NULL); #endif ReceiveMasks(vRcv, chan, OTsPerIteration); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalRcvTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif BuildQMatrix(Q, otid, processedOTBlocks); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalMtxTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif UnMaskBaseOTs(Q, vRcv, processedOTBlocks); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalUnMaskTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif Q.Transpose(wd_size_bits, OTsPerIteration); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalTnsTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif KKHashValues(Q, seedbuf, vSnd, otid, processedOTs, rndmat); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalHshTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif KKMaskAndSend(vSnd, otid, processedOTs, chan); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalSndTime += getMillies(tempStart, tempEnd); #endif otid += processedOTs; Q.Reset(); } vRcv.delCBitVector(); chan->synchronize_end(); Q.delCBitVector(); for (uint32_t i = 0; i < m_nSndVals; i++) { vSnd[i].delCBitVector(); } delete vSnd; if (m_eSndOTFlav == Snd_GC_OT) { freeRndMatrix(rndmat, m_nBaseOTs); } #ifdef OTTiming cout << "Sender time benchmark for performing " << myNumOTs << " OTs (" << lim - myStartPos1ooN << " 1ooN) on " << m_nBitLength << " bit strings" << endl; cout << "Time needed for: " << endl; cout << "\t Matrix Generation:\t" << totalMtxTime << " ms" << endl; cout << "\t Unmasking values:\t" << totalUnMaskTime << " ms" << endl; cout << "\t Sending Matrix:\t" << totalSndTime << " ms" << endl; cout << "\t Transposing Matrix:\t" << totalTnsTime << " ms" << endl; cout << "\t Hashing Matrix:\t" << totalHshTime << " ms" << endl; cout << "\t Receiving Values:\t" << totalRcvTime << " ms" << endl; #endif delete chan; return TRUE; }
//export and pad all leading zeros void gmp_num::export_to_bytes(uint8_t* buf, uint32_t field_size) { mpz_export_padded(buf, ceil_divide(field_size, 8), val); }
BOOL NNOBOTExtRec::receiver_routine(uint32_t id, uint64_t myNumOTs) { uint64_t myStartPos = id * myNumOTs; uint64_t wd_size_bits = m_nBlockSizeBits; myNumOTs = min(myNumOTs + myStartPos, m_nOTs) - myStartPos; uint64_t lim = myStartPos + myNumOTs; uint64_t processedOTBlocks = min((uint64_t) NUMOTBLOCKS, ceil_divide(myNumOTs, wd_size_bits)); uint64_t OTsPerIteration = processedOTBlocks * wd_size_bits; uint64_t OTwindow = NUMOTBLOCKS * wd_size_bits; uint64_t** rndmat; bool use_mat_chan = (m_eSndOTFlav == Snd_GC_OT || m_bUseMinEntCorRob); uint32_t nchans = 2; if(use_mat_chan) { nchans = 3; } channel* ot_chan = new channel(nchans*id, m_cRcvThread, m_cSndThread); channel* check_chan = new channel(nchans*id+1, m_cRcvThread, m_cSndThread); channel* mat_chan; if(use_mat_chan) { mat_chan = new channel(nchans*id+2, m_cRcvThread, m_cSndThread); } //counter variables uint64_t numblocks = ceil_divide(myNumOTs, OTsPerIteration); // A temporary part of the T matrix CBitVector T(wd_size_bits * OTsPerIteration); // The send buffer CBitVector vSnd(m_nBaseOTs * OTsPerIteration); // A temporary buffer that stores the resulting seeds from the hash buffer //TODO: Check for some maximum size CBitVector seedbuf(OTwindow * m_cCrypt->get_aes_key_bytes() * 8); uint64_t otid = myStartPos; queue<nnob_rcv_check_t> check_buf; queue<mask_block*> mask_queue; CBitVector maskbuf; maskbuf.Create(m_nBitLength * OTwindow); //TODO only do when successfull checks if(m_eSndOTFlav == Snd_GC_OT) { initRndMatrix(&rndmat, m_nBitLength, m_nBaseOTs); } #ifdef OTTiming double totalMtxTime = 0, totalTnsTime = 0, totalHshTime = 0, totalRcvTime = 0, totalSndTime = 0, totalChkTime = 0, totalMaskTime = 0, totalEnqueueTime = 0; timeval tempStart, tempEnd; #endif while (otid < lim) { processedOTBlocks = min((uint64_t) NUMOTBLOCKS, ceil_divide(lim - otid, wd_size_bits)); OTsPerIteration = processedOTBlocks * wd_size_bits; //nSize = bits_in_bytes(m_nBaseOTs * OTsPerIteration); #ifdef OTTiming gettimeofday(&tempStart, NULL); #endif BuildMatrices(T, vSnd, otid, processedOTBlocks); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalMtxTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif check_buf.push(EnqueueSeed(T.GetArr(), otid, processedOTBlocks)); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalEnqueueTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif MaskBaseOTs(T, vSnd, otid, processedOTBlocks); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalMaskTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif SendMasks(vSnd, ot_chan, otid, OTsPerIteration); //ot_chan->send_id_len(vSnd.GetArr(), nSize, otid, OTsPerIteration); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalSndTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif ReceiveAndFillMatrix(rndmat, mat_chan); ReceiveAndXORCorRobVector(T, OTsPerIteration, mat_chan); T.Transpose(wd_size_bits, OTsPerIteration); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalTnsTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif HashValues(&T, &seedbuf, &maskbuf, otid, min(lim - otid, OTsPerIteration), rndmat); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalHshTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif if(check_chan->data_available()) { ComputeOWF(&check_buf, check_chan); } //if(ot_chan->data_available()) { // ReceiveAndUnMask(ot_chan); //} SetOutput(&maskbuf, otid, OTsPerIteration, &mask_queue, ot_chan); otid += min(lim - otid, OTsPerIteration); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalRcvTime += getMillies(tempStart, tempEnd); #endif vSnd.Reset(); T.Reset(); } while(!check_buf.empty()) { if(check_chan->data_available()) { ComputeOWF(&check_buf, check_chan); } } if(m_eSndOTFlav != Snd_R_OT) { //finevent->Wait(); while(ot_chan->is_alive() && !(mask_queue.empty())) ReceiveAndUnMask(ot_chan, &mask_queue); } ot_chan->synchronize_end(); check_chan->synchronize_end(); T.delCBitVector(); vSnd.delCBitVector(); seedbuf.delCBitVector(); maskbuf.delCBitVector(); if(use_mat_chan) { mat_chan->synchronize_end(); } if(m_eSndOTFlav==Snd_GC_OT) { freeRndMatrix(rndmat, m_nBaseOTs); } #ifdef OTTiming cout << "Receiver time benchmark for performing " << myNumOTs << " OTs on " << m_nBitLength << " bit strings" << endl; cout << "Time needed for: " << endl; cout << "\t Matrix Generation:\t" << totalMtxTime << " ms" << endl; cout << "\t Enqueuing Seeds:\t" << totalEnqueueTime << " ms" << endl; cout << "\t Base OT Masking:\t" << totalMaskTime << " ms" << endl; cout << "\t Sending Matrix:\t" << totalSndTime << " ms" << endl; cout << "\t Transposing Matrix:\t" << totalTnsTime << " ms" << endl; cout << "\t Hashing Matrix:\t" << totalHshTime << " ms" << endl; cout << "\t Receiving Values:\t" << totalRcvTime << " ms" << endl; #endif return TRUE; }
void OTExtSnd::HashValues(CBitVector& Q, CBitVector* seedbuf, CBitVector* snd_buf, uint64_t OT_ptr, uint64_t OT_len, uint64_t** mat_mul) { uint64_t numhashiters = ceil_divide(m_nBitLength, m_cCrypt->get_hash_bytes()); uint32_t rowbytelen = bits_in_bytes(m_nBaseOTs); uint32_t hashinbytelen = rowbytelen + sizeof(uint64_t); uint64_t wd_size_bytes = m_nBlockSizeBytes;//1 << (ceil_log2(m_nBaseOTs) - 3); uint32_t u; uint32_t aes_key_bytes = m_cCrypt->get_aes_key_bytes(); uint64_t* Qptr = (uint64_t*) Q.GetArr(); uint64_t* Uptr = (uint64_t*) m_vU.GetArr(); uint8_t** sbp = (uint8_t**) malloc(sizeof(uint8_t*) * m_nSndVals); uint8_t* inbuf = (uint8_t*) calloc(hashinbytelen, 1); uint8_t* resbuf = (uint8_t*) calloc(m_cCrypt->get_hash_bytes(), 1); uint8_t* hash_buf = (uint8_t*) calloc(m_cCrypt->get_hash_bytes(), 1); uint64_t* tmpbuf = (uint64_t*) calloc(PadToMultiple(bits_in_bytes(m_nBitLength), sizeof(uint64_t)), 1); uint8_t* tmpbufb = (uint8_t*) calloc(bits_in_bytes(m_nBitLength), 1); uint64_t global_OT_ptr = OT_ptr + m_nCounter; for (u = 0; u < m_nSndVals; u++) sbp[u] = seedbuf[u].GetArr(); for (uint64_t i = 0; i < OT_len; global_OT_ptr++, i++, Qptr += 2) { for (u = 0; u < m_nSndVals; u++) { #ifdef HIGH_SPEED_ROT_LT if(u == 1) { Qptr[0]^=Uptr[0]; Qptr[1]^=Uptr[1]; } #else if (u == 1) Q.XORBytes((uint8_t*) Uptr, i * wd_size_bytes, rowbytelen); #endif #ifdef DEBUG_OT_HASH_IN cout << "Hash-In for i = " << global_OT_ptr << ", u = " << u << ": " << (hex); for(uint32_t p = 0; p < rowbytelen; p++) cout << setw(2) << setfill('0') << (uint32_t) (Q.GetArr() + i * wd_size_bytes)[p]; cout << (dec) << endl; #endif if(m_eSndOTFlav != Snd_GC_OT) { #ifdef FIXED_KEY_AES_HASHING FixedKeyHashing(m_kCRFKey, sbp[u], (BYTE*) Qptr, hash_buf, i, hashinbytelen, m_cCrypt); #else memcpy(inbuf, &global_OT_ptr, sizeof(uint64_t)); memcpy(inbuf+sizeof(uint64_t), Q.GetArr() + i * wd_size_bytes, rowbytelen); m_cCrypt->hash_buf(resbuf, aes_key_bytes, inbuf, hashinbytelen, hash_buf); memcpy(sbp[u], resbuf, aes_key_bytes); } else { BitMatrixMultiplication(tmpbufb, bits_in_bytes(m_nBitLength), Q.GetArr() + i * wd_size_bytes, m_nBaseOTs, mat_mul, tmpbuf); //m_vValues[u].SetBits(tmpbufb, (OT_ptr + i)* m_nBitLength, m_nBitLength); snd_buf[u].SetBits(tmpbufb, i * m_nBitLength, m_nBitLength); //m_vTempOTMasks.SetBytes(tmpbufb, (uint64_t) (OT_ptr + i) * aes_key_bytes, (uint64_t) aes_key_bytes); //m_vValues[u].SetBytes(Q.GetArr() + i * wd_size_bytes, (OT_ptr + i)* wd_size_bytes, rowbytelen); } #endif #ifdef DEBUG_OT_HASH_OUT cout << "Hash-Out for i = " << global_OT_ptr << ", u = " << u << ": " << (hex); for(uint32_t p = 0; p < aes_key_bytes; p++) cout << setw(2) << setfill('0') << (uint32_t) sbp[u][p]; cout << (dec) << endl; #endif sbp[u] += aes_key_bytes; } } //m_vValues[0].PrintHex(); //m_vValues[1].PrintHex(); #ifndef HIGH_SPEED_ROT_LT if(m_eSndOTFlav != Snd_GC_OT) { //Two calls to expandMask, both writing into snd_buf for (uint32_t u = 0; u < m_nSndVals; u++) m_fMaskFct->expandMask(snd_buf[u], seedbuf[u].GetArr(), 0, OT_len, m_nBitLength, m_cCrypt); } #endif free(resbuf); free(inbuf); free(sbp); free(hash_buf); free(tmpbuf); free(tmpbufb); }
uint32_t #endif cuckoo_hashing(uint8_t* elements, uint32_t neles, uint32_t nbins, uint32_t bitlen, uint32_t *outbitlen, uint32_t* nelesinbin, uint32_t* perm, uint32_t ntasks, prf_state_ctx* prf_state) { //The resulting hash table uint8_t* hash_table; #ifdef DOUBLE_TABLE cuckoo_entry_ctx*** cuckoo_table; #else cuckoo_entry_ctx** cuckoo_table; #endif cuckoo_entry_ctx* cuckoo_entries; uint32_t i, j; uint32_t *perm_ptr; pthread_t* entry_gen_tasks; cuckoo_entry_gen_ctx* ctx; hs_t hs; #ifdef COUNT_FAILS uint32_t fails = 0; #endif init_hashing_state(&hs, neles, bitlen, nbins, prf_state); *outbitlen = hs.outbitlen; #ifdef DOUBLE_TABLE cuckoo_table = (cuckoo_entry_ctx***) calloc(2, sizeof(cuckoo_entry_ctx**)); cuckoo_table[0] = (cuckoo_entry_ctx**) calloc(nbins, sizeof(cuckoo_entry_ctx*)); cuckoo_table[1] = (cuckoo_entry_ctx**) calloc(nbins, sizeof(cuckoo_entry_ctx*)); #else cuckoo_table = (cuckoo_entry_ctx**) calloc(nbins, sizeof(cuckoo_entry_ctx*)); #endif cuckoo_entries = (cuckoo_entry_ctx*) malloc(neles * sizeof(cuckoo_entry_ctx)); entry_gen_tasks = (pthread_t*) malloc(sizeof(pthread_t) * ntasks); ctx = (cuckoo_entry_gen_ctx*) malloc(sizeof(cuckoo_entry_gen_ctx) * ntasks); #ifndef TEST_UTILIZATION for(i = 0; i < ntasks; i++) { ctx[i].elements = elements; ctx[i].cuckoo_entries = cuckoo_entries; ctx[i].hs = &hs; ctx[i].startpos = i * ceil_divide(neles, ntasks); ctx[i].endpos = min(ctx[i].startpos + ceil_divide(neles, ntasks), neles); //cout << "Thread " << i << " starting from " << ctx[i].startpos << " going to " << ctx[i].endpos << " for " << neles << " elements" << endl; if(pthread_create(entry_gen_tasks+i, NULL, gen_cuckoo_entries, (void*) (ctx+i))) { cerr << "Error in creating new pthread at cuckoo hashing!" << endl; exit(0); } } for(i = 0; i < ntasks; i++) { if(pthread_join(entry_gen_tasks[i], NULL)) { cerr << "Error in joining pthread at cuckoo hashing!" << endl; exit(0); } } #else ctx[0].elements = elements; ctx[0].cuckoo_entries = cuckoo_entries; ctx[0].hs = &hs; ctx[0].startpos = 0; ctx[0].endpos = neles; gen_cuckoo_entries(ctx); #endif //for(i = 0; i < nbins; i++) { // cout << "Address " << i << " mapped to " << hs.address_used[i] << " times" << endl; //} //insert all elements into the cuckoo hash table for(i = 0; i < neles; i++) { if(!(insert_element(cuckoo_table, cuckoo_entries + i, neles))) { #ifdef COUNT_FAILS fails++; /*cout << "insertion failed for element " << (hex) << (*(((uint32_t*) elements)+i)) << ", inserting to address: "; for(uint32_t j = 0; j < NUM_HASH_FUNCTIONS; j++) { cout << (cuckoo_entries + i)->address[j] << ", "; } cout << (dec) << endl;*/ #else cerr << "Insertion not successful for element " <<i <<"!" << endl; //exit(0); #endif } } //Copy the final state of the cuckoo table into the hash table perm_ptr = perm; #ifndef TEST_UTILIZATION hash_table = (uint8_t*) calloc(nbins, hs.outbytelen); for(i = 0; i < nbins; i++) { if(cuckoo_table[i] != NULL) { memcpy(hash_table + i * hs.outbytelen, cuckoo_table[i]->val, hs.outbytelen); //cout << "copying value: " << (hex) << (unsigned int) cuckoo_table[i]->val[cuckoo_table[i]->pos][0] << (dec) << endl; *perm_ptr = cuckoo_table[i]->eleid; perm_ptr++; nelesinbin[i] = 1; } else { memset(hash_table + i * hs.outbytelen, DUMMY_ENTRY_CLIENT, hs.outbytelen); nelesinbin[i] = 0; } } #endif #ifndef TEST_UTILIZATION //Cleanup for(i = 0; i < neles; i++) { free(cuckoo_entries[i].val); } #endif free(cuckoo_entries); #ifdef DOUBLE_TABLE free(cuckoo_table[0]); free(cuckoo_table[1]); #else free(cuckoo_table); #endif free(entry_gen_tasks); free(ctx); free_hashing_state(&hs); #ifdef TEST_UTILIZATION return fails; #else return hash_table; #endif }
void NNOBOTExtRec::ComputeOWF(std::queue<nnob_rcv_check_t>* check_buf_q, channel* check_chan) {//linking_t* permbits, int nchecks, int otid, int processedOTs, BYTE* outhashes) { //Obtain T0 and T1 from the SeedPointers uint32_t receiver_hashes = 1; uint64_t tmpid, tmpnblocks; linking_t* perm; uint8_t* rcv_buf_perm = check_chan->blocking_receive_id_len((uint8_t**) &perm, &tmpid, &tmpnblocks); uint8_t* rcv_buf_permchoices = check_chan->blocking_receive(); uint8_t* sender_permchoicebitptr = rcv_buf_permchoices; nnob_rcv_check_t check_buf = check_buf_q->front(); check_buf_q->pop(); assert(tmpid == check_buf.otid); assert(tmpnblocks == check_buf.numblocks); //the bufsize has to be padded to a multiple of the PRF-size since we will omit boundary checks there uint32_t i, j; uint64_t bufrowbytelen = m_nBlockSizeBytes * check_buf.numblocks;//seedptr->expstrbitlen>>3;//(CEIL_DIVIDE(processedOTs, wd_size_bits) * wd_size_bits) >>3; uint64_t checkbytelen = std::min(bufrowbytelen, bits_in_bytes(m_nOTs - check_buf.otid)); //contains the T-matrix uint8_t* T0 = check_buf.T0; //contains the T-matrix XOR the receive bits //uint8_t* T1 = check_buf.T1; uint32_t outhashbytelen = m_nChecks * OWF_BYTES * receiver_hashes; uint8_t* outhashes = (uint8_t*) malloc(outhashbytelen); #ifdef AES_OWF AES_KEY_CTX aesowfkey; MPC_AES_KEY_INIT(&aesowfkey); #else uint8_t* hash_buf = (uint8_t*) malloc(SHA512_DIGEST_LENGTH); #endif uint8_t* tmpbuf = (uint8_t*) malloc(bufrowbytelen); uint8_t **ka = (uint8_t**) malloc(2 * sizeof(uint8_t*)); uint8_t **kb = (uint8_t**) malloc(2 * sizeof(uint8_t*)); uint8_t *kaptr, *kbptr; uint8_t* outptr = outhashes; uint8_t* receiver_choicebits = m_vChoices->GetArr() + ceil_divide(check_buf.otid, 8); CBitVector tmp; tmp.AttachBuf(tmpbuf, bufrowbytelen*8); //Compute all hashes for the permutations given Ta, Tb and the choice bits for(i = 0; i < m_nChecks; i++, sender_permchoicebitptr++) { ka[0] = T0 + perm[i].ida * bufrowbytelen; kb[0] = T0 + perm[i].idb * bufrowbytelen; #ifdef DEBUG_MALICIOUS std::cout << (std::dec) << i << "-th check: between " << perm[i].ida << ", and " << perm[i].idb << std::endl; #endif for(j = 0; j < receiver_hashes; j++, outptr+=OWF_BYTES) { kaptr = ka[0]; kbptr = kb[0]; assert((*sender_permchoicebitptr) == 0 || (*sender_permchoicebitptr == 1)); tmp.SetXOR(kaptr, kbptr, 0, bufrowbytelen); if(*sender_permchoicebitptr == 1) { tmp.XORBytesReverse(receiver_choicebits, 0, checkbytelen); } #ifdef DEBUG_NNOB_CHECKS_INPUT std::cout << "XOR-OWF Input:\t" << (std::hex); for(uint32_t t = 0; t < checkbytelen; t++) { std::cout << std::setw(2) << std::setfill('0') << (uint32_t) tmpbuf[t]; } std::cout << (std::dec) << std::endl; #endif #ifdef AES_OWF owf(&aesowfkey, rowbytelen, tmpbuf, outhashes); #else //m_cCrypt->hash_buf(outptr, OWF_BYTES, tmpbuf, checkbytelen, hash_buf); sha512_hash(outptr, OWF_BYTES, tmpbuf, checkbytelen, hash_buf); #endif #ifdef DEBUG_NNOB_CHECKS_OUTPUT std::cout << "XOR-OWF Output:\t" << (std::hex); for(uint32_t t = 0; t < OWF_BYTES; t++) { std::cout << (uint32_t) outptr[t]; } std::cout << (std::dec) << std::endl; #endif } } check_chan->send_id_len(outhashes, outhashbytelen, check_buf.otid, check_buf.numblocks); free(rcv_buf_perm); free(rcv_buf_permchoices); //free(tmpbuf); free(ka); free(kb); free(check_buf.T0); //free(check_buf.T1); free(outhashes); #ifndef AES_OWF free(hash_buf); #endif }