void CPostingMerger_WL::mergeWith(docid_t baseDocID,CInMemoryPosting* pInMemoryPosting) { CInMemoryPosting_WL* pInMemoryPostingWL = static_cast<CInMemoryPosting_WL*>(pInMemoryPosting); FIRTEX_ASSERT(pInMemoryPostingWL,_T("dynamic cast failed.")); ///flush last doc pInMemoryPostingWL->flushLastDoc(true); CBitVector* pFilter = pInMemoryPosting->getFilter(); if(pFilter && pFilter->hasSmallThan((size_t)pInMemoryPostingWL->m_nLastDocID))///there are deleted documents { PostingChunk* pChunk = pInMemoryPostingWL->m_pDocFreqList->m_pHeadChunk; if(pChunk) { uint8_t* bp = &(pChunk->data[0]); docid_t firstDocID = CCompressedPostingList::decodePosting32(bp); if(!pFilter->hasBiggerThan(firstDocID))///no deleted documents in this posting { mergeWith_(baseDocID,pInMemoryPostingWL); } else //may be there are some deleted documents in this posting { mergeWith_GC(baseDocID,pInMemoryPostingWL,pFilter); } } } else { mergeWith_(baseDocID,pInMemoryPostingWL); } }
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(); }
void CPostingMerger_WL::mergeWith(docid_t baseDocID,COnDiskPosting* pOnDiskPosting) { COnDiskPosting_WL* pOnDiskPostingWL = static_cast<COnDiskPosting_WL*>(pOnDiskPosting); FIRTEX_ASSERT(pOnDiskPostingWL,_T("static cast failed.")); CBitVector* pFilter = pOnDiskPostingWL->getFilter(); if(pFilter && pFilter->hasSmallThan((size_t)pOnDiskPostingWL->m_chunkDesc.lastdocid))///there are deleted documents { mergeWith_GC(baseDocID,pOnDiskPostingWL,pFilter); } else { mergeWith_(baseDocID,pOnDiskPostingWL); } }
void OTExtSnd::BuildQMatrix(CBitVector& T, uint64_t OT_ptr, uint64_t numblocks) { BYTE* Tptr = T.GetArr(); uint8_t* ctr_buf = (uint8_t*) calloc (AES_BYTES, sizeof(uint8_t)); uint32_t dummy; uint64_t* counter = (uint64_t*) ctr_buf; uint64_t wd_size_bytes = m_nBlockSizeBytes;//pad_to_power_of_two(m_nBaseOTs/8);//1 << (ceil_log2(m_nBaseOTs) - 3); uint64_t rowbytelen = wd_size_bytes * numblocks; AES_KEY_CTX* seedptr = m_vBaseOTKeys; uint64_t global_OT_ptr = OT_ptr + m_nCounter; uint64_t iters = rowbytelen / AES_BYTES; for (uint64_t k = 0, b; k < m_nBaseOTs; k++) { *counter = global_OT_ptr; for (b = 0; b < iters; b++, (*counter)++, Tptr += AES_BYTES) { m_cCrypt->encrypt(seedptr + k, Tptr, ctr_buf, AES_BYTES); #ifdef DEBUG_MALICIOUS cout << "k = " << k << ": "<< (hex) << ((uint64_t*) Tptr)[0] << ((uint64_t*) Tptr)[1] << (hex) << endl; #endif } #ifdef DEBUG_OT_SEED_EXPANSION cout << "Xs[" << k << "]: " << (hex); for(uint64_t i = 0; i < AES_BYTES * iters; i++) { cout << setw(2) << setfill('0') << (uint32_t) (Tptr-AES_BYTES*iters)[i]; } cout << (dec) << " (" << (*counter)-iters << ")" <<endl; #endif } free(ctr_buf); }
void OTExtSnd::GenerateSendAndXORCorRobVector(CBitVector& Q, uint64_t OT_len, channel* chan) { if(m_bUseMinEntCorRob) { uint64_t len = bits_in_bytes(m_nBaseOTs * OT_len); uint8_t* rndvec = (uint8_t*) malloc(len); m_cCrypt->gen_rnd(rndvec, len); Q.XORBytes(rndvec, len); chan->send(rndvec, len); free(rndvec); } }
void OTExtSnd::ReceiveMasks(CBitVector& vRcv, channel* chan, uint64_t processedOTs) { //uint64_t nSize = bits_in_bytes(m_nBaseOTs * processedOTs); uint64_t tmpctr, tmpotlen; uint32_t startpos = 0; uint8_t *rcvbuftmpptr, *rcvbufptr; rcvbufptr = chan->blocking_receive_id_len(&rcvbuftmpptr, &tmpctr, &tmpotlen); if(m_eRecOTFlav == Rec_R_OT) { startpos = 1; #ifdef GENERATE_T_EXPLICITELY vRcv.SetBytesToZero(0, 2* bits_in_bytes(processedOTs)); #else vRcv.SetBytesToZero(0, bits_in_bytes(processedOTs)); #endif } #ifdef GENERATE_T_EXPLICITELY if(m_eRecOTFlav == Rec_R_OT) { vRcv.SetBytes(rcvbuftmpptr, bits_in_bytes(processedOTs), bits_in_bytes((m_nBaseOTs -startpos) * processedOTs));//AttachBuf(rcvbuftmpptr, bits_in_bytes(m_nBaseOTs * OTsPerIteration)); vRcv.SetBytes(rcvbuftmpptr + bits_in_bytes((m_nBaseOTs -startpos) * processedOTs), bits_in_bytes(m_nBaseOTs * processedOTs), bits_in_bytes((m_nBaseOTs -startpos) * processedOTs)); } else { vRcv.SetBytes(rcvbuftmpptr, 0, 2 * bits_in_bytes(m_nBaseOTs* processedOTs));//AttachBuf(rcvbuftmpptr, bits_in_bytes(m_nBaseOTs * OTsPerIteration)); } #else vRcv.SetBytes(rcvbuftmpptr, bits_in_bytes(startpos * processedOTs), bits_in_bytes((m_nBaseOTs - startpos) * processedOTs));//AttachBuf(rcvbuftmpptr, bits_in_bytes(m_nBaseOTs * OTsPerIteration)); #endif free(rcvbufptr); }
//XOR m_nU on top void OTExtSnd::UnMaskBaseOTs(CBitVector& T, CBitVector& RcvBuf, uint64_t numblocks) { uint64_t rowbytelen = m_nBlockSizeBytes * numblocks; uint8_t* rcvbufptr = RcvBuf.GetArr(); #ifdef GENERATE_T_EXPLICITELY uint64_t blocksizebytes = m_nBaseOTs * rowbytelen; #endif for (uint64_t k = 0; k < m_nBaseOTs; k++, rcvbufptr += rowbytelen) { #ifdef GENERATE_T_EXPLICITELY if (m_vU.GetBit(k) == 0) { T.XORBytes(rcvbufptr, k * rowbytelen, rowbytelen); } else { T.XORBytes(rcvbufptr + blocksizebytes, k * rowbytelen, rowbytelen); } #else if (m_vU.GetBit(k)) { T.XORBytes(rcvbufptr, k * rowbytelen, rowbytelen); } #endif } }
//--------------------------------------------------------------------------- // @function: // CUnittest::UlFindTest // // @doc: // Find a test with given attributes and add it the list; // If no name passed (NULL), match only on attribute; // //--------------------------------------------------------------------------- void CUnittest::FindTest ( CBitVector &bv, ETestType ett, CHAR *szTestName ) { for(ULONG i = 0; i < CUnittest::m_ulTests; i++) { CUnittest &ut = CUnittest::m_rgut[i]; if ((ut.Ett() == ett && (NULL == szTestName || ut.FEquals(szTestName))) || (NULL != szTestName && ut.FEquals(szTestName))) { (void) bv.FExchangeSet(i); } } if(bv.FEmpty()) { GPOS_TRACE_FORMAT("'%s' is not a valid test case.", szTestName); } }
void CClient::RunOTThread() { // generate input vector int nInputStart = m_pCircuit->GetInputStart(ID_CLIENT); int nInputEnd = m_pCircuit->GetInputEnd(ID_CLIENT); int nInputSize = nInputEnd-nInputStart+1; m_r.Create(nInputSize); for(int i=nInputStart; i<=nInputEnd; i++) { m_r.SetBit(i-nInputStart, m_pGates[i].val); } // IKNP-first step: sender of Naor-Pinkas ZZ& p = CConfig::GetInstance()->GetPrime(); ZZ& g = CConfig::GetInstance()->GetGenerator(); ZZ q = p/2 - 1; int nBufSize = NUM_EXECS_NAOR_PINKAS * FIELD_SIZE_IN_BYTES; BYTE* pBuf = new BYTE[nBufSize]; // generate and send c CBitVector rnd; rnd.Create( NUM_EXECS_NAOR_PINKAS*FIELD_SIZE_IN_BITS, m_aSeed, m_nCounter); ZZ* pC = new ZZ[NUM_EXECS_NAOR_PINKAS ]; BYTE* pBufIdx = pBuf; BYTE* pBufIn = rnd.GetArr(); ZZ ztmp, ztmp2; for(int i=0; i<NUM_EXECS_NAOR_PINKAS; i++) { ZZFromBytes(ztmp, pBufIn, FIELD_SIZE_IN_BYTES); rem(ztmp2, ztmp, p); SqrMod(pC[i], ztmp2, p); BytesFromZZ(pBufIdx, pC[i], FIELD_SIZE_IN_BYTES); pBufIn += FIELD_SIZE_IN_BYTES; pBufIdx += FIELD_SIZE_IN_BYTES; } m_sockOT.Send(pBuf, NUM_EXECS_NAOR_PINKAS * FIELD_SIZE_IN_BYTES); // receive pk0 m_sockOT.Receive(pBuf, nBufSize); ZZ* pPK0 = new ZZ[NUM_EXECS_NAOR_PINKAS]; ZZ* pPK1 = new ZZ[NUM_EXECS_NAOR_PINKAS]; pBufIdx = pBuf; for(int i=0; i<NUM_EXECS_NAOR_PINKAS; i++ ) { ZZFromBytes(pPK0[i], pBufIdx, FIELD_SIZE_IN_BYTES); pBufIdx += FIELD_SIZE_IN_BYTES; // pPK[i] = pC[i]/pPK0[i] InvMod(ztmp, pPK0[i], p); MulMod(pPK1[i], pC[i], ztmp, p); } delete [] pBuf; // send <g^r1, Enc(M0)> and <g^r2, Enc(M1)> int nMsgSize = (nInputEnd-nInputStart)/SHA1_BITS + 1; // in sha1 scale int nMsginOT = FIELD_SIZE_IN_BYTES + nMsgSize*SHA1_BYTES; int nBufSize2 = NUM_EXECS_NAOR_PINKAS * nMsginOT * 2; BYTE* pBuf2 = new BYTE[nBufSize2]; // to do ZZ* pR0 = new ZZ[NUM_EXECS_NAOR_PINKAS]; ZZ* pR1 = new ZZ[NUM_EXECS_NAOR_PINKAS]; rnd.Create( NUM_EXECS_NAOR_PINKAS*2*FIELD_SIZE_IN_BITS, m_aSeed, m_nCounter); pBufIdx = rnd.GetArr(); for(int i=0; i<NUM_EXECS_NAOR_PINKAS; i++) { ZZFromBytes(ztmp, pBufIdx, FIELD_SIZE_IN_BYTES); rem(pR0[i], ztmp, q); pBufIdx += FIELD_SIZE_IN_BYTES; ZZFromBytes(ztmp, pBufIdx, FIELD_SIZE_IN_BYTES); rem(pR1[i], ztmp, q); pBufIdx += FIELD_SIZE_IN_BYTES; } ZZ gr0, gr1, pkr0, pkr1; pBufIdx = pBuf2; sha1_context sha; BYTE tmp[FIELD_SIZE_IN_BYTES]; SHA_BUFFER buf_key; for(int i=0; i<NUM_EXECS_NAOR_PINKAS; i++) { // put g^r0 PowerMod(gr0, g, pR0[i], p); BytesFromZZ(pBufIdx, gr0, FIELD_SIZE_IN_BYTES); pBufIdx += FIELD_SIZE_IN_BYTES; // compute the key for M0 PowerMod(pkr0, pPK0[i], pR0[i], p); BytesFromZZ(tmp, pkr0, FIELD_SIZE_IN_BYTES); sha1_starts(&sha); sha1_update(&sha, tmp, FIELD_SIZE_IN_BYTES); sha1_finish(&sha, (BYTE*) &buf_key); // put Enc(M0): M0 = t for(int j=0, k=0; j<nMsgSize; j++) { sha1_starts(&sha); sha1_update(&sha, (BYTE*) &buf_key, sizeof(buf_key)); sha1_update(&sha, (BYTE*) &j, sizeof(int)); sha1_finish(&sha, pBufIdx); for(int x=0; x < SHA1_BYTES; x++, k++, pBufIdx++ ) { *(pBufIdx) ^= m_T[i].GetByte(k); } } // put g^r1 PowerMod(gr1, g, pR1[i], p); BytesFromZZ(pBufIdx, gr1, FIELD_SIZE_IN_BYTES); pBufIdx += FIELD_SIZE_IN_BYTES; // compute the key for M1 PowerMod(pkr1, pPK1[i], pR1[i], p); BytesFromZZ(tmp, pkr1, FIELD_SIZE_IN_BYTES); sha1_starts(&sha); sha1_update(&sha, tmp, FIELD_SIZE_IN_BYTES); sha1_finish(&sha, (BYTE*) &buf_key); // put Enc(M1) : M1 = r xor t for(int j=0,k=0; j<nMsgSize; j++) { sha1_starts(&sha); sha1_update(&sha, (BYTE*) &buf_key, sizeof(buf_key)); sha1_update(&sha, (BYTE*) &j, sizeof(int)); sha1_finish(&sha, pBufIdx); for(int x=0; x < SHA1_BYTES; x++, pBufIdx++, k++ ) { *pBufIdx ^= m_T[i].GetByte(k) ^ m_r.GetByte(k); } } } m_sockOT.Send(pBuf2, nBufSize2); delete [] pBuf2; delete [] pR0; delete [] pR1; // IKNP: recv the keys for client inputs KEY* pKeys = new KEY[nInputSize*2]; m_sockOT.Receive(pKeys, nInputSize*sizeof(KEY)*2); KEY* pKeyIdx = pKeys; KEY* pYaoKeyIdx = m_pYaoKeys + nInputStart; CBitVector tj; tj.Create(NUM_EXECS_NAOR_PINKAS); for(int i=nInputStart, j=0; i<nInputEnd+1; i++, j++) { for(int x=0; x<NUM_EXECS_NAOR_PINKAS; x++) tj.SetBit(x, m_T[x].GetBit(j)); sha1_starts(&sha); sha1_update(&sha, tj.GetArr(), NUM_EXECS_NAOR_PINKAS/8); sha1_update(&sha, (BYTE*)&j, sizeof(int)); sha1_finish(&sha, (BYTE*)&buf_key); /* #ifdef _DEBUG cout << "H(tj, j)="; LOG_KEY(*pYaoKeyIdx); cout <<endl; cout << "gate-val=" << (int) m_pGates[i].val << endl; cout << "key0="; LOG_KEY(*pKeyIdx); cout << "key1="; LOG_KEY(*(pKeyIdx+1)); #endif */ if( !m_pGates[i].val ) { XOR_KEYP3(pYaoKeyIdx, (&buf_key), pKeyIdx); pKeyIdx++; pKeyIdx++; } else { pKeyIdx++; XOR_KEYP3(pYaoKeyIdx, (&buf_key), pKeyIdx); pKeyIdx++; } /* #ifdef _DEBUG cout << "gateid: " << i << " "; LOG_KEY(*pYaoKeyIdx); cout << endl; #endif */ pYaoKeyIdx++; } // clean-up delete [] pKeys; m_bOTDone = TRUE; }
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; }
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); }
void NaorPinkas::Receiver(uint32_t nSndVals, uint32_t nOTs, CBitVector& choices, channel* chan, uint8_t* ret) { fe* PK0 = m_cPKCrypto->get_fe(); fe** PK_sigma = (fe**) malloc(sizeof(fe*) * nOTs); fe** pDec = (fe**) malloc(sizeof(fe*) * nOTs); fe** pC = (fe**) malloc(sizeof(fe*) * nSndVals); fe* g = m_cPKCrypto->get_generator(); num** pK = (num**) malloc(sizeof(num*) * nOTs); uint8_t* retPtr; uint32_t u, k, choice, hash_bytes, fe_bytes; hash_bytes = m_cCrypto->get_hash_bytes(); fe_bytes = m_cPKCrypto->fe_byte_size(); brickexp *bg, *bc; bg = m_cPKCrypto->get_brick(g); //uint8_t* pBuf = (uint8_t*) malloc(nOTs * fe_bytes); uint32_t nBufSize = nSndVals * fe_bytes; //calculate the generator of the group for (k = 0; k < nOTs; k++) { PK_sigma[k] = m_cPKCrypto->get_fe(); pK[k] = m_cPKCrypto->get_rnd_num(); bg->pow(PK_sigma[k], pK[k]); } uint8_t* pBuf = chan->blocking_receive(); uint8_t* pBufIdx = pBuf; for (u = 0; u < nSndVals; u++) { pC[u] = m_cPKCrypto->get_fe(); pC[u]->import_from_bytes(pBufIdx); pBufIdx += fe_bytes; } bc = m_cPKCrypto->get_brick(pC[0]); //==================================================== // N-P receiver: send pk0 free(pBuf); pBuf = (uint8_t*) malloc(nOTs * fe_bytes); pBufIdx = pBuf; for (k = 0; k < nOTs; k++) { choice = choices.GetBit((int32_t) k); if (choice != 0) { PK0->set_div(pC[choice], PK_sigma[k]); } else { PK0->set(PK_sigma[k]); } PK0->export_to_bytes(pBufIdx); pBufIdx += fe_bytes; } //socket->Send(pBuf, nOTs * fe_bytes); chan->send(pBuf, nOTs * fe_bytes); free(pBuf); pBuf = (uint8_t*) malloc(fe_bytes); retPtr = ret; for (k = 0; k < nOTs; k++) { pDec[k] = m_cPKCrypto->get_fe(); bc->pow(pDec[k], pK[k]); pDec[k]->export_to_bytes(pBuf); hashReturn(retPtr, hash_bytes, pBuf, fe_bytes, k); retPtr += hash_bytes; } delete bc; delete bg; free(pBuf); //TODO delete all field elements and numbers free(PK_sigma); free(pDec); free(pC); free(pK); }
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); }
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 }
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 CServer::RunOTThread() { cout << "\not thread started\n" << flush; // IKNP-first step: receiver of Naor-Pinkas ZZ& p = CConfig::GetInstance()->GetPrime(); ZZ q = p/2 - 1; ZZ& g = CConfig::GetInstance()->GetGenerator(); // NP receiver: receive Cs int nBufSize = NUM_EXECS_NAOR_PINKAS * FIELD_SIZE_IN_BYTES; BYTE* pBuf = new BYTE[nBufSize]; m_sockOT.Receive(pBuf, nBufSize); ZZ* pC = new ZZ[NUM_EXECS_NAOR_PINKAS]; BYTE* pBufIdx = pBuf; for(int i=0, idx=0; i<NUM_EXECS_NAOR_PINKAS; i++) { ZZFromBytes(pC[i], pBufIdx, FIELD_SIZE_IN_BYTES); pBufIdx += FIELD_SIZE_IN_BYTES; #ifdef _DEBUG cout << "pC[" << i <<"]: " << pC[i] << endl; #endif } // compute pk0, pk1 CBitVector rnd; rnd.Create(NUM_EXECS_NAOR_PINKAS*FIELD_SIZE_IN_BITS, m_aSeed, m_nCounter); BYTE* pBufRnd = rnd.GetArr(); ZZ* pK = new ZZ[NUM_EXECS_NAOR_PINKAS]; ZZ ztmp; for(int i=0, idx=0; !m_bStop && i<NUM_EXECS_NAOR_PINKAS; i++) { ZZFromBytes(ztmp, pBufRnd, FIELD_SIZE_IN_BYTES); pBufRnd += FIELD_SIZE_IN_BYTES; rem(pK[i], ztmp, q); } pBufIdx = pBuf; ZZ pk0, pk1; for(int i=0, idx=0; !m_bStop && i<NUM_EXECS_NAOR_PINKAS; i++) { // compute pk0, pk1 if( !m_S.GetBit(i) ) { PowerMod(pk0, g, pK[i], p); } else { PowerMod(pk1, g, pK[i], p); //pk0 = pC[i]/pk1; InvMod(ztmp, pk1, p); MulMod(pk0, pC[i], ztmp, p); } #ifdef _DEBUG cout << "pk0[" << i << "]: " << pk0 << endl; #endif // put pk0 BytesFromZZ(pBufIdx, pk0, FIELD_SIZE_IN_BYTES); pBufIdx += FIELD_SIZE_IN_BYTES; } m_sockOT.Send(pBuf, nBufSize); delete [] pC; delete [] pBuf; if( m_bStop ) return; // NP receiver: get the g^r0, Enc(M0), g^r2, Enc(M1) int nInputStart = m_pCircuit->GetInputStart(ID_CLIENT); int nInputEnd = m_pCircuit->GetInputEnd(ID_CLIENT); int nMsgSize = (nInputEnd-nInputStart)/SHA1_BITS + 1; // in sha1 scale int nMsginOT = FIELD_SIZE_IN_BYTES + nMsgSize*SHA1_BYTES; int nBufSize2 = NUM_EXECS_NAOR_PINKAS * nMsginOT * 2; BYTE* pBuf2 = new BYTE[nBufSize2]; m_sockOT.Receive(pBuf2, nBufSize2); ZZ w; ZZ key; BYTE tmp[FIELD_SIZE_IN_BYTES]; sha1_context sha; SHA_BUFFER buf_key; BYTE** ppMat = new BYTE*[NUM_EXECS_NAOR_PINKAS]; BYTE* pBufToRead; BYTE* pBufMatIdx; pBufIdx = pBuf2; for(int i=0, idx=0; !m_bStop && i<NUM_EXECS_NAOR_PINKAS; i++) { ppMat[i] = new BYTE[nMsgSize*SHA1_BYTES]; if( !m_S.GetBit(i)) { pBufToRead = pBufIdx; pBufIdx += nMsginOT + nMsginOT; } else { pBufIdx += nMsginOT; pBufToRead = pBufIdx; pBufIdx += nMsginOT; } ZZFromBytes(w, pBufToRead, FIELD_SIZE_IN_BYTES); pBufToRead += FIELD_SIZE_IN_BYTES; PowerMod(key, w, pK[i], p); BytesFromZZ(tmp, key, FIELD_SIZE_IN_BYTES); sha1_starts(&sha); sha1_update(&sha, tmp, FIELD_SIZE_IN_BYTES); sha1_finish(&sha, (BYTE*) &buf_key); pBufMatIdx=ppMat[i]; for(int j=0; j<nMsgSize; j++) { sha1_starts(&sha); sha1_update(&sha, (BYTE*) &buf_key, sizeof(buf_key)); sha1_update(&sha, (BYTE*) &j, sizeof(int)); sha1_finish(&sha, tmp); for(int x=0; x<SHA1_BYTES; x++, pBufMatIdx++, pBufToRead++ ) { *(pBufMatIdx) = *(pBufToRead) ^ tmp[x]; } } } delete [] pK; if( m_bStop ) return; // IKNP-second step: send the keys for client inputs int nInputSize = nInputEnd - nInputStart + 1; KEY* pKeys = new KEY[nInputSize*2]; YAO_WIRE* wire; KEY* wirekey; CBitVector qj; qj.Create(NUM_EXECS_NAOR_PINKAS); int j=0; // 0-starting index KEY* pKeyIdx = pKeys; for(int i=nInputStart; !m_bStop && i<=nInputEnd; i++,j++) { while( m_nGatesDone < i ) { SleepMiliSec(100); } // compute qj for(int r=0; r<NUM_EXECS_NAOR_PINKAS; r++) { qj.SetBit( r, ppMat[r][j/8] & bitmask[j & 0x7] ); } // compute hash sha1_starts(&sha); sha1_update(&sha, qj.GetArr(), NUM_EXECS_NAOR_PINKAS/8); sha1_update(&sha, (BYTE*)&j, sizeof(int)); sha1_finish(&sha, (BYTE*)&buf_key); // y0 wire = m_pYaoWires+i; wirekey = wire->keys + wire->b; XOR_KEYP3( pKeyIdx, (&buf_key), wirekey ); pKeyIdx++; // compute qj xor s for(int x=0; x<NUM_EXECS_NAOR_PINKAS/8; x++ ) qj.GetArr()[x] ^= m_S.GetByte(x); /* #ifdef _DEBUG cout << "qj xor s = "; for(int z=0; z<NUM_EXECS_NAOR_PINKAS; z++) cout << (int) qj.GetBit(z); cout << endl; #endif */ // y1 sha1_starts(&sha); sha1_update(&sha, qj.GetArr(), NUM_EXECS_NAOR_PINKAS/8); sha1_update(&sha, (BYTE*)&j, sizeof(int)); sha1_finish(&sha, (BYTE*)&buf_key); wirekey = wire->keys + (wire->b^1); XOR_KEYP3( pKeyIdx, (&buf_key), wirekey ); pKeyIdx++; } m_sockOT.Send( pKeys, nInputSize*sizeof(KEY)*2); // clean-up delete [] pBuf2; for(int i=0; i<NUM_EXECS_NAOR_PINKAS; i++) { delete [] ppMat[i]; } delete [] ppMat; delete [] pKeys; cout << "\not thread ended \n" << flush; }