Пример #1
0
bool CommObject::SendFrame(span<const std::uint8_t> frame)
{
    if (frame.size() > CommMaxFrameSize)
    {
        LOGF(LOG_LEVEL_ERROR, "Frame payload is too long. Allowed: %d, Requested: '%d'.", CommMaxFrameSize, frame.size());
        return false;
    }

    uint8_t cmd[ComPrefferedBufferSize];
    cmd[0] = TransmitterSendFrame;
    memcpy(cmd + 1, frame.data(), frame.size());
    uint8_t remainingBufferSize;

    const bool status = (this->_low.WriteRead(CommTransmitter,           //
                             span<const uint8_t>(cmd, 1 + frame.size()), //
                             span<uint8_t>(&remainingBufferSize, 1)      //
                             ) == I2CResult::OK);
    if (!status)
    {
        LOG(LOG_LEVEL_ERROR, "[comm] Failed to send frame");
    }

    if (remainingBufferSize == 0xff)
    {
        LOG(LOG_LEVEL_ERROR, "[comm] Frame was not accepted by the transmitter.");
    }

    return status && remainingBufferSize != 0xff;
}
Пример #2
0
	void iterate_every_other_element(span<int, dynamic_range> av)
	{
		// pick every other element

		auto length = av.size() / 2;
#if _MSC_VER > 1800
		auto bounds = strided_bounds<1>({ length }, { 2 });
#else
		auto bounds = strided_bounds<1>(index<1>{ length }, index<1>{ 2 });
#endif
		strided_span<int, 1> strided(&av.data()[1], av.size() - 1, bounds);

		CHECK(strided.size() == length);
		CHECK(strided.bounds().index_bounds()[0] == length);
		for (auto i = 0; i < strided.size(); ++i)
		{
			CHECK(strided[i] == av[2 * i + 1]);
		}

		int idx = 0;
		for (auto num : strided)
		{
			CHECK(num == av[2 * idx + 1]);
			idx++;
		}
	}
	bool udp_tracker_connection::on_announce_response(span<char const> buf)
	{
		if (buf.size() < 20) return false;

		buf = buf.subspan(8);
		restart_read_timeout();

		tracker_response resp;

		resp.interval = aux::read_int32(buf);
		resp.min_interval = 60;
		resp.incomplete = aux::read_int32(buf);
		resp.complete = aux::read_int32(buf);
		int const num_peers = int(buf.size()) / 6;
		if ((buf.size() % 6) != 0)
		{
			fail(error_code(errors::invalid_tracker_response_length));
			return false;
		}

		boost::shared_ptr<request_callback> cb = requester();
#ifndef TORRENT_DISABLE_LOGGING
		if (cb)
		{
			cb->debug_log("<== UDP_TRACKER_RESPONSE [ url: %s ]", tracker_req().url.c_str());
		}
#endif

		if (!cb)
		{
			close();
			return true;
		}

		std::vector<peer_entry> peer_list;
		resp.peers4.reserve(num_peers);
		for (int i = 0; i < num_peers; ++i)
		{
			ipv4_peer_entry e;
			memcpy(&e.ip[0], buf.data(), 4);
			buf = buf.subspan(4);
			e.port = aux::read_uint16(buf);
			resp.peers4.push_back(e);
		}

		std::list<address> ip_list;
		for (std::vector<tcp::endpoint>::const_iterator i = m_endpoints.begin()
			, end(m_endpoints.end()); i != end; ++i)
		{
			ip_list.push_back(i->address());
		}

		cb->tracker_response(tracker_req(), m_target.address(), ip_list
			, resp);

		close();
		return true;
	}
