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
}