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); }
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); } }
BOOL OTExtSnd::verifyOT(uint64_t NumOTs) { cout << "Verifying OT" << endl; uint64_t processedOTBlocks, OTsPerIteration; uint32_t bytelen = ceil_divide(m_nBitLength, 8); uint64_t nSnd; uint8_t* resp; channel* chan = new channel(0, m_cRcvThread, m_cSndThread); for (uint64_t i = 0; i < NumOTs; i += OTsPerIteration) { processedOTBlocks = min((uint64_t) NUMOTBLOCKS, ceil_divide(NumOTs - i, AES_BITS)); OTsPerIteration = min(processedOTBlocks * AES_BITS, NumOTs - i); nSnd = ceil_divide(OTsPerIteration * m_nBitLength, 8); chan->send_id_len(m_vValues[0].GetArr() + bits_in_bytes(i * m_nBitLength), nSnd, i, OTsPerIteration); chan->send_id_len(m_vValues[1].GetArr() + bits_in_bytes(i * m_nBitLength), nSnd, i, OTsPerIteration); //sndthread->add_snd_task_start_len(0, nSnd, m_vValues[0].GetArr() + bits_in_bytes(i * m_nBitLength), i, OTsPerIteration); //sndthread->add_snd_task_start_len(0, nSnd, m_vValues[1].GetArr() + bits_in_bytes(i * m_nBitLength), i, OTsPerIteration); //cout << "Waiting for reply" << endl; resp = chan->blocking_receive(); //rcvev->Wait(); //resp = *rcvqueue->front(); //rcvqueue->pop(); //cout << "Got reply with " << (uint32_t) resp << endl; if (*resp == 0x00) { cout << "OT verification unsuccessful" << endl; free(resp); chan->synchronize_end(); return false; } free(resp); } //cout << "signalling end" << endl, //sndthread->signal_end(0); cout << "OT Verification successful" << flush << endl; chan->synchronize_end(); return true; }
void OTExtSnd::MaskAndSend(CBitVector* snd_buf, uint64_t OT_ptr, uint64_t OT_len, channel* chan) { m_fMaskFct->Mask(OT_ptr, OT_len, m_vValues, snd_buf, m_eSndOTFlav); if (m_eSndOTFlav == Snd_R_OT || m_eSndOTFlav == Snd_GC_OT) return; uint64_t bufsize = bits_in_bytes(OT_len * m_nBitLength); uint8_t* buf; if (m_eSndOTFlav == Snd_OT) { buf = (uint8_t*) malloc(2*bufsize); memcpy(buf, snd_buf[0].GetArr(), bufsize); memcpy(buf+ bufsize, snd_buf[1].GetArr(), bufsize); bufsize *= 2; } else if (m_eSndOTFlav == Snd_C_OT) { buf = (uint8_t*) malloc(bufsize); memcpy(buf, snd_buf[1].GetArr(), bufsize); } chan->send_id_len(buf, bufsize, OT_ptr, OT_len); free(buf); }
void ALSZOTExtRec::ComputeBaseOTs(field_type ftype) { /*m_cBaseOT = new SimpleOT(m_cCrypt, ftype); ComputePKBaseOTs(); delete m_cBaseOT;*/ uint32_t nsndvals = 2; if(m_bDoBaseOTs) { //use public-key crypto routines (simple OT) m_cBaseOT = new SimpleOT(m_cCrypt, ftype); ComputePKBaseOTs(); delete m_cBaseOT; /*base_ots_snd_t* tmp = (base_ots_snd_t*) malloc(sizeof(base_ots_snd_t)); tmp->base_ot_key_ptr = (AES_KEY_CTX*) malloc(sizeof(AES_KEY_CTX) * m_nBaseOTs * nsndvals); memcpy(tmp->base_ot_key_ptr, m_vBaseOTKeys, sizeof(AES_KEY_CTX) * m_nBaseOTs * nsndvals); m_tBaseOTQ.push_back(tmp);*/ } else { ALSZOTExtSnd* snd = new ALSZOTExtSnd(m_cCrypt, m_cRcvThread, m_cSndThread, m_nBaseOTs, m_nChecks); uint32_t numots = buffer_ot_keys * m_nBaseOTs; XORMasking* m_fMaskFct = new XORMasking(m_cCrypt->get_seclvl().symbits); CBitVector** X = (CBitVector**) malloc(sizeof(CBitVector*) * nsndvals);//new CBitVector[nsndvals]; uint32_t secparambytes = bits_in_bytes(m_cCrypt->get_seclvl().symbits); uint8_t* buf; for(uint32_t i = 0; i < nsndvals; i++) { X[i] = new CBitVector(); X[i]->Create(numots * m_cCrypt->get_seclvl().symbits); } //X1.Create(numots * m_cCrypt->get_seclvl().symbits); snd->computePKBaseOTs(); snd->ComputeBaseOTs(ftype); snd->send(numots, m_cCrypt->get_seclvl().symbits, nsndvals, X, Snd_R_OT, Rec_R_OT, 1, m_fMaskFct); //assign keys to base OT queue buf = (uint8_t*) malloc(secparambytes * nsndvals * m_nBaseOTs); OT_AES_KEY_CTX* tmp_keys; for(uint32_t i = 0; i < buffer_ot_keys; i++) { //base_ots_snd_t* tmp = (base_ots_snd_t*) malloc(sizeof(base_ots_snd_t)); tmp_keys = (OT_AES_KEY_CTX*) malloc(sizeof(OT_AES_KEY_CTX) * m_nBaseOTs * nsndvals); /*for(uint32_t j = 0; j < m_nBaseOTs; j++) { memcpy(buf + j * nsndvals * secparambytes, X0.GetArr() + (i * m_nBaseOTs + j) * secparambytes, secparambytes); memcpy(buf + (j * nsndvals + 1) * secparambytes, X1.GetArr() + (i * m_nBaseOTs + j) * secparambytes, secparambytes); }*/ memcpy(buf, X[0]->GetArr() + secparambytes * m_nBaseOTs * i, secparambytes * m_nBaseOTs); memcpy(buf + secparambytes * m_nBaseOTs, X[1]->GetArr() + secparambytes * m_nBaseOTs * i, secparambytes * m_nBaseOTs); InitAESKey(tmp_keys, buf, nsndvals * m_nBaseOTs, m_cCrypt); m_tBaseOTKeys.push_back(tmp_keys); } free(buf); for(uint32_t i = 0; i < nsndvals; i++) { delete X[i]; } //free(X); // X0.delCBitVector(); // X1.delCBitVector(); delete m_fMaskFct; delete snd; } }
nnob_snd_check_t NNOBOTExtSnd::UpdateCheckBuf(uint8_t* tocheckseed, uint8_t* tocheckrcv, uint64_t otid, uint64_t numblocks, channel* check_chan) { uint64_t rowbytelen = m_nBlockSizeBytes * numblocks; uint64_t checkbytelen = min(rowbytelen, bits_in_bytes(m_nOTs - otid)); uint8_t* hash_buf = (uint8_t*) malloc(SHA512_DIGEST_LENGTH); uint8_t* tmpbuf = (uint8_t*) malloc(rowbytelen); uint8_t *idaptr, *idbptr; nnob_snd_check_t check_buf; //check_buf.rcv_chk_buf = (uint8_t*) malloc(m_nChecks * OWF_BYTES); check_buf.chk_buf = (uint8_t*) malloc(m_nChecks * OWF_BYTES); uint8_t *chk_buf_ptr = check_buf.chk_buf; uint8_t *idatmpbuf = (BYTE*) malloc(sizeof(BYTE) * rowbytelen); uint8_t *idbtmpbuf = (BYTE*) malloc(sizeof(BYTE) * rowbytelen); uint8_t *seedptr, *rcvptr; //uint32_t blockoffset = ceil_divide(otid, NUMOTBLOCKS * m_nBlockSizeBits); uint32_t blockid = 0; //TODO bring in as soon as 3-step OT is implemented check_buf.otid = otid; check_buf.numblocks = numblocks; check_buf.perm = (linking_t*) malloc(sizeof(linking_t*) * m_nChecks); check_buf.permchoicebits = (BYTE*) malloc(sizeof(uint8_t) * m_nChecks); genRandomMapping(check_buf.perm, m_nBaseOTs); for(uint32_t i = 0; i < m_nChecks; i++) { check_buf.permchoicebits[i] = m_vU.GetBit(blockid * m_nBaseOTs + check_buf.perm[i].ida) ^ m_vU.GetBit(blockid * m_nBaseOTs + check_buf.perm[i].idb); } //right now the checkbytelen needs to be a multiple of AES_BYTES assert(ceil_divide(rowbytelen, OWF_BYTES) * OWF_BYTES == rowbytelen); #ifdef DEBUG_NNOB_CHECKS m_vU.PrintHex(); #endif for(uint64_t i = 0; i < m_nChecks; i++, chk_buf_ptr+=OWF_BYTES) { if(m_vU.GetBit(blockid * m_nBaseOTs + check_buf.perm[i].ida) == 0) { memcpy(idatmpbuf, tocheckseed + check_buf.perm[i].ida * rowbytelen, rowbytelen); } else { seedptr = tocheckseed + check_buf.perm[i].ida * rowbytelen; rcvptr = tocheckrcv + check_buf.perm[i].ida * rowbytelen; for(int j = 0; j < rowbytelen/sizeof(uint64_t); j++) { ((uint64_t*) idatmpbuf)[j] = ((uint64_t*) seedptr)[j] ^ ((uint64_t*) rcvptr)[j]; } } if(m_vU.GetBit(blockid * m_nBaseOTs + check_buf.perm[i].idb) == 0) { memcpy(idbtmpbuf, tocheckseed + check_buf.perm[i].idb * rowbytelen, rowbytelen); } else { seedptr = tocheckseed + check_buf.perm[i].idb * rowbytelen; rcvptr = tocheckrcv + check_buf.perm[i].idb * rowbytelen; for(int j = 0; j < rowbytelen/sizeof(uint64_t); j++) { ((uint64_t*) idbtmpbuf)[j] = ((uint64_t*) seedptr)[j] ^ ((uint64_t*) rcvptr)[j]; } } /*#ifdef DEBUG_NNOB_CHECKS cout << "seedA: " << (hex) << ((uint64_t*) (tocheckseed + check_buf.perm[i].ida * rowbytelen))[0] << ", rcvA: " << ((uint64_t*) (tocheckrcv + check_buf.perm[i].ida * rowbytelen))[0] << (dec) << endl; cout << "seedB: " << (hex) << ((uint64_t*) (tocheckseed + check_buf.perm[i].idb * rowbytelen))[0] << ", rcvB: " << ((uint64_t*) (tocheckrcv + check_buf.perm[i].idb * rowbytelen))[0] << (dec) << endl; cout << "input to owf " << (hex) << ((uint64_t*) idatmpbuf)[0] << ", " << ((uint64_t*) idbtmpbuf)[0] << (dec) << endl; #endif*/ memset(tmpbuf, 0, rowbytelen); for(uint64_t j = 0; j < rowbytelen/sizeof(uint64_t); j++) { ((uint64_t*) tmpbuf)[j] = ((uint64_t*) tmpbuf)[j] ^ ((uint64_t*) idatmpbuf)[j] ^ ((uint64_t*) idbtmpbuf)[j]; } #ifdef DEBUG_NNOB_CHECKS_INPUT cout << "XOR-OWF Input:\t" << (hex); for(uint32_t t = 0; t < checkbytelen; t++) { cout << setw(2) << setfill('0') << (uint32_t) tmpbuf[t]; } cout << (dec) << endl; #endif #ifdef AES_OWF owf(&aesowfkey, rowbytelen, tmpbuf, resbuf); #else //m_cCrypt->hash_buf(chk_buf_ptr, OWF_BYTES, tmpbuf, checkbytelen, hash_buf);//hash_buf, rowbytelen, tmpbuf, resbuf, hash_buf); sha512_hash(chk_buf_ptr, OWF_BYTES, tmpbuf, checkbytelen, hash_buf); #endif #ifdef DEBUG_NNOB_CHECKS_OUTPUT cout << "XOR-OWF Output:\t" << (hex); for(uint32_t t = 0; t < OWF_BYTES; t++) { cout << (uint32_t) chk_buf_ptr[t]; } cout << (dec) << endl; #endif //XORandOWF(idatmpbuf, idbtmpbuf, checkbytelen, tmpbuf, chk_buf_ptr, hash_buf); } /* for(uint64_t i = 0; i < m_nChecks; i++, seedcheckbufptr+=OWF_BYTES, rcvcheckbufptr+=OWF_BYTES) { memset(tmpbuf, 0, rowbytelen); #ifdef DEBUG_ALSZ_CHECKS cout << i << "-th check between " << check_buf.perm[i].ida << " and " << check_buf.perm[i].idb << ": " << endl; #endif XORandOWF(tocheckseed + check_buf.perm[i].ida * rowbytelen, tocheckseed + check_buf.perm[i].idb * rowbytelen, rowbytelen, tmpbuf, seedcheckbufptr, hash_buf); XORandOWF(tocheckrcv + check_buf.perm[i].ida * rowbytelen, tocheckrcv + check_buf.perm[i].idb * rowbytelen, rowbytelen, tmpbuf, rcvcheckbufptr, hash_buf); }*/ free(tmpbuf); free(hash_buf); free(idatmpbuf); free(idbtmpbuf); //Send the permutation and the XORed bits over to the receiver check_chan->send_id_len((uint8_t*) check_buf.perm, sizeof(linking_t) * m_nChecks, otid, numblocks); check_chan->send(check_buf.permchoicebits, m_nChecks); return check_buf; }
BOOL NNOBOTExtSnd::sender_routine(uint32_t id, uint64_t myNumOTs) { uint64_t myStartPos = id * myNumOTs; uint64_t wd_size_bits = m_nBlockSizeBits; uint64_t processedOTBlocks = min((uint64_t) NUMOTBLOCKS, ceil_divide(myNumOTs, wd_size_bits)); uint64_t OTsPerIteration = processedOTBlocks * wd_size_bits; uint64_t tmpctr, tmpotlen; uint32_t nchans = 2; bool use_mat_chan = (m_eSndOTFlav == Snd_GC_OT || m_bUseMinEntCorRob); if(use_mat_chan) { nchans = 3; } channel* ot_chan = new channel(nchans*id, m_cRcvThread, m_cSndThread); channel* check_chan = new channel(nchans*id + 1, m_cRcvThread, m_cSndThread); channel* mat_chan; if(use_mat_chan) { mat_chan = new channel(nchans*id+2, m_cRcvThread, m_cSndThread); } myNumOTs = min(myNumOTs + myStartPos, m_nOTs) - myStartPos; uint64_t lim = myStartPos + myNumOTs; uint64_t** rndmat; // The vector with the received bits CBitVector vRcv(m_nBaseOTs * OTsPerIteration); vRcv.Reset(); // Holds the reply that is sent back to the receiver uint32_t numsndvals = 2; CBitVector* vSnd; CBitVector* seedbuf = new CBitVector[m_nSndVals]; for (uint32_t u = 0; u < m_nSndVals; u++) seedbuf[u].Create(OTsPerIteration * m_cCrypt->get_aes_key_bytes() * 8); #ifdef ZDEBUG cout << "seedbuf size = " <<OTsPerIteration * AES_KEY_BITS << endl; #endif vSnd = new CBitVector[numsndvals]; for (uint32_t i = 0; i < numsndvals; i++) { vSnd[i].Create(OTsPerIteration * m_nBitLength); } // Contains the parts of the V matrix CBitVector Q(wd_size_bits * OTsPerIteration); mask_buf_t tmpmaskbuf; uint64_t OT_ptr = myStartPos; uint8_t *rcvbuftmpptr, *rcvbufptr; queue<nnob_snd_check_t> check_queue; queue<mask_buf_t> mask_queue; uint32_t startpos = 0; if(m_eRecOTFlav==Rec_R_OT) { startpos = 1; } if(m_eSndOTFlav == Snd_GC_OT) { initRndMatrix(&rndmat, m_nBitLength, m_nBaseOTs); } #ifdef OTTiming double totalMtxTime = 0, totalTnsTime = 0, totalHshTime = 0, totalRcvTime = 0, totalSndTime = 0, totalUnMaskTime = 0, totalHashCheckTime = 0; timeval tempStart, tempEnd; #endif while (OT_ptr < lim) //do while there are still transfers missing { processedOTBlocks = min((uint64_t) NUMOTBLOCKS, ceil_divide(lim - OT_ptr, wd_size_bits)); OTsPerIteration = processedOTBlocks * wd_size_bits; #ifdef ZDEBUG cout << "Processing block " << nProgress << " with length: " << OTsPerIteration << ", and limit: " << lim << endl; #endif #ifdef OTTiming gettimeofday(&tempStart, NULL); #endif rcvbufptr = ot_chan->blocking_receive_id_len(&rcvbuftmpptr, &tmpctr, &tmpotlen); //vRcv.AttachBuf(rcvbuftmpptr, bits_in_bytes(m_nBaseOTs * OTsPerIteration)); vRcv.SetBytes(rcvbuftmpptr, bits_in_bytes(OTsPerIteration*startpos), bits_in_bytes((m_nBaseOTs-startpos)*OTsPerIteration)); free(rcvbufptr); //vRcv.PrintHex(); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalRcvTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif BuildQMatrix(Q, OT_ptr, processedOTBlocks); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalMtxTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif check_queue.push(UpdateCheckBuf(Q.GetArr(), vRcv.GetArr(), OT_ptr, processedOTBlocks, check_chan)); FillAndSendRandomMatrix(rndmat, mat_chan); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalHashCheckTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif UnMaskBaseOTs(Q, vRcv, processedOTBlocks); GenerateSendAndXORCorRobVector(Q, OTsPerIteration, mat_chan); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalUnMaskTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif Q.Transpose(wd_size_bits, OTsPerIteration); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalTnsTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif HashValues(Q, seedbuf, vSnd, OT_ptr, min(lim - OT_ptr, OTsPerIteration), rndmat); #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalHshTime += getMillies(tempStart, tempEnd); gettimeofday(&tempStart, NULL); #endif //TODO: outsource into method tmpmaskbuf.otid = OT_ptr; tmpmaskbuf.otlen = min(lim - OT_ptr, OTsPerIteration); tmpmaskbuf.maskbuf = new CBitVector[numsndvals]; for(uint32_t i = 0; i < numsndvals; i++) tmpmaskbuf.maskbuf[i].Copy(vSnd[i]); mask_queue.push(tmpmaskbuf); if(check_chan->data_available()) { assert(CheckConsistency(&check_queue, check_chan));//TODO assert tmpmaskbuf = mask_queue.front(); mask_queue.pop(); MaskAndSend(tmpmaskbuf.maskbuf, tmpmaskbuf.otid, tmpmaskbuf.otlen, ot_chan); } #ifdef OTTiming gettimeofday(&tempEnd, NULL); totalSndTime += getMillies(tempStart, tempEnd); #endif OT_ptr += min(lim - OT_ptr, OTsPerIteration); Q.Reset(); //free(rcvbufptr); } while(!check_queue.empty()) { if(check_chan->data_available()) { assert(CheckConsistency(&check_queue, check_chan));//TODO assert tmpmaskbuf = mask_queue.front(); mask_queue.pop(); MaskAndSend(tmpmaskbuf.maskbuf, tmpmaskbuf.otid, tmpmaskbuf.otlen, ot_chan); } } //vRcv.delCBitVector(); ot_chan->synchronize_end(); check_chan->synchronize_end(); Q.delCBitVector(); for (uint32_t u = 0; u < m_nSndVals; u++) seedbuf[u].delCBitVector(); for (uint32_t i = 0; i < numsndvals; i++) vSnd[i].delCBitVector(); if (numsndvals > 0) free(vSnd); if(use_mat_chan) { mat_chan->synchronize_end(); } if(m_eSndOTFlav == Snd_GC_OT) { freeRndMatrix(rndmat, m_nBaseOTs); } #ifdef OTTiming cout << "Sender time benchmark for performing " << myNumOTs << " OTs on " << m_nBitLength << " bit strings" << endl; cout << "Time needed for: " << endl; cout << "\t Matrix Generation:\t" << totalMtxTime << " ms" << endl; cout << "\t BaseOT Unmasking:\t" << totalUnMaskTime << " ms" << endl; cout << "\t Check Hashing:\t" << totalHashCheckTime << " ms" << endl; cout << "\t Sending Matrix:\t" << totalSndTime << " ms" << endl; cout << "\t Transposing Matrix:\t" << totalTnsTime << " ms" << endl; cout << "\t Hashing Matrix:\t" << totalHshTime << " ms" << endl; cout << "\t Receiving Values:\t" << totalRcvTime << " ms" << endl; #endif delete ot_chan; delete check_chan; return TRUE; }
void KKOTExtSnd::KKMaskAndSend(CBitVector * snd_buf, uint64_t OT_ptr, uint64_t OT_len, channel * chan) { // m_fMaskFct->Mask(OT_ptr, OT_len, m_vValues, snd_buf, m_eSndOTFlav); uint32_t choicecodebits = ceil_log2(m_nSndVals); uint64_t valsize = bits_in_bytes(OT_len * m_nBitLength * choicecodebits); uint64_t bufsize = valsize * (m_nSndVals - 2); // For R-OT uint8_t *buf; buf = (uint8_t *)malloc(bufsize); CBitVector tmpmask(valsize * 8); CBitVector *snd_buf_ptr; // Define the X0 values as the output of 0 and the X1 values as output // of m_nSndVals-1 (only 1 values) m_vValues[0]->SetBytes( snd_buf[0].GetArr(), bits_in_bytes(OT_ptr * choicecodebits * m_nBitLength), valsize); m_vValues[1]->SetBytes( snd_buf[m_nSndVals - 1].GetArr(), bits_in_bytes(OT_ptr * choicecodebits * m_nBitLength), valsize); #ifdef DEBUG_KK_OTBREAKDOWN cout << endl << "X0: "; m_vValues[0].PrintHex(0, valsize); cout << "X1: "; m_vValues[1].PrintHex(0, valsize); #endif uint8_t *tmpbuf = (uint8_t *)malloc(bits_in_bytes(m_nBitLength)); for (uint32_t i = 1; i < m_nSndVals - 1; i++) { tmpmask.Reset(); for (uint32_t j = 0; j < choicecodebits; j++) { // write the value of snd_buf[0] or snd_buf[1] in every // choicecodebits position snd_buf_ptr = m_vValues[((i >> j) & 0x01)]; for (uint32_t o = 0; o < OT_len; o++) { memset(tmpbuf, 0, bits_in_bytes(m_nBitLength)); snd_buf_ptr->GetBits(tmpbuf, (OT_ptr + o) * choicecodebits * m_nBitLength + j * m_nBitLength, m_nBitLength); tmpmask.SetBits(tmpbuf, o * choicecodebits * m_nBitLength + j * m_nBitLength, m_nBitLength); // tmpmask.SetBit(i*choicecodebits + o, // snd_buf_ptr->GetBit(i*choicecodebits + o)); } } #ifdef DEBUG_KK_OTBREAKDOWN cout << "Val " << i << ": "; tmpmask.PrintHex(0, valsize); cout << "Mask " << i << ": "; snd_buf[i].PrintHex(0, valsize); #endif tmpmask.XORBytes(snd_buf[i].GetArr(), 0, valsize); #ifdef DEBUG_KK_OTBREAKDOWN cout << "Res " << i << ": "; tmpmask.PrintHex(0, valsize); #endif memcpy(buf + (i - 1) * valsize, tmpmask.GetArr(), valsize); } chan->send_id_len(buf, bufsize, OT_ptr, OT_len); free(buf); free(tmpbuf); tmpmask.delCBitVector(); }
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 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 }