Пример #1
0
		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);
			}
		}
Пример #2
0
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();
}
Пример #3
0
		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);
			}
		}
Пример #4
0
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);
}
Пример #5
0
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);
	}
}
Пример #6
0
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);
}
Пример #7
0
//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

	}
}
Пример #8
0
//---------------------------------------------------------------------------
//	@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);
	}
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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);
    }
Пример #12
0
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);
}
Пример #13
0
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);
}
Пример #14
0
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
}
Пример #15
0
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;
}
Пример #16
0
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;
}