-
-
Save cyberbit/d82459efff745d04f6afbd37e3130546 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local e={}local t,a,o=require,{},{startup=e} | |
local function i(n)local s=o[n] | |
if s~=nil then if s==e then | |
error("loop or previous error loading module '"..n.. | |
"'",2)end;return s end;o[n]=e;local h=a[n]if h then s=h(n)elseif t then s=t(n)else | |
error("cannot load '"..n.."'",2)end;if s==nil then s=true end;o[n]=s;return s end | |
a["ecnet.util"]=function(...) | |
local n={__tostring=function(r)return string.char(unpack(r))end,__index={toHex=function(r)return("%02x"):rep( | |
#r):format(unpack(r))end,isEqual=function(r,d)if | |
type(d)~="table"then return false end;if#r~=#d then return false end;local l=0 | |
for u=1, | |
#r do l=bit32.bor(l,bit32.bxor(r[u],d[u]))end;return l==0 end}} | |
local function s(r,d)local l=fs.open(r,"wb")l.write(d)l.close()end | |
local function h(r)local d=fs.open(r,"rb")local l=d.readAll()d.close()return l end;return{byteTableMT=n,saveFile=s,loadFile=h}end | |
a["ecnet.symmetric.siphash"]=function(...)local n=i("ecnet.util")local s=bit32.bxor | |
local h=bit32.band;local r=bit32.rshift;local d=n.byteTableMT;local function l(f)local m=#f | |
while(#f%8 ~=7)do f[#f+1]=0 end;f[#f+1]=m%256 end | |
local function u(m,f,w,y,p,v,b,g)local k,q;m=m+w;f=(f+y+ (m> | |
0xffffffff and 1 or 0))% | |
0x100000000;m=m%0x100000000;p=p+b;v= | |
( | |
v+g+ (p>0xffffffff and 1 or 0))%0x100000000;p=p%0x100000000;k= | |
h(w,0xfff80000)/0x80000;q=h(y,0xfff80000)/0x80000;w= | |
w*0x2000+q;y=y*0x2000+k;k=h(b,0xffff0000)/0x10000;q= | |
h(g,0xffff0000)/0x10000;b=b*0x10000+q;g=g*0x10000+k | |
w=s(w,m)y=s(y,f)b=s(b,p)g=s(g,v)m,f=f,m;p=p+w | |
v=(v+y+ | |
(p>0xffffffff and 1 or 0))%0x100000000;p=p%0x100000000;m=m+b;f= | |
(f+g+ (m>0xffffffff and 1 or 0))%0x100000000;m=m%0x100000000;k= | |
h(w,0xffff8000)/0x8000;q=h(y,0xffff8000)/0x8000;w= | |
w*0x20000+q;y=y*0x20000+k;k=h(b,0xfffff800)/0x800;q= | |
h(g,0xfffff800)/0x800;b=b*0x200000+q;g=g*0x200000+k | |
w=s(w,p)y=s(y,v)b=s(b,m)g=s(g,f)p,v=v,p;return m,f,w,y,p,v,b,g end | |
local function c(m,f) | |
local w=type(f)=="table"and | |
{string.char(unpack(f)):byte(1,-1)}or{tostring(f):byte(1,-1)} | |
local y=type(m)=="table"and | |
{string.char(unpack(m)):byte(1,-1)}or{tostring(m):byte(1,-1)} | |
assert(#w==16,"SipHash: Invalid key length ("..#w.."), must be 16")l(y) | |
local p=s(w[1],w[2]*0x100,w[3]*0x10000,w[4]*0x1000000,0x70736575) | |
local v=s(w[5],w[6]*0x100,w[7]*0x10000,w[8]*0x1000000,0x736f6d65) | |
local b=s(w[9],w[10]*0x100,w[11]*0x10000,w[12]*0x1000000,0x6e646f6d) | |
local g=s(w[13],w[14]*0x100,w[15]*0x10000,w[16]*0x1000000,0x646f7261) | |
local k=s(w[1],w[2]*0x100,w[3]*0x10000,w[4]*0x1000000,0x6e657261) | |
local q=s(w[5],w[6]*0x100,w[7]*0x10000,w[8]*0x1000000,0x6c796765) | |
local j=s(w[9],w[10]*0x100,w[11]*0x10000,w[12]*0x1000000,0x79746573) | |
local x=s(w[13],w[14]*0x100,w[15]*0x10000,w[16]*0x1000000,0x74656462) | |
for T=1,#y,8 do | |
j=s(y[T],y[T+1]*0x100,y[T+2]*0x10000,y[T+3]*0x1000000,j) | |
x=s(y[T+4],y[T+5]*0x100,y[T+6]*0x10000,y[T+7]*0x1000000,x)p,v,b,g,k,q,j,x=u(p,v,b,g,k,q,j,x)p,v,b,g,k,q,j,x=u(p,v,b,g,k,q,j,x) | |
p=s(y[T], | |
y[T+1]*0x100,y[T+2]*0x10000,y[T+3]*0x1000000,p) | |
v=s(y[T+4],y[T+5]*0x100,y[T+6]*0x10000,y[T+7]*0x1000000,v) | |
if T%64000 ==0 then os.queueEvent("")os.pullEvent("")end end;k=s(k,0xff)p,v,b,g,k,q,j,x=u(p,v,b,g,k,q,j,x) | |
p,v,b,g,k,q,j,x=u(p,v,b,g,k,q,j,x)p,v,b,g,k,q,j,x=u(p,v,b,g,k,q,j,x)p,v,b,g,k,q,j,x=u(p,v,b,g,k,q,j,x) | |
local z=s(p,b,k,j)local _=s(v,g,q,x) | |
local E={r(_,24)%256,r(_,16)%256,r(_,8)%256,_%256,r(z,24)%256,r(z,16)% | |
256,r(z,8)%256,z%256}return setmetatable(E,d)end;return{mac=c}end | |
a["ecnet.symmetric.sha256"]=function(...)local n=i("ecnet.util")local s=_G.bit;local h=2^32;local r=bit32 and | |
bit32.band or s.band | |
local d=bit32 and bit32.bnot or s.bnot;local l=bit32 and bit32.bxor or s.bxor;local u= | |
bit32 and bit32.lshift or s.blshift | |
local c=unpack or table.unpack;local m=n.byteTableMT | |
local function f(_,E)local T=_/ (2^E)local A=T%1;return(T-A)+A*h end;local function w(_,E)local T=_/ (2^E)return T-T%1 end | |
local y={0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19} | |
local p={0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2} | |
local function v(_)local E,T=0,0;if 0xFFFFFFFF-E<_ then T=T+1 | |
E=_- (0xFFFFFFFF-E)-1 else E=E+_ end;return T,E end | |
local function b(_,E)return | |
u((_[E]or 0),24)+u((_[E+1]or 0),16)+ | |
u((_[E+2]or 0),8)+ (_[E+3]or 0)end | |
local function g(_)local E=#_;local T={}_[#_+1]=0x80;while#_%64 ~=56 do _[#_+1]=0 end;local A=math.ceil(# | |
_/64) | |
for O=1,A do T[O]={}for I=1,16 do T[O][I]=b(_,1+ ((O-1)*64)+ | |
((I-1)*4))end end;T[A][15],T[A][16]=v(E*8)return T end | |
local function k(_,E) | |
for D=17,64 do | |
local L=l(l(f(_[D-15],7),f(_[D-15],18)),w(_[D-15],3)) | |
local U=l(l(f(_[D-2],17),f(_[D-2],19)),w(_[D-2],10))_[D]=(_[D-16]+L+_[D-7]+U)%h end;local T,A,O,I,N,S,H,R=c(E) | |
for D=1,64 do local L=l(l(f(N,6),f(N,11)),f(N,25)) | |
local U=l(r(N,S),r(d(N),H))local C=(R+L+U+p[D]+_[D])%h | |
local M=l(l(f(T,2),f(T,13)),f(T,22))local F=l(l(r(T,A),r(T,O)),r(A,O))local W=(M+F)%h;R,H,S,N,I,O,A,T=H,S,N,(I+ | |
C)%h,O,A,T,(C+W)%h end;E[1]=(E[1]+T)%h;E[2]=(E[2]+A)%h | |
E[3]=(E[3]+O)%h;E[4]=(E[4]+I)%h;E[5]=(E[5]+N)%h | |
E[6]=(E[6]+S)%h;E[7]=(E[7]+H)%h;E[8]=(E[8]+R)%h;return E end | |
local function q(_,E)local T={}for A=1,E do T[(A-1)*4+1]=r(w(_[A],24),0xFF) | |
T[(A-1)*4+2]=r(w(_[A],16),0xFF)T[(A-1)*4+3]=r(w(_[A],8),0xFF) | |
T[(A-1)*4+4]=r(_[A],0xFF)end;return | |
setmetatable(T,m)end | |
local function j(_)_=_ or""_=type(_)=="table"and{c(_)}or | |
{tostring(_):byte(1,-1)}_=g(_)local E={c(y)}for T=1,#_ do | |
E=k(_[T],E)end;return q(E,8)end | |
local function x(_,E)_=type(_)=="table"and{c(_)}or | |
{tostring(_):byte(1,-1)} | |
E=type(E)=="table"and | |
{c(E)}or{tostring(E):byte(1,-1)}local T=64;E=#E>T and j(E)or E;local A={}local O={}local I={}for N=1,T do | |
A[N]=l(0x36,E[N]or 0)O[N]=l(0x5C,E[N]or 0)end;for N=1,#_ do | |
A[T+N]=_[N]end;A=j(A)for N=1,T do I[N]=O[N]I[T+N]=A[N]end;return j(I)end | |
local function z(_,E,T,A) | |
E=type(E)=="table"and E or{tostring(E):byte(1,-1)}local O=32;A=A or 32;local I=1;local N={} | |
while A>0 do local S={}local H={c(E)}local R=A>O and O or A;H[# | |
H+1]=r(w(I,24),0xFF)H[#H+1]=r(w(I,16),0xFF) | |
H[#H+1]=r(w(I,8),0xFF)H[#H+1]=r(I,0xFF) | |
for D=1,T do H=x(H,_) | |
for L=1,R do S[L]=l(H[L],S[L]or 0)end;if D%200 ==0 then os.queueEvent("PBKDF2",D) | |
coroutine.yield("PBKDF2")end end;A=A-R;I=I+1;for D=1,R do N[#N+1]=S[D]end end;return setmetatable(N,m)end;return{digest=j,hmac=x,pbkdf2=z}end | |
a["ecnet.symmetric.random"]=function(...)local n=i("ecnet.symmetric.sha256") | |
local s=""local h=""local r="/.random"local function d(p)h=h.. (p or"")end;local function l() | |
s=tostring(n.digest(s..h))h=""end;if fs.exists(r)then local p=fs.open(r,"rb") | |
d(p.readAll())p.close()end;local u=os.epoch("utc") | |
local c=u;local m=1;d("init") | |
d(tostring(math.random(1,2^31-1)))d("|") | |
d(tostring(math.random(1,2^31-1)))d("|") | |
d(tostring(math.random(1,2^4)))d("|")d(tostring(u))d("|") | |
while(c-u<500)or(m<10000)do | |
c=os.epoch("utc")local p=tostring({}):sub(8)while#p<8 do p="0"..p end;d(string.char( | |
c%256)) | |
d(string.char(tonumber(p:sub(1,2),16))) | |
d(string.char(tonumber(p:sub(3,4),16))) | |
d(string.char(tonumber(p:sub(5,6),16))) | |
d(string.char(tonumber(p:sub(7,8),16)))m=m+1 end;l()d(tostring(os.epoch("utc")))l() | |
local function f() | |
d("save")d(tostring(os.epoch("utc"))) | |
d(tostring({}))l()local p=fs.open(r,"wb") | |
p.write(tostring(n.hmac("save",s)))s=tostring(n.digest(s))p.close()end;f() | |
local function w(p)d("seed") | |
d(tostring(os.epoch("utc")))d(tostring({}))d(p)l()f()end;local function y()d("random") | |
d(tostring(os.epoch("utc")))d(tostring({}))l()f()local p=n.hmac("out",s) | |
s=tostring(n.digest(s))return p end;return | |
{seed=w,save=f,random=y}end | |
a["ecnet.symmetric.chacha20"]=function(...)local n=i("ecnet.util")local s=bit32.bxor | |
local h=bit32.band;local r=bit32.lshift;local d=bit32.arshift;local l=_G.textutils;local u=n.byteTableMT | |
local c=2^32 | |
local m={("expand 16-byte k"):byte(1,-1)} | |
local f={("expand 32-byte k"):byte(1,-1)} | |
local function w(q,j)local x=q/ (2^ (32-j))local z=x%1;return(x-z)+z*c end | |
local function y(q,j,x,z,_)q[j]=(q[j]+q[x])%c;q[_]=w(s(q[_],q[j]),16)q[z]=( | |
q[z]+q[_])%c;q[x]=w(s(q[x],q[z]),12)q[j]=(q[j]+ | |
q[x])%c;q[_]=w(s(q[_],q[j]),8)q[z]= | |
(q[z]+q[_])%c;q[x]=w(s(q[x],q[z]),7)return q end | |
local function p(q,j)local x={table.unpack(q)} | |
for z=1,j do local _=z%2 ==1;x=_ and y(x,1,5,9,13)or | |
y(x,1,6,11,16) | |
x=_ and y(x,2,6,10,14)or y(x,2,7,12,13)x=_ and y(x,3,7,11,15)or y(x,3,8,9,14)x=_ and | |
y(x,4,8,12,16)or y(x,4,5,10,15)end;for z=1,16 do x[z]=(x[z]+q[z])%c end;return x end | |
local function v(q,j)return | |
(q[j+1]or 0)+r((q[j+2]or 0),8)+ | |
r((q[j+3]or 0),16)+r((q[j+4]or 0),24)end | |
local function b(q,j,x)local z=#q==32;local _=z and f or m;local E={}E[1]=v(_,0)E[2]=v(_,4) | |
E[3]=v(_,8)E[4]=v(_,12)E[5]=v(q,0)E[6]=v(q,4)E[7]=v(q,8)E[8]=v(q,12)E[9]=v(q, | |
z and 16 or 0)E[10]=v(q,z and 20 or 4)E[11]=v(q, | |
z and 24 or 8)E[12]=v(q,z and 28 or 12) | |
E[13]=x;E[14]=v(j,0)E[15]=v(j,4)E[16]=v(j,8)return E end | |
local function g(q)local j={}for x=1,16 do j[#j+1]=h(q[x],0xFF) | |
j[#j+1]=h(d(q[x],8),0xFF)j[#j+1]=h(d(q[x],16),0xFF) | |
j[#j+1]=h(d(q[x],24),0xFF)end;return j end | |
local function k(q,j,x,z,_) | |
assert(type(j)=="table","ChaCha20: Invalid key format ("..type(j).."), must be table") | |
assert(type(x)=="table","ChaCha20: Invalid nonce format ("..type(x).."), must be table") | |
assert(#j==16 or#j==32,"ChaCha20: Invalid key length ("..#j.."), must be 16 or 32") | |
assert(#x==12,"ChaCha20: Invalid nonce length ("..#x.."), must be 12") | |
q=type(q)=="table"and{table.unpack(q)}or{tostring(q):byte(1, | |
-1)}z=tonumber(z)or 1;_=tonumber(_)or 20;local E={} | |
local T=b(j,x,z)local A=math.floor(#q/64) | |
for O=0,A do local I=g(p(T,_)) | |
T[13]=(T[13]+1)%c;local N={}for S=1,64 do N[S]=q[((O)*64)+S]end;for S=1,#N do | |
E[#E+1]=s(N[S],I[S])end;if O%1000 ==0 then os.queueEvent("") | |
os.pullEvent("")end end;return setmetatable(E,u)end;return{crypt=k}end | |
a["ecnet.symmetric.aecrypt"]=function(...)local n=i("ecnet.symmetric.chacha20") | |
local s=i("ecnet.symmetric.sha256")local h=i("ecnet.symmetric.siphash") | |
local r=i("ecnet.symmetric.random")local d=i("ecnet.util")local l=d.byteTableMT | |
local function u()local f={} | |
local w=os.epoch("utc")for y=1,7 do f[#f+1]=w%256;w=w/256;w=w-w%1 end;for y=8,12 do | |
f[y]=math.random(0,255)end;return f end | |
local function c(f,w,y)local p=u()local v=n.crypt(f,w,p,1,8)local b=p;for k=1,#v do b[#b+1]=v[k]end | |
local g=h.mac(b,{unpack(y,1,16)})for k=1,#g do b[#b+1]=g[k]end;return setmetatable(b,l)end | |
local function m(f,w,y)local f=type(f)=="table"and{unpack(f)}or | |
{tostring(f):byte(1,-1)} | |
local p=h.mac({unpack(f,1,#f-8)},{unpack(y,1,16)})local v={unpack(f,#f-7)}local b={unpack(f,13,#f-8)} | |
assert(p:isEqual(v),"invalid mac")local g={unpack(f,1,12)}local k=n.crypt(b,w,g,1,8)return | |
setmetatable(k,l)end;return{encrypt=c,decrypt=m}end | |
a["ecnet.ecnet"]=function(...)local n=i("ecnet.util")local s=i("ecnet.cbor") | |
local h=i("ecnet.symmetric.sha256")local r=i("ecnet.symmetric.chacha20") | |
local d=i("ecnet.symmetric.siphash")local l=i("ecnet.symmetric.aecrypt") | |
local u=i("ecnet.symmetric.random")local c=i("ecnet.ecc.ecc")local m=33635;local f="/.ecnet-secretseed" | |
local w=os.epoch("utc")local y={}local p=false | |
local function v(L)local U=h.digest(L)local C=U:toHex()local M="" | |
M=M..C:sub(1,4)M=M..":"M=M..C:sub(5,8)M=M..":"M=M..C:sub(9,12) | |
M=M..":"M=M..C:sub(13,16)M=M..":"M=M..C:sub(17,20)return M end;if not fs.exists(f)then local L=u.random() | |
L=string.char(unpack(L))n.saveFile(f,L)end | |
local b=n.loadFile(f)local g,k=c.keypair(b)local q=v(k) | |
local function j(L,U) | |
local C={type="addressRequest",from=q,to=U}L.transmit(m,m,C)local M={otherAddress=U}return M end | |
local function x(L,U)local C=v(U)local M | |
if y[C]then M=y[C].sharedSecret else M=c.exchange(g,U)end;local F,W=c.keypair()local Y=h.hmac("senderTagKey",M) | |
local P=os.epoch("utc")local V=h.hmac(tostring(W)..tostring(P),Y) | |
local B={type="connectionRequest",from=q,to=C,publicKey=tostring(k),ephemeralPublicKey=tostring(W),tag=tostring(V):sub(1,10),counter=P}L.transmit(m,m,B) | |
local G={ephemeralSecretKey=tostring(F),sharedSecret=M,otherAddress=C}return G end | |
local function z(L,U)local C=U.from | |
local M={type="addressResponse",from=q,to=C,publicKey=tostring(k)}L.transmit(m,m,M)end | |
local function _(L,U)local C=U.from;local M=U.publicKey;assert(L.otherAddress==C)assert( | |
type(M)=="string"and#M==22) | |
assert(v(M)==C)return M end | |
local function E(L,U)local C=U.publicKey;local M=U.ephemeralPublicKey;local F=U.from;local W=U.tag;local Y=U.counter;assert( | |
type(C)=="string"and#C==22)assert( | |
type(M)=="string")assert(#M==22) | |
assert(v(C)==F)assert(type(W)=="string"and#W==10)assert( | |
type(Y)=="number")if y[F]then | |
assert(Y>y[F].counter)else assert(Y>w)end;local P;if y[F]then P=y[F].sharedSecret else | |
P=c.exchange(g,C)end;local V,B=c.keypair()local G=c.exchange(V,M) | |
local K=h.hmac(G,P)local Q=h.hmac("senderEncryptionKey",K) | |
local J={unpack(h.hmac("senderMacKey",K),1,16)}local X=h.hmac("receiverEncryptionKey",K) | |
local Z={unpack(h.hmac("receiverMacKey",K),1,16)}local ee=h.hmac("senderTagKey",P) | |
local et=h.hmac("receiverTagKey",K) | |
assert( | |
tostring(h.hmac(M..tostring(Y),ee)):sub(1,10)==W)local Y=os.epoch("utc") | |
local ea=h.hmac(tostring(B)..tostring(Y),et) | |
local eo={type="connectionResponse",from=q,to=F,publicKey=tostring(k),ephemeralPublicKey=tostring(B),tag=tostring(ea):sub(1,10),counter=Y}L.transmit(m,m,eo) | |
y[F]={publicKey=C,sharedSecret=P,ownEncryptionKey=X,ownMacKey=Z,otherEncryptionKey=Q,otherMacKey=J,counter=Y}end | |
local function T(L,U)local C=U.publicKey;local M=U.ephemeralPublicKey;local F=U.from;local W=U.tag;local Y=U.counter;assert( | |
L.otherAddress==F) | |
assert(type(C)=="string"and#C==22)assert(type(M)=="string")assert(#M==22)assert(v(C)== | |
F) | |
assert(type(W)=="string"and#W==10)assert(type(Y)=="number")local P=L.ephemeralSecretKey | |
local V=L.sharedSecret;local B=c.exchange(P,M)local G=h.hmac(B,V) | |
local K=h.hmac("senderEncryptionKey",G) | |
local Q={unpack(h.hmac("senderMacKey",G),1,16)}local J=h.hmac("receiverEncryptionKey",G) | |
local X={unpack(h.hmac("receiverMacKey",G),1,16)}local Z=h.hmac("receiverTagKey",G) | |
assert( | |
tostring(h.hmac(M..tostring(Y),Z)):sub(1,10)==W) | |
y[F]={publicKey=C,sharedSecret=V,ownEncryptionKey=K,ownMacKey=Q,otherEncryptionKey=J,otherMacKey=X,counter=Y}end | |
local function A(L)local U=L.ciphertext;local C=L.from;local M=L.counter;local F=y[C].counter | |
assert(type(U)=="string")assert(type(C)=="string") | |
assert(type(M)=="number")assert(y[C])assert(M>F)local W=y[C].otherEncryptionKey | |
local Y=y[C].otherMacKey;local P=l.decrypt(U,W,Y)P=tostring(P)local V=0;for Q=1,6 do V=V*256 | |
V=V+P:byte(7-Q)end;local B=P:byte(7) | |
local G=#P-7- ((-B-1)%256)local K=P:sub(8,G+7)K=s.decode(K)assert(V>F)y[C].counter=V | |
return C,K end | |
local function O(L)local U;local C={L}local M=false;local F,W,Y | |
while true do | |
if not M then if#C>0 then W=table.remove(C,1) | |
U=coroutine.create(A)M=true end end | |
if M then F,W,Y=coroutine.resume(U,W)if | |
coroutine.status(U)=="dead"then if F then os.queueEvent("ecnet_message",W,Y)end | |
M=false end end;C[#C+1]=coroutine.yield()end end;local I=coroutine.wrap(O) | |
local function N(L) | |
while true do | |
while true do local U,C,M,C,F=os.pullEvent()if | |
U~="modem_message"then I()end;if M~=m then break end;if type(F)~="table"then break end;if F.to~= | |
q then break end | |
if F.type=="addressRequest"then pcall(z,L,F)elseif | |
F.type=="connectionRequest"then local W=pcall(E,L,F)if W then | |
os.queueEvent("ecnet_connection",F.from)end elseif F.type=="message"then I(F)end end end end | |
local function S(L,U,C) | |
local M=parallel.waitForAny(function()sleep(C)end,function()local F | |
if y[U]then F=y[U].publicKey else local Y=j(L,U) | |
while true do | |
local P,P,V,P,B=os.pullEvent("modem_message") | |
if | |
( | |
V==m and type(B)=="table"and B.to==q and B.from==U and B.type=="addressResponse")then local G;G,F=pcall(_,Y,B)if G then break end end end end;local W=x(L,F) | |
while true do local Y,Y,P,Y,V=os.pullEvent("modem_message") | |
if | |
( | |
P==m and type(V)== | |
"table"and V.to==q and V.from==U and V.type=="connectionResponse")then local B=pcall(T,W,V)if B then break end end end end,N)return(M==2)end | |
local function H(L,U,C)if not y[U]then return false end;local M=y[U].ownEncryptionKey | |
local F=y[U].ownMacKey;C=s.encode(C)local W=os.epoch("utc")local Y=W;local P="" | |
for G=1,6 do P=P.. | |
string.char(Y%256)Y=math.floor(Y/256)end;P=P..string.char(#C%256)P=P..C;P=P.. ("\0"):rep((-#C-1)% | |
256)local V=l.encrypt(P,M,F) | |
local B={type="message",from=q,to=U,ciphertext=tostring(V),counter=W}L.transmit(m,m,B)return true end | |
local function R(L,U,C)local M,F | |
local W=parallel.waitForAny(function()if C then sleep(C)else | |
while true do coroutine.yield()end end end,function() | |
while true do local Y | |
Y,M,F=os.pullEvent("ecnet_message")if not U or M==U then return end end end,function()N(L)end)if W==2 then return M,F else return nil end end | |
local function D(L)L.open(m) | |
return | |
{listen=function()return N(L)end,connect=function(U,C)return S(L,U,C)end,send=function(U,C) | |
return H(L,U,C)end,receive=function(U,C)return R(L,U,C)end}end;return{wrap=D,address=q}end | |
a["ecnet.ecc.modq"]=function(...)local n=i("ecnet.util") | |
local s=i("ecnet.ecc.arith")local h=i("ecnet.symmetric.sha256") | |
local r=i("ecnet.symmetric.random")local d=s.isEqual;local l=s.compare;local u=s.add;local c=s.sub;local m=s.addDouble;local f=s.mult | |
local w=s.square;local y=s.encodeInt;local p=s.decodeInt;local v=n.byteTableMT;local b | |
local g={9622359,6699217,13940450,16775734,16777215,16777215,3940351} | |
local k={1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,0,1,1,0,0,0,1,0,1,1,0,0,0,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,0,0,0,1,1,1,0,1,1,0,1,1,0,1,0,0,1,0,1,0,1,1,0,1,1,0,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1} | |
local q={15218585,5740955,3271338,9903997,9067368,7173545,6988392} | |
local j={1336213,11071705,9716828,11083885,9188643,1494868,3306114}local function x(C)local M={unpack(C)}if l(M,g)>=0 then M=c(M,g)end | |
return setmetatable(M,b)end | |
local function z(C,M)return x(u(C,M))end | |
local function _(C,M)local F=c(C,M)if F[7]<0 then F=u(F,g)end;return setmetatable(F,b)end | |
local function E(C) | |
local M={unpack(f({unpack(C,1,7)},q,true),1,7)}local F={unpack(m(C,f(M,g)),8,14)}return x(F)end;local function T(C,M)return E(f(C,M))end;local function A(C)return E(w(C))end;local function O(C) | |
return T(C,j)end | |
local function I(C)local C={unpack(C)}for M=8,14 do C[M]=0 end;return E(C)end;local N=O({1,0,0,0,0,0,0}) | |
local function S(C,M)local C={unpack(C)} | |
local F={unpack(N)}for W=1,168 do if M[W]==1 then F=T(F,C)end;C=A(C)end;return F end | |
local function H(C,M)local C={unpack(C)}local F=setmetatable({unpack(N)},b)if | |
M<0 then C=S(C,k)M=-M end;while M>0 do if M%2 ==1 then F=T(F,C)end;C=A(C)M=M/2 | |
M=M-M%1 end;return F end;local function R(C)local M=y(C)return setmetatable(M,v)end | |
local function D(C)C=type(C)== | |
"table"and{unpack(C,1,21)}or | |
{tostring(C):byte(1,21)}local M=p(C)M[7]= | |
M[7]%g[7]return setmetatable(M,b)end;local function L() | |
while true do local C={unpack(r.random(),1,21)}local M=p(C)if | |
M[7]<g[7]then return setmetatable(M,b)end end end;local function U(C)return | |
D(h.digest(C))end | |
b={__index={encode=function(C)return R(C)end},__tostring=function(C)return | |
C:encode():toHex()end,__add=function(C,M) | |
if type(C)=="number"then return M+C end;if type(M)=="number"then | |
assert(M<2^24,"number operand too big")M=O({M,0,0,0,0,0,0})end;return | |
z(C,M)end,__sub=function(C,M)if | |
type(C)=="number"then assert(C<2^24,"number operand too big") | |
C=O({C,0,0,0,0,0,0})end;if type(M)=="number"then | |
assert(M<2^24,"number operand too big")M=O({M,0,0,0,0,0,0})end;return | |
_(C,M)end,__unm=function(C)return | |
_(g,C)end,__eq=function(C,M)return d(C,M)end,__mul=function(C,M) | |
if type(C)=="number"then return M*C end | |
if type(M)=="table"and type(M[1])=="table"then return M*C end;if type(M)=="number"then | |
assert(M<2^24,"number operand too big")M=O({M,0,0,0,0,0,0})end;return | |
T(C,M)end,__div=function(C,M)if | |
type(C)=="number"then assert(C<2^24,"number operand too big") | |
C=O({C,0,0,0,0,0,0})end;if type(M)=="number"then | |
assert(M<2^24,"number operand too big")M=O({M,0,0,0,0,0,0})end | |
local F=S(M,k)return T(C,F)end,__pow=function(C,M)return | |
H(C,M)end}return{hashModQ=U,randomModQ=L,decodeModQ=D,inverseMontgomeryModQ=I}end | |
a["ecnet.ecc.modp"]=function(...)local n=i("ecnet.ecc.arith")local s=n.add;local h=n.sub | |
local r=n.addDouble;local d=n.mult;local l=n.square;local u={3,0,0,0,0,0,15761408} | |
local c={5592405,5592405,5592405,5592405,5592405,5592405,14800213} | |
local m={13533400,837116,6278376,13533388,837116,6278376,7504076} | |
local function f(z)local _,E,T,A,O,I,N=unpack(z)local S=_*3;local H=E*3;local R=T*3;local D=A*3;local L=O*3;local U=I*3 | |
local C=_*15761408;C=C+N*3;local M=E*15761408;local F=T*15761408;local W=A*15761408 | |
local Y=O*15761408;local P=I*15761408;local V=N*15761408;local B=0;local G;G=S/0x1000000 | |
H=H+ (G-G%1)S=S%0x1000000;G=H/0x1000000;R=R+ (G-G%1)H=H%0x1000000;G=R/ | |
0x1000000;D=D+ (G-G%1)R=R%0x1000000;G=D/0x1000000;L=L+ | |
(G-G%1)D=D%0x1000000;G=L/0x1000000;U=U+ (G-G%1) | |
L=L%0x1000000;G=U/0x1000000;C=C+ (G-G%1)U=U%0x1000000;G=C/0x1000000;M=M+ (G- | |
G%1)C=C%0x1000000;G=M/0x1000000 | |
F=F+ (G-G%1)M=M%0x1000000;G=F/0x1000000;W=W+ (G-G%1)F=F%0x1000000;G=W/ | |
0x1000000;Y=Y+ (G-G%1)W=W%0x1000000;G=Y/0x1000000;P=P+ | |
(G-G%1)Y=Y%0x1000000;G=P/0x1000000;V=V+ (G-G%1) | |
P=P%0x1000000;G=V/0x1000000;B=B+ (G-G%1)V=V%0x1000000;return | |
{S,H,R,D,L,U,C,M,F,W,Y,P,V,B}end | |
local function w(z)if z[7]<15761408 or z[7]==15761408 and z[1]<3 then return | |
{unpack(z)}end;local _=z[1]local E=z[2]local T=z[3] | |
local A=z[4]local O=z[5]local I=z[6]local N=z[7]_=_-3;N=N-15761408 | |
if _<0 then E=E-1;_=_+0x1000000 end;if E<0 then T=T-1;E=E+0x1000000 end | |
if T<0 then A=A-1;T=T+0x1000000 end;if A<0 then O=O-1;A=A+0x1000000 end | |
if O<0 then I=I-1;O=O+0x1000000 end;if I<0 then N=N-1;I=I+0x1000000 end;return{_,E,T,A,O,I,N}end;local function y(z,_)return w(s(z,_))end;local function p(z,_)local E=h(z,_) | |
if E[7]<0 then E=s(E,u)end;return E end;local function v(z)local _=d(z,c,true) | |
local E={unpack(r(z,f(_)),8,14)}return w(E)end | |
local function b(z,_)return v(d(z,_))end;local function g(z)return v(l(z))end;local function k(z)return b(z,m)end;local function q(z) | |
local z={unpack(z)}for _=8,14 do z[_]=0 end;return v(z)end | |
local j=k({1,0,0,0,0,0,0}) | |
local function x(z,_)local z={unpack(z)}local E={unpack(j)}for T=1,168 do | |
if _[T]==1 then E=b(E,z)end;z=g(z)end;return E end | |
return{addModP=y,subModP=p,multModP=b,squareModP=g,montgomeryModP=k,inverseMontgomeryModP=q,expModP=x}end | |
a["ecnet.ecc.ecc"]=function(...)local n=i("ecnet.util") | |
local s=i("ecnet.ecc.curve")local h=i("ecnet.ecc.modq")local r=i("ecnet.symmetric.sha256") | |
local d=i("ecnet.symmetric.chacha20")local l=i("ecnet.symmetric.siphash") | |
local u=i("ecnet.symmetric.random")local c=n.byteTableMT | |
local function m(p)local v | |
if p then v=h.hashModQ(p)else v=h.randomModQ()end;local b=s.G*v;local g=v:encode()local k=b:encode()return g,k end;local function f(p,v)local b=h.decodeModQ(p)local g=s.pointDecode(v)local k=g*b | |
local q=r.digest(k:encode())return q end | |
local function w(p,v) | |
local v= | |
type(v)=="table"and string.char(unpack(v))or tostring(v)local p=type(p)=="table"and string.char(unpack(p))or | |
tostring(p) | |
local b=h.decodeModQ(p)local g=h.randomModQ()local k=s.G*g | |
local q=h.hashModQ(v..tostring(k))local j=g-b*q;q=q:encode()j=j:encode()local x=q | |
for z=1,#j do x[#x+1]=j[z]end;return setmetatable(x,c)end | |
local function y(p,v,b)local v=type(v)=="table"and string.char(unpack(v))or | |
tostring(v) | |
local g=s.pointDecode(p)local k=h.decodeModQ({unpack(b,1,#b/2)})local q=h.decodeModQ({unpack(b, | |
#b/2+1)}) | |
local j=s.G*q+g*k;local x=h.hashModQ(v..tostring(j))return x==k end;return{keypair=m,exchange=f,sign=w,verify=y}end | |
a["ecnet.ecc.curve"]=function(...)local n=i("ecnet.util") | |
local s=i("ecnet.ecc.arith")local h=i("ecnet.ecc.modp")local r=i("ecnet.ecc.modq") | |
local l=s.isEqual;local u=s.NAF;local c=s.encodeInt;local m=s.decodeInt;local f=h.multModP;local w=h.squareModP | |
local y=h.addModP;local v=h.subModP;local b=h.montgomeryModP;local g=h.expModP;local k=r.inverseMontgomeryModQ | |
local q=n.byteTableMT;local j;local x={0,0,0,0,0,0,0}local z=b({1,0,0,0,0,0,0}) | |
local _=b({122,0,0,0,0,0,0})local E={3,0,0,0,0,0,15761408} | |
local T={1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,1,1} | |
local A={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,1,1} | |
local I={{6636044,10381432,15741790,2914241,5785600,264923,4550291},{13512827,8449886,5647959,1135556,5489843,7177356,8002203},{unpack(z)}} | |
local N={{unpack(x)},{unpack(z)},{unpack(z)}} | |
local function S(d)local p,O,G=unpack(d)local K=y(p,O)local Q=w(K)local X=w(p)local Z=w(O)local ee=y(X,Z) | |
local et=w(G)local ea=v(ee,y(et,et))local eo=f(v(Q,ee),ea)local ei=f(ee,v(X,Z)) | |
local en=f(ee,ea)local es={eo,ei,en}return setmetatable(es,j)end | |
local function H(d,p)local O,G,K=unpack(d)local Q,J,X=unpack(p)local Z=f(K,X)local ee=w(Z)local et=f(O,Q) | |
local ea=f(G,J)local eo=f(_,f(et,ea))local ei=v(ee,eo)local I=y(ee,eo) | |
local en=f(Z,f(ei,v(f(y(O,G),y(Q,J)),y(et,ea))))local es=f(Z,f(I,v(ea,et)))local eh=f(ei,I)local er={en,es,eh}return | |
setmetatable(er,j)end | |
local function R(d)local p,O,B=unpack(d)local G=v(x,p)local K={unpack(O)} | |
local Q={unpack(B)}local J={G,K,Q}return setmetatable(J,j)end;local function D(d,p)return H(d,R(p))end | |
local function L(d)local p,O,B=unpack(d)local G=g(B,T) | |
local K=f(p,G)local Q=f(O,G)local J={unpack(z)}local X={K,Q,J}return setmetatable(X,j)end | |
local function U(d,p)local O,B,G=unpack(d)local K,Q,J=unpack(p)local X=f(O,J)local Z=f(B,J)local ee=f(K,G) | |
local et=f(Q,G)return l(X,ee)and l(Z,et)end | |
local function C(d)local p,O,B=unpack(d)local G=w(p)local K=w(O)local Q=w(B)local J=w(Q)local X=y(G,K)X=f(X,Q) | |
local Z=f(_,f(G,K))Z=y(J,Z)return l(X,Z)end;local function M(d)return l(d[1],x)end | |
local function F(d,p)local O=u(d,5)local B={p}local G=S(p) | |
local K={{unpack(x)},{unpack(z)},{unpack(z)}}for Q=3,31,2 do B[Q]=H(B[Q-2],G)end | |
for Q=#O,1,-1 do K=S(K)if O[Q]>0 then | |
K=H(K,B[O[Q]])elseif O[Q]<0 then K=D(K,B[-O[Q]])end end;return setmetatable(K,j)end;local W={I}for d=2,168 do W[d]=S(W[d-1])end | |
local function Y(d)local p=u(d,2) | |
local O={{unpack(x)},{unpack(z)},{unpack(z)}}for B=1,168 do | |
if p[B]==1 then O=H(O,W[B])elseif p[B]==-1 then O=D(O,W[B])end end;return setmetatable(O,j)end;local function P(d)d=L(d)local p={}local O,B=unpack(d)p=c(B)p[22]=O[1]%2 | |
return setmetatable(p,q)end | |
local function V(d) | |
d=type(d)=="table"and | |
{unpack(d,1,22)}or{tostring(d):byte(1,22)}local p=m(d)p[7]=p[7]%E[7]local O=w(p)local B=v(O,z)local G=v(f(_,O),z) | |
local K=w(B)local Q=f(B,K)local J=f(Q,K)local X=f(G,w(G))local Z=f(J,X) | |
local ee=f(Q,f(G,g(Z,A)))if ee[1]%2 ~=d[22]then ee=v(x,ee)end | |
local et={ee,p,{unpack(z)}}return setmetatable(et,j)end | |
j={__index={isOnCurve=function(d)return C(d)end,isInf=function(d)return d:isOnCurve()and M(d)end,encode=function(d)return | |
P(d)end},__tostring=function(d)return | |
d:encode():toHex()end,__add=function(d,p) | |
assert(d:isOnCurve(),"invalid point")assert(p:isOnCurve(),"invalid point")return H(d,p)end,__sub=function(d,p) | |
assert(d:isOnCurve(),"invalid point")assert(p:isOnCurve(),"invalid point")return D(d,p)end,__unm=function(d) | |
assert(d:isOnCurve(),"invalid point")return R(d)end,__eq=function(d,p) | |
assert(d:isOnCurve(),"invalid point")assert(p:isOnCurve(),"invalid point")return U(d,p)end,__mul=function(d,p)if | |
type(d)=="number"then return p*d end | |
if type(p)=="number"then | |
assert(p<2^24,"number multiplier too big")p={p,0,0,0,0,0,0}else p=k(p)end;if d==I then return Y(p)else return F(p,d)end end}I=setmetatable(I,j)N=setmetatable(N,j) | |
return{G=I,O=N,pointDecode=V}end | |
a["ecnet.ecc.arith"]=function(...) | |
local function n(p,v)return | |
( | |
p[1]==v[1]and p[2]==v[2]and p[3]==v[3]and p[4]==v[4]and p[5]==v[5]and p[6]==v[6]and p[7]==v[7])end;local function s(p,v) | |
for b=7,1,-1 do if p[b]>v[b]then return 1 elseif p[b]<v[b]then return-1 end end;return 0 end | |
local function h(p,v) | |
local b=p[1]+v[1]local g=p[2]+v[2]local k=p[3]+v[3]local q=p[4]+v[4] | |
local j=p[5]+v[5]local x=p[6]+v[6]local z=p[7]+v[7] | |
if b>0xffffff then g=g+1;b=b-0x1000000 end;if g>0xffffff then k=k+1;g=g-0x1000000 end;if k>0xffffff then q=q+1 | |
k=k-0x1000000 end;if q>0xffffff then j=j+1;q=q-0x1000000 end;if j> | |
0xffffff then x=x+1;j=j-0x1000000 end;if x>0xffffff then z=z+1 | |
x=x-0x1000000 end;return{b,g,k,q,j,x,z}end | |
local function r(p,v)local b=p[1]-v[1]local g=p[2]-v[2]local k=p[3]-v[3] | |
local q=p[4]-v[4]local j=p[5]-v[5]local x=p[6]-v[6]local z=p[7]-v[7]if b<0 then g=g-1 | |
b=b+0x1000000 end;if g<0 then k=k-1;g=g+0x1000000 end;if k<0 then q=q-1 | |
k=k+0x1000000 end;if q<0 then j=j-1;q=q+0x1000000 end;if j<0 then x=x-1 | |
j=j+0x1000000 end;if x<0 then z=z-1;x=x+0x1000000 end | |
return{b,g,k,q,j,x,z}end | |
local function d(p)local v=p[1]local b=p[2]local g=p[3]local k=p[4]local q=p[5]local j=p[6]local x=p[7]v=v/2 | |
v=v-v%1;v=v+ (b%2)*0x800000;b=b/2;b=b-b%1 | |
b=b+ (g%2)*0x800000;g=g/2;g=g-g%1;g=g+ (k%2)*0x800000;k=k/2;k=k-k%1;k=k+ | |
(q%2)*0x800000;q=q/2;q=q-q%1;q=q+ (j%2)*0x800000;j=j/2;j=j-j% | |
1;j=j+ (x%2)*0x800000;x=x/2;x=x-x%1 | |
return{v,b,g,k,q,j,x}end | |
local function l(p,v)local b=p[1]+v[1]local g=p[2]+v[2]local k=p[3]+v[3] | |
local q=p[4]+v[4]local j=p[5]+v[5]local x=p[6]+v[6]local z=p[7]+v[7] | |
local _=p[8]+v[8]local E=p[9]+v[9]local T=p[10]+v[10]local A=p[11]+v[11] | |
local O=p[12]+v[12]local I=p[13]+v[13]local N=p[14]+v[14]if b>0xffffff then g=g+1 | |
b=b-0x1000000 end;if g>0xffffff then k=k+1;g=g-0x1000000 end;if k> | |
0xffffff then q=q+1;k=k-0x1000000 end;if q>0xffffff then j=j+1 | |
q=q-0x1000000 end;if j>0xffffff then x=x+1;j=j-0x1000000 end;if x> | |
0xffffff then z=z+1;x=x-0x1000000 end;if z>0xffffff then _=_+1 | |
z=z-0x1000000 end;if _>0xffffff then E=E+1;_=_-0x1000000 end;if E> | |
0xffffff then T=T+1;E=E-0x1000000 end;if T>0xffffff then A=A+1 | |
T=T-0x1000000 end;if A>0xffffff then O=O+1;A=A-0x1000000 end;if O> | |
0xffffff then I=I+1;O=O-0x1000000 end;if I>0xffffff then N=N+1 | |
I=I-0x1000000 end;return{b,g,k,q,j,x,z,_,E,T,A,O,I,N}end | |
local function u(p,v,b)local g,k,q,j,x,z,_=unpack(p)local E,T,A,O,I,N,S=unpack(v)local H=g*E;local R=g*T+k*E;local D= | |
g*A+k*T+q*E;local L=g*O+k*A+q*T+j*E;local U=g*I+k*O+q*A+ | |
j*T+x*E;local C=g*N+k*I+q*O+j*A+x*T+ | |
z*E;local M= | |
g*S+k*N+q*I+j*O+x*A+z*T+_*E;local F,W,Y,P,V,B,G;if not b then F=k*S+q*N+j*I+x*O+ | |
z*A+_*T | |
W=q*S+j*N+x*I+z*O+_*A;Y=j*S+x*N+z*I+_*O;P=x*S+z*N+_*I;V=z*S+_*N | |
B=_*S;G=0 else F=0 end;local K;K=H;H= | |
H%0x1000000;R=R+ (K-H)/0x1000000;K=R;R=R%0x1000000;D= | |
D+ (K-R)/0x1000000;K=D;D=D%0x1000000 | |
L=L+ (K-D)/0x1000000;K=L;L=L%0x1000000;U=U+ (K-L)/0x1000000;K=U | |
U=U%0x1000000;C=C+ (K-U)/0x1000000;K=C;C=C%0x1000000 | |
M=M+ (K-C)/0x1000000;K=M;M=M%0x1000000 | |
if not b then F=F+ (K-M)/0x1000000;K=F | |
F=F%0x1000000;W=W+ (K-F)/0x1000000;K=W;W=W%0x1000000 | |
Y=Y+ (K-W)/0x1000000;K=Y;Y=Y%0x1000000;P=P+ (K-Y)/0x1000000;K=P | |
P=P%0x1000000;V=V+ (K-P)/0x1000000;K=V;V=V%0x1000000 | |
B=B+ (K-V)/0x1000000;K=B;B=B%0x1000000;G=G+ (K-B)/0x1000000 end;return{H,R,D,L,U,C,M,F,W,Y,P,V,B,G}end | |
local function c(p)local v,b,g,k,q,j,x=unpack(p)local z=v*v;local _=v*b*2;local E=v*g*2+b*b | |
local T=v*k*2+b*g*2;local A=v*q*2+b*k*2+g*g | |
local O=v*j*2+b*q*2+g*k*2;local I=v*x*2+b*j*2+g*q*2+k*k;local N=b*x*2+g*j*2+k* | |
q*2;local S=g*x*2+k*j*2+q*q;local H=k*x*2+ | |
q*j*2;local R=q*x*2+j*j;local D=j*x*2;local L=x*x;local U=0;local C;C=z | |
z=z%0x1000000;_=_+ (C-z)/0x1000000;C=_;_=_%0x1000000 | |
E=E+ (C-_)/0x1000000;C=E;E=E%0x1000000;T=T+ (C-E)/0x1000000;C=T | |
T=T%0x1000000;A=A+ (C-T)/0x1000000;C=A;A=A%0x1000000 | |
O=O+ (C-A)/0x1000000;C=O;O=O%0x1000000;I=I+ (C-O)/0x1000000;C=I | |
I=I%0x1000000;N=N+ (C-I)/0x1000000;C=N;N=N%0x1000000 | |
S=S+ (C-N)/0x1000000;C=S;S=S%0x1000000;H=H+ (C-S)/0x1000000;C=H | |
H=H%0x1000000;R=R+ (C-H)/0x1000000;C=R;R=R%0x1000000 | |
D=D+ (C-R)/0x1000000;C=D;D=D%0x1000000;L=L+ (C-D)/0x1000000;C=L | |
L=L%0x1000000;U=U+ (C-L)/0x1000000 | |
return{z,_,E,T,A,O,I,N,S,H,R,D,L,U}end | |
local function m(p)local v={}for b=1,7 do local g=p[b] | |
for k=1,3 do v[#v+1]=g%256;g=math.floor(g/256)end end;return v end | |
local function f(p)local v={}local b={} | |
for g=1,21 do local k=p[g] | |
assert(type(k)=="number","integer decoding failure") | |
assert(k>=0 and k<=255,"integer decoding failure")assert(k%1 ==0,"integer decoding failure")b[g]=k end | |
for g=1,21,3 do local k=0;for q=2,0,-1 do k=k*256;k=k+b[g+q]end;v[#v+1]=k end;return v end | |
local function w(p,v)local b=p[1]%2^v;if b>=2^ (v-1)then b=b-2^v end;return b end | |
local function y(p,v)local b={}local p={unpack(p)} | |
for g=1,168 do if p[1]%2 ==1 then b[#b+1]=w(p,v) | |
p=r(p,{b[#b],0,0,0,0,0,0})else b[#b+1]=0 end;p=d(p)end;return b end | |
return{isEqual=n,compare=s,add=h,sub=r,addDouble=l,mult=u,square=c,encodeInt=m,decodeInt=f,NAF=y}end | |
a["ecnet.cbor"]=function(...)local function n(ed,el)local eu,ec=pcall(i,ed)if not eu then return end | |
if el then return ec[el]end;return ec end | |
local s=function(ed) | |
local el,eu=pcall(loadstring or load,ed)if el and eu then return eu()end end;local h=setmetatable;local r=getmetatable | |
local d=debug and debug.getmetatable;local l=assert;local u=error;local c=type;local m=pairs;local f=ipairs;local w=tostring | |
local y=string.char;local p=table.concat;local v=table.sort;local b=math.floor;local g=math.abs | |
local k=math.huge;local q=math.max;local j=math.maxinteger or 9007199254740992;local x= | |
math.mininteger or-9007199254740992;local z=0/0 | |
local _=math.frexp | |
local E=math.ldexp or function(ed,el)return ed*2.0^el end | |
local T=math.type or function(ed)return | |
ed%1 ==0 and ed<=j and ed>=x and"integer"or"float"end;local A=string.pack or n("struct","pack")local O=string.unpack or | |
n("struct","unpack") | |
local I= | |
n("bit32","rshift")or n("bit","rshift")or s"return function(a,b) return a >> b end"or function(ed,el)return | |
q(0,b(ed/ (2^el)))end;if A and A(">I2",0)~="\0\0"then A=nil end;if O and | |
O(">I2","\1\2\3\4")~=0x102 then O=nil end;local N=nil;local S={}local function H(ed,el)return | |
S[c(ed)](ed,el)end | |
local function R(ed,el) | |
if el==0 and ed<0 then ed,el=-ed-1,32 end | |
if ed<24 then return y(el+ed)elseif ed<2^8 then return y(el+24,ed)elseif ed<2^16 then return | |
y(el+25,I(ed,8),ed%0x100)elseif ed<2^32 then return y(el+26,I(ed,24)%0x100,I(ed,16)%0x100,I(ed,8)%0x100, | |
ed%0x100)elseif ed< | |
2^64 then local eu=b(ed/2^32)ed=ed%2^32;return | |
y(el+27,I(eu,24)%0x100,I(eu,16)%0x100, | |
I(eu,8)%0x100,eu%0x100,I(ed,24)%0x100,I(ed,16)%0x100,I(ed,8)%0x100,ed%0x100)end;u"int too large"end | |
if A then | |
function R(ed,el)local eu;el=el or 0 | |
if ed<24 then eu,el=">B",el+ed elseif ed<256 then eu,el=">BB",el+24 elseif ed<65536 then | |
eu,el=">BI2",el+25 elseif ed<4294967296 then eu,el=">BI4",el+26 else eu,el=">BI8",el+27 end;return A(eu,el,ed)end end;local D={}function D:__tostring()return | |
self.name or("simple(%d)"):format(self.value)end | |
function D:__tocbor()return | |
self.cbor or R(self.value,224)end | |
local function L(ed,el,eu) | |
l(ed>=0 and ed<=255,"bad argument #1 to 'simple' (integer in range 0..255 expected)")return h({value=ed,name=el,cbor=eu},D)end;local U={}function U:__tostring() | |
return("%d(%s)"):format(self.tag,w(self.value))end;function U:__tocbor()return | |
R(self.tag,192)..H(self.value)end | |
local function C(ed,el) | |
l(ed>=0,"bad argument #1 to 'tagged' (positive integer expected)")return h({tag=ed,value=el},U)end;local M=L(22,"null")local F=L(23,"undefined") | |
local W=L(31,"break","\255")function S.number(ed)return S[T(ed)](ed)end;function S.integer(ed)if ed<0 then | |
return R(-1-ed,32)end;return R(ed,0)end | |
function S.float(ed)if | |
ed~=ed then return"\251\127\255\255\255\255\255\255\255"end;local el=( | |
ed>0 or 1/ed>0)and 0 or 1 | |
ed=g(ed)if ed==k then | |
return y(251,el*128+128-1).."\240\0\0\0\0\0\0"end;local eu,ec=_(ed)if eu==0 then return | |
y(251,el*128).."\0\0\0\0\0\0\0"end;eu=eu*2;ec=ec+1024-2;if | |
ec<=0 then eu=eu*2^ (ec-1)ec=0 else eu=eu-1 end | |
return | |
y(251,el*2^7+b(ec/ | |
2^4)%2^7,ec%2^4*2^4+b(eu*2^4%0x100),b( | |
eu*2^12%0x100),b(eu*2^20%0x100),b(eu*2^28%0x100),b( | |
eu*2^36%0x100),b(eu*2^44%0x100),b(eu*2^52%0x100))end | |
if A then function S.float(ed)return A(">Bd",251,ed)end end;function S.bytestring(ed)return R(#ed,64)..ed end;function S.utf8string(ed)return | |
R(#ed,96)..ed end;S.string=S.bytestring;function S.boolean(ed)return | |
ed and"\245"or"\244"end | |
S["nil"]=function()return"\246"end;function S.userdata(ed,el)local eu=d(ed)if eu then local ec=el and el[eu]or eu.__tocbor;if ec then return | |
ec(ed,el)end end | |
u"can't encode userdata"end | |
function S.table(ed,el) | |
local eu=r(ed)if eu then local ep=el and el[eu]or eu.__tocbor | |
if ep then return ep(ed,el)end end | |
local ec,em,ef,ew={R(#ed,128)},{"\191"},1,2;local ey=true | |
for ep,ev in m(ed)do ey=ey and ef==ep;ef=ef+1;local eb=H(ev,el)ec[ef]=eb;em[ew],ew=H(ep,el), | |
ew+1;em[ew],ew=eb,ew+1 end;em[1]=R(ef-1,160)return p(ey and ec or em)end;function S.array(ed,el)local eu={}for ec,em in f(ed)do eu[ec]=H(em,el)end | |
return R(#eu,128)..p(eu)end | |
function S.map(ed,el)local eu,ec,em={"\191"},2,0 | |
for ef,ew in | |
m(ed)do eu[ec],ec=H(ef,el),ec+1;eu[ec],ec=H(ew,el),ec+1;em=em+1 end;eu[1]=R(em,160)return p(eu)end;S.dict=S.map | |
function S.ordered_map(ed,el)local eu={}if not ed[1]then local ec=0 | |
for em in m(ed)do ec=ec+1;eu[ec]=em end;v(eu)end;for ec,em in f(ed[1]and ed or eu)do eu[ec]= | |
H(em,el)..H(ed[em],el)end;return | |
R(#eu,160)..p(eu)end | |
S["function"]=function()u"can't encode function"end;local function Y(ed,el)return ed:read(el)end;local function P(ed) | |
return ed:read(1):byte()end | |
local function V(ed,el) | |
if el<24 then return el elseif el<28 then local eu=0;for ec=1,2^ (el-24)do | |
eu=eu*256+P(ed)end;return eu else u"invalid length"end end;local B={}local function G(ed)local el=P(ed)return I(el,5),el%32 end;local function K(ed,el) | |
local eu,ec=G(ed)return B[eu](ed,ec,el)end | |
local function Q(ed,el)return V(ed,el)end;local function J(ed,el)return-1-V(ed,el)end | |
local function X(ed,el) | |
if el~=31 then return Y(ed,V(ed,el))end;local eu={}local ec=1;local em=K(ed) | |
while em~=W do eu[ec],ec=em,ec+1;em=K(ed)end;return p(eu)end;local function Z(ed,el)return X(ed,el)end | |
local function ee(ed,el,eu)local ec={} | |
if el==31 then local em=1;local ef=K(ed,eu)while ef~=W do ec[em],em=ef, | |
em+1;ef=K(ed,eu)end else local em=V(ed,el)for ef=1,em do | |
ec[ef]=K(ed,eu)end end;return ec end | |
local function et(ed,el,eu)local ec={}local em | |
if el==31 then local ef=1;em=K(ed,eu)while em~=W do ec[em],ef=K(ed,eu),ef+1 | |
em=K(ed,eu)end else local ef=V(ed,el) | |
for ew=1,ef do em=K(ed,eu)ec[em]=K(ed,eu)end end;return ec end;local ea={} | |
local function eo(ed,el,eu)local ec=V(ed,el)local em=K(ed,eu) | |
local ef=eu and eu[ec]or ea[ec]if ef then return ef(em)end;return C(ec,em)end | |
local function ei(ed)local el=P(ed)local eu=P(ed)local ec=el<128 and 1 or-1;eu=eu+ | |
(el*256)%1024;el=I(el,2)%32 | |
if el==0 then return ec*E(eu,-24)elseif el~=31 then return ec*E(eu+ | |
1024,el-25)elseif eu==0 then return ec*k else return z end end | |
local function en(ed)local el=P(ed)local eu=P(ed)local ec=el<128 and 1 or-1 | |
el=el*2%256+I(eu,7)eu=eu%128;eu=eu*256+P(ed)eu=eu*256+P(ed)if el==0 then return | |
ec*E(el,-149)elseif el~=0xff then return ec*E(eu+2^23,el-150)elseif eu==0 then | |
return ec*k else return z end end | |
local function es(ed)local el=P(ed)local eu=P(ed)local ec=el<128 and 1 or-1 | |
el=el%128*16+I(eu,4)eu=eu%16;eu=eu*256+P(ed)eu=eu*256+P(ed) | |
eu=eu*256+P(ed)eu=eu*256+P(ed)eu=eu*256+P(ed)eu=eu*256+P(ed) | |
if | |
el==0 then return ec*E(el,-149)elseif el~=0xff then | |
return ec*E(eu+2^52,el-1075)elseif eu==0 then return ec*k else return z end end;if O then function en(ed)return O(">f",Y(ed,4))end;function es(ed) | |
return O(">d",Y(ed,8))end end | |
local function eh(ed,el,eu)if el==24 then | |
el=P(ed)end | |
if el==20 then return false elseif el==21 then return true elseif el==22 then return M elseif el==23 then return F elseif el==25 then return ei(ed)elseif | |
el==26 then return en(ed)elseif el==27 then return es(ed)elseif el==31 then return W end;if eu and eu.simple then return eu.simple(el)end;return L(el)end;B[0]=Q;B[1]=J;B[2]=X;B[3]=Z;B[4]=ee;B[5]=et;B[6]=eo;B[7]=eh | |
local function er(ed,el)local eu={}local ec=1;local em | |
if | |
c(el)=="function"then em=el elseif c(el)=="table"then em=el.more elseif el~=nil then | |
u(("bad argument #2 to 'decode' (function or table expected, got %s)"):format(c(el)))end | |
if c(em)~="function"then function em()u"input too short"end end | |
function eu:read(ef)local ew=ed:sub(ec,ec+ef-1) | |
if#ew<ef then ew=em(ef-#ew,eu,el)if | |
ew then self:write(ew)end;return self:read(ef)end;ec=ec+ef;return ew end | |
function eu:write(ef)ed=ed..ef;if ec>256 then ed=ed:sub(ec+1)ec=1 end;return#ef end;return K(eu,el)end | |
return{encode=H,decode=er,decode_file=K,type_encoders=S,type_decoders=B,tagged_decoders=ea,simple=L,tagged=C,null=M,undefined=F}end;return a["ecnet.ecnet"](...) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment