diff --git a/bitvector.cc b/bitvector.cc index ca630ee..ca91541 100644 --- a/bitvector.cc +++ b/bitvector.cc @@ -296,12 +296,13 @@ return n; //NOTE: naive algorithm, just for testing //does not perform modulo irreducible polynomial, is NOT GF(2^n) multiplication -bitvector bitvector::operator*(const bitvector &rhs) const +bitvector bitvector::multiply(const bitvector &rhs, bool autoresize) const { -bitvector r(size()+rhs.size()); +int maxsize=size(); if(rhs.size()>maxsize) maxsize=rhs.size(); +bitvector r(autoresize?size()+rhs.size():maxsize); r.clear(); bitvector tmp(rhs); -tmp.resize(size()+rhs.size(),true); +if(autoresize) tmp.resize(size()+rhs.size(),true); for(int i=0; i<=degree(); ++i) { if((*this)[i]) r+= tmp; @@ -310,6 +311,60 @@ for(int i=0; i<=degree(); ++i) return r; } + +//this is GF(2^n) multiplication +bitvector bitvector::field_mult(const bitvector &rhs, const bitvector &irpolynom) const +{ +int d=irpolynom.degree(); +if(d>size()||d>rhs.size()) laerror("inconsistent dimensions in field_mult"); +bitvector r(size()); +r.clear(); +bitvector tmp(*this); +tmp.resize(size()+1,true); +int rd=rhs.degree(); +for(int i=0; i<=rd; ++i) //avoid making a working copy of rhs and shifting it + { + if(rhs[i]) r+= tmp; + tmp.leftshift(1,false); + if(tmp[d]) tmp -= irpolynom; + } +return r; +} + + + +//this is GF(2^n) multiplicative inverseion +//cf. https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm +bitvector bitvector::field_inv(const bitvector &irpolynom) const +{ +int d=irpolynom.degree(); +if(d>size()) laerror("inconsistent dimensions in field_inv"); + +bitvector t(size()); t.clear(); +bitvector newt(size()); newt.clear(); newt.set(0); +bitvector r(irpolynom); r.copyonwrite(); +bitvector newr(*this); if(r.size()>newr.size()) newr.resize(r.size(),true); newr.copyonwrite(); +int rs=r.size(); + + +while(!newr.is_zero()) + { + //std::cout <<"r "<0) laerror("field_inv: polynomial is not irreducible or input is its multiple"); +if(!r[0]) laerror("zero in field_inv"); + +return t; +} + + + void bitvector::resize(const unsigned int n, bool preserve) { int old=size(); @@ -338,9 +393,9 @@ while((d=remainder.degree()) >= rhsd) { unsigned int pos = d-rhsd; r.set(pos); - remainder -= (rhs<gcd(rhs);}; - unsigned int bitdiff(const bitvector &y) const; //number of differing bits + unsigned int bitdiff(const bitvector &y) const; //number of differing bits (Hamming distance) unsigned int population(const unsigned int before=0) const; //number of 1's unsigned int nlz() const; //number of leading zeroes unsigned int degree() const {if(iszero()) return 0; else return size()-nlz()-1;}; //interprested as a polynomial over GF(2) diff --git a/t.cc b/t.cc index a7308c2..7581412 100644 --- a/t.cc +++ b/t.cc @@ -2939,11 +2939,23 @@ if(!(u%g).is_zero()) laerror("error in gcd"); if(!(v%g).is_zero()) laerror("error in gcd"); } -if(1) +if(0) { uint64_t n; cin >>n; cout <