-rw-r--r-- 4441 cryptattacktester-20230614/index.cpp raw
#include "bit_vector.h"
#include "index.h"
#include "sorting.h"
using namespace std;
bigint index_value(vector<bit> &v)
{
	bigint ret = 0;
	for (bigint i = 0; i < v.size(); i++)
		ret += v.at(i).value() << i; // XXX: takes only bottom bit from bitset
	return ret;
}
bit bit_vector_gt(vector<bit> &v,vector<bit> &w)
{
	bigint len = v.size();
	assert(len == w.size());
	bit ret;
	if (len <= 0) return ret;
	bigint i = len-1;
        ret = v.at(i).andn(w.at(i));
        if (i == 0) return ret;
        bit d = v.at(i) ^ w.at(i);
        for (;;) {
          --i;
          ret |= v.at(i).andn(w.at(i)).andn(d);
          if (i == 0) return ret;
          d |= v.at(i) ^ w.at(i);
        }
}
bit bit_vector_gt_rev(vector<bit> &v,vector<bit> &w)
{
	bigint len = v.size();
	assert(len == w.size());
	bit ret;
	if (len <= 0) return ret;
	bigint i = 0;
        ret = v.at(i).andn(w.at(i));
        if (i == len-1) return ret;
        bit d = v.at(i) ^ w.at(i);
        for (;;) {
          ++i;
          ret |= v.at(i).andn(w.at(i)).andn(d);
          if (i == len-1) return ret;
          d |= v.at(i) ^ w.at(i);
        }
}
vector<bit> bit_vector_add(vector<bit> &ret, vector<bit> a, vector<bit> b, bit c_in)
{
        if (b.size() > a.size())
        	return bit_vector_add(ret,b,a,c_in);
        assert(a.size()+1 >= ret.size());
        assert(ret.size() >= a.size());
        assert(a.size() >= b.size());
        bit c = c_in;
        for (bigint i = 0; i < b.size(); i++)
                full_adder(ret.at(i), c, a.at(i), b.at(i));
        for (bigint i = b.size(); i < a.size(); i++)
                half_adder(ret.at(i), c, a.at(i), c);
        if (a.size() < ret.size())
                ret.at(a.size()) = c;
        return ret;
}
vector<bit> bit_vector_hamming_weight(const vector<bit> &v)
{
        bigint n = v.size();
        bigint k = nbits(n) - 1;
        if (n == 0) return vector<bit> (0);
        if (n == 1) return vector<bit> (1, v.at(0));
        bigint x = 1;
        x <<= k;
        x -= 1;
        bigint y = n - x - 1;
        assert(n == x + y + 1);
        vector<bit> weight_x = bit_vector_hamming_weight(bit_vector_extract(v, 0, x));
        vector<bit> weight_y = bit_vector_hamming_weight(bit_vector_extract(v, x, x + y));
        vector<bit> ret(nbits(n));
        bit_vector_add(ret, weight_x, weight_y, v.back());
        return ret;
}
bit bit_vector_hamming_weight_isnot(const vector<bit> &v,bigint target)
{
  vector<bit> w = bit_vector_hamming_weight(v);
  assert(nbits(target) <= w.size());
  bit ret;
  // XXX: can speed up i=0
  for (bigint i = 0;i < w.size();++i)
    if (target.bit(i))
      ret = ret.orn(w.at(i));
    else
      ret |= w.at(i);
  return ret;
}
// merge with bit_matrix_sum_of_cols_viasorting
// note that for each i in indices, e[i] = 0 instead of 1
vector<bit> indices_to_vector(vector<vector<bit>> &indices, bigint n)
{
        vector<bit> e(0);
        bigint idx_size = indices.at(0).size();
        vector<vector<bit>> L;
        for (bigint i = 0; i < indices.size(); i++)
        {
                bigint j = indices.size()-1-i;
                vector<bit> v_j = bit_vector_from_integer(j, idx_size, 1);
                vector<bit> idx = indices.at(i);
                vector<bit> v(idx_size);
                bit_vector_add(v, v_j, idx, bit(1));
                v.insert(v.begin(), bit(0));
                L.push_back(v);
        }
        for (bigint i = 0; i < n; i++)
        {
                vector<bit> v = bit_vector_from_integer(i, idx_size);
                v.insert(v.begin(), bit(1));
                L.push_back(v);
        }
        sorting(L);
        for (bigint i = 0; i < n; i++)
                e.push_back(L.at(i).at(0));
        return e;
}
vector<bit> set_size(vector<vector<bit>> &set)
{
        bit b;
        vector<bit> v(set.size(), bit(1));
        sorting(set);
        for (bigint i = 0; i < set.size()-1; i++)
        {
                b = v.at(i+0) & v.at(i+1);
                b = b.andn(bit_vector_compare(set.at(i+0), set.at(i+1)));
                v.at(i+0) ^= b;
                v.at(i+1) ^= b;
        }
        return bit_vector_hamming_weight(v);
}
bit set_size_check(vector<vector<bit>> &set, bigint w)
{
        vector<bit> w_set = set_size(set);
        vector<bit> w_vec = bit_vector_from_integer(w);
        bit ret = ~bit_vector_integer_compare(w_set, w_vec);
        return ret;
}