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; }
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; }