#include #include "gf28.h" using namespace std; int GF28::reduce(int v,int m){ assert(m); while(true){ int sh=__builtin_clz(m)-__builtin_clz(v); if(sh<0)break; v^=m<>=1; } return res; } GF28::GF28() :value(0){} GF28::GF28(int v) :value(reduce(v,modulus)){} GF28::operator uint8_t() const { return value; } GF28& GF28::operator+=(GF28 o){ value^=o.value; return *this; } GF28& GF28::operator-=(GF28 o){ value^=o.value; return *this; } GF28& GF28::operator<<=(int n){ //multiplication by x^n assert(n>=0); value<<=n; if(value&0x100)value^=modulus; return *this; } GF28 GF28::operator+(GF28 o) const { return GF28(value^o.value); } GF28 GF28::operator-(GF28 o) const { return GF28(value^o.value); } GF28 GF28::operator*(GF28 o) const { if(value==0||o.value==0)return GF28(0); GF28 res; GF28 addend(*this); while(o.value){ if(o.value&1)res+=addend; addend<<=1; o.value>>=1; } return res; } GF28 GF28::operator<<(int n) const { return GF28(*this)<<=n; } bool GF28::operator==(GF28 o) const { return value==o.value; } GF28 GF28::inverse() const { if(value==0)return *this; int x=1,y=0,x2=0,y2=1,r=modulus,r2=value; while(r2!=0){ assert(r!=0); int ex=__builtin_clz(r2)-__builtin_clz(r); if(ex<0){ swap(x,x2); swap(y,y2); swap(r,r2); } else { int xn=x^(x2<>=1,i--){ if(p.value&m){ if(!first)os<<'+'; first=false; if(i==0)os<<'1'; else os<<"x^"<