/* * This file is part of Codecrypt. * * Codecrypt is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at * your option) any later version. * * Codecrypt is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Codecrypt. If not, see . */ #include "fwht.h" #include using namespace std; /* * we count on that all integers are sufficiently large. * They should be, largest value occuring should be O(k*n) if initial vector is * consisted only from {0,1}^n, and we don't usually have codes of this size. */ static void fwht (vector x, vector&r) { int bs, s; s = x.size(); r.resize (s); bs = s >> 1; r.swap (x); while (bs) { x.swap (r); for (uint i = 0; i < s; ++i) { if ( (i / bs) & 1) r[i] = x[i - bs] - x[i]; else r[i] = x[i] + x[i + bs]; } bs >>= 1; } } //we expect correct parameter size and preallocated out. void fwht_dyadic_multiply (const bvector& a, const bvector& b, bvector& out) { //lift everyting to Z. vector t, A, B; uint i; t.resize (a.size() ); A.resize (a.size() ); B.resize (a.size() ); for (i = 0; i < a.size(); ++i) t[i] = a[i]; fwht (t, A); for (i = 0; i < b.size(); ++i) t[i] = b[i]; fwht (t, B); //multiply diagonals to A for (i = 0; i < A.size(); ++i) A[i] *= B[i]; fwht (A, t); uint bitpos = a.size(); //no problem as a.size() == 1<