Пример #4
0
	// allocate an uninitialized buffer of the specified size
	// and copy the initialization range into the start of the buffer
	buffer(std::size_t const size, span<char const> initialize)
		: buffer(size)
	{
		TORRENT_ASSERT(initialize.size() <= size);
		if (!initialize.empty())
		{
			std::memcpy(m_begin, initialize.data(), (std::min)(initialize.size(), size));
		}
	}
	bool udp_tracker_connection::on_scrape_response(span<char const> buf)
	{
		using namespace libtorrent::aux;

		restart_read_timeout();
		int const action = aux::read_int32(buf);
		std::uint32_t const transaction = read_uint32(buf);

		if (transaction != m_transaction_id)
		{
			fail(error_code(errors::invalid_tracker_transaction_id));
			return false;
		}

		if (action == action_error)
		{
			fail(error_code(errors::tracker_failure), -1
				, std::string(buf.data(), buf.size()).c_str());
			return true;
		}

		if (action != action_scrape)
		{
			fail(error_code(errors::invalid_tracker_action));
			return true;
		}

		if (buf.size() < 12)
		{
			fail(error_code(errors::invalid_tracker_response_length));
			return true;
		}

		int const complete = aux::read_int32(buf);
		int const downloaded = aux::read_int32(buf);
		int const incomplete = aux::read_int32(buf);

		boost::shared_ptr<request_callback> cb = requester();
		if (!cb)
		{
			close();
			return true;
		}

		cb->tracker_scrape_response(tracker_req()
			, complete, incomplete, downloaded, -1);

		close();
		return true;
	}
Пример #6
0
		void random_bytes(span<char> buffer)
		{
#if TORRENT_USE_CRYPTOAPI
			HCRYPTPROV prov;

			if (!CryptAcquireContext(&prov, NULL, NULL
				, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
			{
#ifndef BOOST_NO_EXCEPTIONS
				throw system_error(error_code(GetLastError(), system_category()));
#else
				std::terminate();
#endif
			}

			if (!CryptGenRandom(prov, int(buffer.size())
				, reinterpret_cast<BYTE*>(buffer.data())))
			{
				CryptReleaseContext(prov, 0);
#ifndef BOOST_NO_EXCEPTIONS
				throw system_error(error_code(GetLastError(), system_category()));
#else
				std::terminate();
#endif
			}

			CryptReleaseContext(prov, 0);
#elif defined TORRENT_USE_LIBCRYPTO
#ifdef TORRENT_MACOS_DEPRECATED_LIBCRYPTO
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
			int r = RAND_bytes(reinterpret_cast<unsigned char*>(buffer.data())
				, int(buffer.size()));
			if (r != 1)
			{
#ifndef BOOST_NO_EXCEPTIONS
				throw system_error(error_code(int(::ERR_get_error()), system_category()));
#else
				std::terminate();
#endif
			}
#ifdef TORRENT_MACOS_DEPRECATED_LIBCRYPTO
#pragma clang diagnostic pop
#endif
#else
			for (auto& b : buffer) b = char(random(0xff));
#endif
		}
Пример #7
0
	int count_trailing_ones_hw(span<std::uint32_t const> buf)
	{
		auto const num = int(buf.size());
		std::uint32_t const* ptr = buf.data();

		TORRENT_ASSERT(num >= 0);
		TORRENT_ASSERT(ptr != nullptr);

		for (int i = num - 1; i >= 0; i--)
		{
			if (ptr[i] == 0xffffffff) continue;

#if TORRENT_HAS_BUILTIN_CTZ
			std::uint32_t const v = ~aux::network_to_host(ptr[i]);
			return (num - i - 1) * 32 + __builtin_ctz(v);
#elif defined _MSC_VER
			std::uint32_t const v = ~aux::network_to_host(ptr[i]);
			DWORD pos;
			_BitScanForward(&pos, v);
			return (num - i - 1) * 32 + pos;
#else
			TORRENT_ASSERT_FAIL();
			return -1;
#endif
		}

		return num * 32;
	}
Пример #8
0
	bool tracker_manager::incoming_packet(char const* hostname
		, span<char const> const buf)
	{
		TORRENT_ASSERT(is_single_thread());
		// ignore packets smaller than 8 bytes
		if (buf.size() < 16) return false;

		// the first word is the action, if it's not [0, 3]
		// it's not a valid udp tracker response
		span<const char> ptr = buf;
		std::uint32_t const action = aux::read_uint32(ptr);
		if (action > 3) return false;

		std::uint32_t const transaction = aux::read_uint32(ptr);
		auto const i = m_udp_conns.find(transaction);

		if (i == m_udp_conns.end())
		{
#ifndef TORRENT_DISABLE_LOGGING
			// now, this may not have been meant to be a tracker response,
			// but chances are pretty good, so it's probably worth logging
			m_ses.session_log("incoming UDP tracker packet from %s has invalid "
				"transaction ID (%x)", hostname, int(transaction));
#endif
			return false;
		}

		std::shared_ptr<udp_tracker_connection> const p = i->second;
		// on_receive() may remove the tracker connection from the list
		return p->on_receive_hostname(hostname, buf);
	}
Пример #9
0
	ImageFileInfo DetectImageFormat(span<uint8_t> data) {
		ImageFileInfo info;

		stbi__context ctx;
		stbi__start_mem(&ctx, &data[0], data.size_bytes());

		int comp;
		if (stbi__bmp_info(&ctx, &info.width, &info.height, &comp)) {
			info.hasAlpha = (comp == 4);
			info.format = ImageFileFormat::BMP;
			return info;
		}

		TjDecompressHandle handle;
		if (tjDecompressHeader(handle, &data[0], data.size_bytes(), &info.width, &info.height) == 0) {
			info.hasAlpha = false;
			info.format = ImageFileFormat::JPEG;
			return info;
		}

		if (DetectTga(data, info)) {
			return info;
		}

		// Not a very good heuristic
		if (data.size() == 256 * 256) {
			info.width = 256;
			info.height = 256;
			info.hasAlpha = true;
			info.format = ImageFileFormat::FNTART;
			return info;
		}

		return info;
	}
	bool udp_tracker_connection::on_connect_response(span<char const> buf)
	{
		// ignore packets smaller than 16 bytes
		if (buf.size() < 16) return false;

		restart_read_timeout();

		// skip header
		buf = buf.subspan(8);

		// reset transaction
		update_transaction_id();
		std::uint64_t const connection_id = aux::read_int64(buf);

		std::lock_guard<std::mutex> l(m_cache_mutex);
		connection_cache_entry& cce = m_connection_cache[m_target.address()];
		cce.connection_id = connection_id;
		cce.expires = aux::time_now() + seconds(m_man.settings().get_int(settings_pack::udp_tracker_token_expiry));

		if (0 == (tracker_req().kind & tracker_request::scrape_request))
			send_udp_announce();
		else if (0 != (tracker_req().kind & tracker_request::scrape_request))
			send_udp_scrape();
		return true;
	}
Пример #11
0
		void update(span<char const> data)
		{
			if (CryptHashData(m_hash, reinterpret_cast<BYTE const*>(data.data()), int(data.size()), 0) == false)
			{
				throw_ex<system_error>(error_code(GetLastError(), system_category()));
			}
		}
Пример #12
0
		void random_bytes(span<char> buffer)
		{
#ifdef TORRENT_BUILD_SIMULATOR
			// simulator

			for (auto& b : buffer) b = char(random(0xff));

#elif TORRENT_USE_CRYPTOAPI
			// windows

			aux::crypt_gen_random(buffer);

#elif TORRENT_USE_DEV_RANDOM
			// /dev/random

			static dev_random dev;
			dev.read(buffer);

#elif defined TORRENT_USE_LIBCRYPTO
			// openssl

			int r = RAND_bytes(reinterpret_cast<unsigned char*>(buffer.data())
				, int(buffer.size()));
			if (r != 1) aux::throw_ex<system_error>(errors::no_entropy);
#else
			// fallback

			for (auto& b : buffer) b = char(random(0xff));
#endif
		}
Пример #13
0
 explicit
 enumerated_value_range(span<const T> v)
 noexcept
     : _begin(v.data())
     , _end(v.data()+v.size())
 {
     assert(_begin <= _end);
 }
Пример #14
0
	entry::entry(span<char const> v)
		: m_type(undefined_t)
	{
#if TORRENT_USE_ASSERTS
		m_type_queried = true;
#endif
		new(&data) string_type(v.data(), v.size());
		m_type = string_t;
	}
Пример #15
0
	inline void crypt_gen_random(span<char> buffer)
	{
		static HCRYPTPROV provider = crypt_acquire_provider(PROV_RSA_FULL);
		if (!CryptGenRandom(provider, int(buffer.size())
			, reinterpret_cast<BYTE*>(buffer.data())))
		{
			throw_ex<system_error>(error_code(GetLastError(), system_category()));
		}
	}
Пример #16
0
bool item::assign(bdecode_node const& v, span<char const> salt
	, sequence_number const seq, public_key const& pk, signature const& sig)
{
	TORRENT_ASSERT(v.data_section().size() <= 1000);
	if (!verify_mutable_item(v.data_section(), salt, seq, pk, sig))
		return false;
	m_pk = pk;
	m_sig = sig;
	if (salt.size() > 0)
		m_salt.assign(salt.data(), salt.size());
	else
		m_salt.clear();
	m_seq = seq;
	m_mutable = true;

	m_value = v;
	return true;
}
Пример #17
0
	allocation_slot stack_allocator::copy_buffer(span<char const> buf)
	{
		int const ret = int(m_storage.size());
		int const size = int(buf.size());
		if (size < 1) return {};
		m_storage.resize(ret + size);
		std::memcpy(&m_storage[ret], buf.data(), numeric_cast<std::size_t>(size));
		return allocation_slot(ret);
	}
Пример #18
0
	bool tracker_manager::incoming_packet(udp::endpoint const& ep
		, span<char const> const buf)
	{
		TORRENT_ASSERT(is_single_thread());
		// ignore packets smaller than 8 bytes
		if (buf.size() < 8)
		{
#ifndef TORRENT_DISABLE_LOGGING
			if (m_ses.should_log())
			{
				m_ses.session_log("incoming packet from %s, not a UDP tracker message "
					"(%d Bytes)", print_endpoint(ep).c_str(), int(buf.size()));
			}
#endif
			return false;
		}

		// the first word is the action, if it's not [0, 3]
		// it's not a valid udp tracker response
		span<const char> ptr = buf;
		std::uint32_t const action = aux::read_uint32(ptr);
		if (action > 3) return false;

		std::uint32_t const transaction = aux::read_uint32(ptr);
		auto const i = m_udp_conns.find(transaction);

		if (i == m_udp_conns.end())
		{
#ifndef TORRENT_DISABLE_LOGGING
			if (m_ses.should_log())
			{
				m_ses.session_log("incoming UDP tracker packet from %s has invalid "
					"transaction ID (%x)", print_endpoint(ep).c_str()
					, transaction);
			}
#endif
			return false;
		}

		std::shared_ptr<udp_tracker_connection> const p = i->second;
		// on_receive() may remove the tracker connection from the list
		return p->on_receive(ep, buf);
	}
Пример #19
0
		void update(span<char const> data)
		{
			if (CryptHashData(m_hash, reinterpret_cast<BYTE const*>(data.data()), int(data.size()), 0) == false)
			{
#ifndef BOOST_NO_EXCEPTIONS
				throw system_error(error_code(GetLastError(), system_category()));
#else
				std::terminate();
#endif
			}
		}
Пример #20
0
    void CopeOtExtSender::setBaseOts(span<block> baseRecvOts, const BitVector & choices)
    {
        if (baseRecvOts.size() != gOtExtBaseOtCount || choices.size() != gOtExtBaseOtCount)
            throw std::runtime_error("not supported/implemented");


        mBaseChoiceBits = choices;
        for (u64 i = 0; i < gOtExtBaseOtCount; i++)
        {
            mGens[i].SetSeed(baseRecvOts[i]);
        }
    }
Пример #21
0
void item::assign(entry v, span<char const> salt
	, sequence_number const seq
	, public_key const& pk, signature const& sig)
{

	m_pk = pk;
	m_sig = sig;
	m_salt.assign(salt.data(), salt.size());
	m_seq = seq;
	m_mutable = true;
	m_value = std::move(v);
}
Пример #22
0
	inline void crypt_gen_random(span<char> buffer)
	{
		static HCRYPTPROV provider = crypt_acquire_provider(PROV_RSA_FULL);
		if (!CryptGenRandom(provider, int(buffer.size())
			, reinterpret_cast<BYTE*>(buffer.data())))
		{
#ifndef BOOST_NO_EXCEPTIONS
			throw system_error(error_code(GetLastError(), system_category()));
#else
			std::terminate();
#endif
		}
	}
Пример #23
0
    void CopeOtExtReceiver::setBaseOts(span<std::array<block, 2>> baseOTs)
    {
        if (baseOTs.size() != gOtExtBaseOtCount)
            throw std::runtime_error(LOCATION);

        for (u64 i = 0; i < gOtExtBaseOtCount; i++)
        {
            mGens[i][0].SetSeed(baseOTs[i][0]);
            mGens[i][1].SetSeed(baseOTs[i][1]);
        }


        mHasBase = true;
    }
Пример #24
0
void item::assign(entry v, span<char const> salt
	, sequence_number const seq, public_key const& pk, secret_key const& sk)
{
	char buffer[1000];
	int bsize = bencode(buffer, v);
	TORRENT_ASSERT(bsize <= 1000);
	m_sig = sign_mutable_item(span<char const>(buffer, bsize)
		, salt, seq, pk, sk);
	m_salt.assign(salt.data(), salt.size());
	m_pk = pk;
	m_seq = seq;
	m_mutable = true;
	m_value = std::move(v);
}
Пример #25
0
	// this has to be thread safe and atomic. i.e. on posix systems it has to be
	// turned into a series of pread() calls
	std::int64_t file::readv(std::int64_t file_offset, span<iovec_t const> bufs
		, error_code& ec, open_mode_t flags)
	{
		if (m_file_handle == INVALID_HANDLE_VALUE)
		{
#ifdef TORRENT_WINDOWS
			ec = error_code(ERROR_INVALID_HANDLE, system_category());
#else
			ec = error_code(boost::system::errc::bad_file_descriptor, generic_category());
#endif
			return -1;
		}
		TORRENT_ASSERT((m_open_mode & open_mode::rw_mask) == open_mode::read_only
			|| (m_open_mode & open_mode::rw_mask) == open_mode::read_write);
		TORRENT_ASSERT(!bufs.empty());
		TORRENT_ASSERT(is_open());

#if TORRENT_USE_PREADV
		TORRENT_UNUSED(flags);
		std::int64_t ret = iov(&::preadv, native_handle(), file_offset, bufs, ec);
#else

		// there's no point in coalescing single buffer writes
		if (bufs.size() == 1)
		{
			flags &= ~open_mode::coalesce_buffers;
		}

		iovec_t tmp;
		span<iovec_t const> tmp_bufs = bufs;
		if (flags & open_mode::coalesce_buffers)
		{
			if (!coalesce_read_buffers(tmp_bufs, tmp))
				// ok, that failed, don't coalesce this read
				flags &= ~open_mode::coalesce_buffers;
		}

#if TORRENT_USE_PREAD
		std::int64_t ret = iov(&::pread, native_handle(), file_offset, tmp_bufs, ec);
#else
		std::int64_t ret = iov(&::read, native_handle(), file_offset, tmp_bufs, ec);
#endif

		if (flags & open_mode::coalesce_buffers)
			coalesce_read_buffers_end(bufs
				, tmp.data(), !ec);

#endif
		return ret;
	}
Пример #26
0
void GLVertexBuffer::setVertexAttributes(span<const VertexAttribute> a_attributes)
{
	assert(GLStateBuffer::isBegun());
	assert(m_initialized);
	assert(!a_attributes.empty());

	uint64 offset = 0;
	uint stride = 0;

	if (a_attributes.size() == 1)
		stride = 0;
	else
	{
		for (uint i = 0; i < a_attributes.size(); ++i)
		{
			const VertexAttribute& attribute = a_attributes[i];
			stride += attribute.numElements * (attribute.format == VertexAttribute::EFormat::UNSIGNED_BYTE ? 1 : 4);
		}
	}

	for (uint i = 0; i < a_attributes.size(); ++i)
	{
		const VertexAttribute& attribute = a_attributes[i];
		const bool isFloatType = (attribute.format == VertexAttribute::EFormat::FLOAT) || attribute.normalize;
		const uint dataSize = ((attribute.format == VertexAttribute::EFormat::UNSIGNED_BYTE) ? 1 : 4) * attribute.numElements;

		glBindBuffer(GLenum(m_bufferType), m_id);

		if (isFloatType)
			glVertexAttribPointer(attribute.attributeIndex, attribute.numElements, GLenum(attribute.format), attribute.normalize, stride, rcast<GLvoid*>(offset));
		else
			glVertexAttribIPointer(attribute.attributeIndex, attribute.numElements, GLenum(attribute.format), stride, rcast<GLvoid*>(offset));

		glEnableVertexAttribArray(attribute.attributeIndex);
		offset += dataSize;
	}
}
Пример #27
0
	int count_trailing_ones_sw(span<std::uint32_t const> buf)
	{
		auto const num = int(buf.size());
		std::uint32_t const* ptr = buf.data();

		TORRENT_ASSERT(num >= 0);
		TORRENT_ASSERT(ptr != nullptr);

		for (int i = num - 1; i >= 0; i--)
		{
			if (ptr[i] == 0xffffffff) continue;
			std::uint32_t v = ~aux::network_to_host(ptr[i]);

			for (int k = 0; k < 32; ++k, v >>= 1)
			{
				if ((v & 1) == 0) continue;
				return (num - i - 1) * 32 + k;
			}
		}

		return num * 32;
	}
Пример #28
0
	DecodedImage DecodeFontArt(const span<uint8_t> data) {

		// 256x256 image with 8bit alpha
		Expects(data.size() == 256 * 256);

		DecodedImage result;
		result.info.width = 256;
		result.info.height = 256;
		result.info.format = ImageFileFormat::FNTART;
		result.info.hasAlpha = true;
		result.data = std::make_unique<uint8_t[]>(256 * 256 * 4);

		auto *dest = result.data.get();
		for (auto alpha : data) {			
			*dest++ = 0xFF;
			*dest++ = 0xFF;
			*dest++ = 0xFF;
			*dest++ = alpha;
		}

		return result;

	}
Пример #29
0
inline
void write_and_pad_program_source_header(
	std::ostream& output,
	program_source_header& header,
	const span<const span_size_t>& shader_source_lengths,
	span_size_t& spos
)
{
	using eagine::memory::is_aligned_as;
	while(!is_aligned_as<program_source_header>(spos)) {
		output.put('\0');
		++spos;
	}

	const span_size_t size = 48;
	span_size_t done = 0;
	assert(size >= span_size(sizeof(shader_source_header)));

	eagine::memory::const_address hdraddr(&header);

	header.shader_sources.reset(
		hdraddr+std::ptrdiff_t(size),
		span_size_t(shader_source_lengths.size()) // shader count
	);

	output.write(static_cast<const char*>(hdraddr), sizeof(header));
	spos += sizeof(header);
	done += sizeof(header);

	while(done < size)
	{
		output.put('\0');
		++spos;
		++done;
	}

	span_size_t algn = alignof(shader_source_header);
	std::ptrdiff_t offs =
		std::ptrdiff_t(shader_source_lengths.size())*
		std::ptrdiff_t(sizeof(std::ptrdiff_t));

	if(offs % 16 != 0)
	{
		offs += 16 - (offs % 16);
	}

	for(span_size_t len : shader_source_lengths)
	{
		output.write(
			reinterpret_cast<const char*>(&offs),
			std::streamsize(sizeof(offs))
		);
		spos += sizeof(offs);
		done += sizeof(offs);

		// if changing this also change size
		// in write_and_pad_shader_source_header
		span_size_t shader_block_size = 48;
		shader_block_size += len;

		if(span_size_t misalign = shader_block_size % algn)
		{
			shader_block_size += (algn - misalign);
		}

		offs += std::ptrdiff_t(shader_block_size);
		offs -= std::ptrdiff_t(sizeof(std::ptrdiff_t));
	}

	while(spos % 16 != 0)
	{
		output.put('\0');
		++spos;
	}
}
Пример #30
0
    void CopeOtExtSender::send(
        span<ZpNumber> messages,
        Channel& chl)
    {
        auto fieldSize = messages[0].mField->bitCount();

        // round up
        u64 numOtExt = roundUpTo(messages.size() * fieldSize, 128);
        u64 numSuperBlocks = (numOtExt / 128 + copeSuperBlkSize - 1) / copeSuperBlkSize;
        //u64 numBlocks = numSuperBlocks * copeSuperBlkSize;

        // a uNum that will be used to transpose the sender's matrix
        std::array<block, copeSuperBlkSize> t;
        std::vector<std::array<block, copeSuperBlkSize>> u(128 * copeCommStepSize);

        //std::array<block, 128> choiceMask;
        block delta = *(block*)mBaseChoiceBits.data();

        //for (u64 i = 0; i < 128; ++i)
        //{
        //    if (mBaseChoiceBits[i]) choiceMask[i] = AllOneBlock;
        //    else choiceMask[i] = ZeroBlock;
        //}


        auto* mIter = messages.data();

        block * uIter = (block*)u.data() + copeSuperBlkSize * 128 * copeCommStepSize;
        block * uEnd = uIter;

        ZpField field;
        field.setParameters(ZpParam128);

        std::vector<ZpNumber> g;
        //qq.reserve(copeSuperBlkSize * field.bitCount());
        //for (u64 i = 0; i < copeSuperBlkSize * field.bitCount(); ++i)
        //    qq.emplace_back(field);

        std::cout << IoStream::lock;
        g.reserve(field.bitCount());
        for (u64 i = 0; i < field.bitCount(); ++i)
        {
            g.emplace_back(field, 2);
            g[i].powEq(i);
            std::cout << "g[" << i << "] " << g[i] << std::endl;
        }

        std::cout << IoStream::unlock;

        std::array<ZpNumber, copeSuperBlkSize> q
         {
            ZpNumber(field),ZpNumber(field),ZpNumber(field),ZpNumber(field),
            ZpNumber(field), ZpNumber(field), ZpNumber(field), ZpNumber(field)
        };

        ZpNumber uNum(field);

        for (u64 superBlkIdx = 0; superBlkIdx < numSuperBlocks; ++superBlkIdx)
        {

            if (uIter == uEnd)
            {
                u64 step = std::min<u64>(numSuperBlocks - superBlkIdx, (u64)copeCommStepSize);
                chl.recv((u8*)u.data(), step * copeSuperBlkSize * 128 * sizeof(block));
                uIter = (block*)u.data();
            }

            for (u64 j = 0; j < copeSuperBlkSize; ++j)
            {
                //qq[j] = 0;
                mIter[j] = 0;
            }
            std::cout << IoStream::lock;

            // transpose 128 columns at at time. Each column will be 128 * copeSuperBlkSize = 1024 bits long.
            for (u64 colIdx = 0; colIdx < 128; ++colIdx)
            {
                // generate the columns using AES-NI in counter mode.
                mGens[colIdx].mAes.ecbEncCounterMode(mGens[colIdx].mBlockIdx, copeSuperBlkSize, t.data());
                mGens[colIdx].mBlockIdx += copeSuperBlkSize;

                for (u64 i = 0; i < copeSuperBlkSize; ++i)
                {
                    q[i].fromBytes((u8*)&t[i]);
                }

                if (this->mBaseChoiceBits[colIdx])
                {
                    for (u64 i = 0; i < copeSuperBlkSize; ++i)
                    {
                        uNum.fromBytes((u8*)&uIter[i]);
                        q[i] -= uNum;
                    }
                }



                for (u64 i = 0; i < copeSuperBlkSize; ++i)
                {
                    //std::cout <<  (mBaseChoiceBits[colIdx]? "t0x" : "t0 ") <<"[" << i << "][" << colIdx << "] = " << q[i] <<"   " << mBaseChoiceBits[colIdx] << "\n\n"<<std::endl;
                    std::cout << "q[" << colIdx << "][" << i << "] = " << q[i] << std::endl;
                    q[i] *= g[colIdx];

                    mIter[i] += q[i];
                }

                uIter += 8;
            }
            std::cout << IoStream::unlock;

            mIter += 8;

        }


        static_assert(gOtExtBaseOtCount == 128, "expecting 128");
    }