Exemple #1
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;
}
Exemple #2
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;
}