local a=require("nums.bn")local b={}local c={}local function d(e,f)local g=false;if not b.isuint(e)then e,f=f,e;g=true end;return e:copy(),a(f),g end;local function h(i)if i._bn==i._max then i._bn:set(0)elseif i._bn<0 or i._bn>i._max then i._bn=i._bn%i._max end end;c.__index=b;c.__add=function(e,f)local j;e,f,j=d(e,f)if j then e._bn=f+e._bn else e._bn=e._bn+f end;h(e)return e end;c.__sub=function(e,f)local j;e,f,j=d(e,f)if j then e._bn=f-e._bn else e._bn=e._bn-f end;h(e)return e end;c.__mul=function(e,f)e,f=d(e,f)e._bn=e._bn*f;h(e)return e end;c.__div=function(e,f)return e//f end;c.__mod=function(e,f)local j;e,f,j=d(e,f)if j then e._bn=f%e._bn else e._bn=e._bn%f end;h(e)return e end;c.__pow=function(e,f)local j;e,f,j=d(e,f)if j then e._bn=f^e._bn else e._bn=e._bn^f end;h(e)return e end;c.__unm=function(e)e=e:copy()e._bn=-e._bn;h(e)return e end;c.__idiv=function(e,f)local j;e,f,j=d(e,f)if j and f==0 then e._val=0;return e end;if j then e._bn=f//e._bn else e._bn=e._bn//f end;h(e)return e end;c.__band=function(e,f)e,f=d(e,f)e._bn=e._bn&f;h(e)return e end;c.__bor=function(e,f)e,f=d(e,f)e._bn=e._bn|f;h(e)return e end;c.__bxor=function(e,f)e,f=d(e,f)e._bn=e._bn~f;h(e)return e end;c.__bnot=function(e)e=e:copy()e._bn=~e._bn;h(e)return e end;c.__shl=function(e,f)local j;e,f,j=d(e,f)if j then e._bn=f<<e._bn else e._bn=e._bn<<f end;h(e)return e end;c.__shr=function(e,f)local j;e,f,j=d(e,f)if j then e._bn=f>>e._bn else e._bn=e._bn>>f end;h(e)return e end;c.__concat=function(e,f)if b.isuint(e)and b.isuint(f)then return e._bn..f._bn elseif b.isuint(e)and not b.isuint(f)then return e._bn..f end;return e..f._bn end;c.__len=function(e)return e._bits end;c.__eq=function(e,f)e,f=d(e,f)return e._bn==f end;c.__lt=function(e,f)local j;e,f,j=d(e,f)if j then return e._bn>f end;return e._bn<f end;c.__le=function(e,f)if e<f or e==f then return true end;return false end;c.__tostring=function(e)return tostring(e._bn)end;function b:new(k,l)local i=setmetatable({},c)if self~=b then return nil,"first argument must be self"end;if k==nil then return nil,"bits required"end;if b.isuint(k)then i._bits=k._bits;i._max=k._max;if l~=nil then i._bn=a(l)else i._bn=a(k._bn)end else i._bits=k;i._max=a(1)<<i._bits;if l~=nil then i._bn=a(l)else i._bn=a()end end;h(i)return i end;function b.isuint(m)if type(m)=="table"and getmetatable(m)==c then return true end;return false end;function b.u8(l)return b:new(8,l)end;function b.u16(l)return b:new(16,l)end;function b.u32(l)return b:new(32,l)end;function b.u64(l)return b:new(64,l)end;function b.u128(l)return b:new(128,l)end;function b.u256(l)return b:new(256,l)end;function b.u512(l)return b:new(512,l)end;function b:copy()return b:new(self._bits,self._bn)end;function b:set(l)if b.isuint(l)then self._bn=l._val else self._bn:set(l)end;h(self)end;function b:swape()local n;local l=a()local m;n=self:asbytearray()for o=1,#n//2 do m=n[o]n[o]=n[#n-o+1]n[#n-o+1]=m end;m={}for o=#n,1,-1 do m[#m+1]=n[o]end;for o=1,#m do l=l|(a(m[o])<<o*8-8)end;return b:new(self._bits,l)end;function b:asnumber()return self._bn:asnumber()end;function b:asbn()return self._bn:copy()end;function b:ashex(p)return self._bn:ashex(p)end;function b:asbytearray()local q;q=self._bn:asbytearray()for o=1,self._bits//8-#q do table.insert(q,1,0)end;return q end;function b:asbytestring()local f;f=self:asbytearray()for o=1,#f do f[o]=string.char(f[o])end;return table.concat(f)end;return b