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 }