|
MIT License |
|
|
|
Copyright (c) 2025 Nicholas Folse |
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
of this software and associated documentation files (the "Software"), to deal |
|
in the Software without restriction, including without limitation the rights |
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
copies of the Software, and to permit persons to whom the Software is |
|
furnished to do so, subject to the following conditions: |
|
|
|
The above copyright notice and this permission notice shall be included in all |
|
copies or substantial portions of the Software. |
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
SOFTWARE. |
|
|
|
=LAMBDA(input,key, |
|
LET( |
|
modu,2147483648, |
|
mask,2147483647, |
|
|
|
safe,LAMBDA(v,MOD(v,modu)), |
|
addm,LAMBDA(a,b,MOD(MOD(a,modu)+MOD(b,modu),modu)), |
|
xorb,LAMBDA(a,b,MOD(BITXOR(MOD(a,modu),MOD(b,modu)),modu)), |
|
|
|
rotm,LAMBDA(v,s, |
|
LET(k,MOD(s,31), |
|
x,MOD(v,modu), |
|
IF(k=0, |
|
x, |
|
MOD(MOD(x*POWER(2,k),modu)+QUOTIENT(x,POWER(2,31-k)),modu) |
|
) |
|
) |
|
), |
|
|
|
packword,LAMBDA(n, |
|
HSTACK( |
|
BITAND(BITRSHIFT(safe(n),24),255), |
|
BITAND(BITRSHIFT(safe(n),16),255), |
|
BITAND(BITRSHIFT(safe(n),8),255), |
|
BITAND(safe(n),255) |
|
) |
|
), |
|
|
|
repbyte,LAMBDA(b,cnt, |
|
MAKEARRAY(1,cnt,LAMBDA(r,c,b)) |
|
), |
|
|
|
xorrow,LAMBDA(a,b, |
|
LET(m,COLUMNS(a), |
|
idx,SEQUENCE(1,m), |
|
MAP(idx,LAMBDA(i, xorb(INDEX(a,1,i), INDEX(b,1,i)))) |
|
) |
|
), |
|
|
|
utfbytes,LAMBDA(s, |
|
LET( |
|
n,LEN(s), |
|
idx,SEQUENCE(1,n), |
|
DROP( |
|
REDUCE(HSTACK(0),idx, |
|
LAMBDA(acc,i, |
|
LET(cp,UNICODE(MID(s,i,1)), |
|
seg,IF(cp<128, |
|
HSTACK(cp), |
|
IF(cp<2048, |
|
HSTACK( |
|
BITOR(192,BITRSHIFT(cp,6)), |
|
BITOR(128,BITAND(cp,63)) |
|
), |
|
IF(cp<65536, |
|
HSTACK( |
|
BITOR(224,BITRSHIFT(cp,12)), |
|
BITOR(128,BITAND(BITRSHIFT(cp,6),63)), |
|
BITOR(128,BITAND(cp,63)) |
|
), |
|
HSTACK( |
|
BITOR(240,BITRSHIFT(cp,18)), |
|
BITOR(128,BITAND(BITRSHIFT(cp,12),63)), |
|
BITOR(128,BITAND(BITRSHIFT(cp,6),63)), |
|
BITOR(128,BITAND(cp,63)) |
|
) |
|
) |
|
) |
|
), |
|
HSTACK(acc,seg) |
|
) |
|
) |
|
), |
|
,1) |
|
) |
|
), |
|
|
|
mixword,LAMBDA(v, |
|
LET( |
|
x,safe(v), |
|
a,xorb(x,rotm(x,7)), |
|
b,addm(a,2654435769), |
|
c,xorb(b,rotm(b,11)), |
|
xorb(c,rotm(c,13)) |
|
) |
|
), |
|
|
|
stepword,LAMBDA(state,byte, |
|
LET( |
|
aval,safe(INDEX(state,1,1)), |
|
bval,safe(INDEX(state,2,1)), |
|
cval,safe(INDEX(state,3,1)), |
|
dval,safe(INDEX(state,4,1)), |
|
ctr,INDEX(state,5,1), |
|
|
|
rotone,5+MOD(ctr,27), |
|
rottwo,9+MOD(ctr,23), |
|
rotthr,13+MOD(ctr,19), |
|
rotfor,17+MOD(ctr,15), |
|
|
|
anew,addm(rotm(xorb(aval,byte),rotone),bval), |
|
bnew,addm(rotm(xorb(bval,byte),rottwo),cval), |
|
cnew,addm(rotm(xorb(cval,byte),rotthr),dval), |
|
dnew,addm(rotm(xorb(dval,byte),rotfor),aval), |
|
|
|
VSTACK( |
|
safe(anew), |
|
safe(bnew), |
|
safe(cnew), |
|
safe(dnew), |
|
MOD(ctr+1,modu) |
|
) |
|
) |
|
), |
|
|
|
hashbytes,LAMBDA(bytes,domain, |
|
LET( |
|
header,HSTACK(72,51,50,domain), |
|
seed,VSTACK(safe(2166136261),safe(36776121),safe(144066263),safe(374761393),0), |
|
st,REDUCE(seed,HSTACK(header,bytes),stepword), |
|
|
|
aval,INDEX(st,1,1), |
|
bval,INDEX(st,2,1), |
|
cval,INDEX(st,3,1), |
|
dval,INDEX(st,4,1), |
|
|
|
ha,mixword(xorb(aval,bval)), |
|
hb,mixword(xorb(bval,cval)), |
|
hc,mixword(xorb(cval,dval)), |
|
hd,mixword(xorb(dval,aval)), |
|
he,mixword(xorb(ha,hc)), |
|
hf,mixword(xorb(hb,hd)), |
|
|
|
HSTACK( |
|
BITAND(BITRSHIFT(ha,24),255),BITAND(BITRSHIFT(ha,16),255),BITAND(BITRSHIFT(ha,8),255),BITAND(ha,255), |
|
BITAND(BITRSHIFT(hb,24),255),BITAND(BITRSHIFT(hb,16),255),BITAND(BITRSHIFT(hb,8),255),BITAND(hb,255), |
|
BITAND(BITRSHIFT(hc,24),255),BITAND(BITRSHIFT(hc,16),255),BITAND(BITRSHIFT(hc,8),255),BITAND(hc,255), |
|
BITAND(BITRSHIFT(hd,24),255),BITAND(BITRSHIFT(hd,16),255),BITAND(BITRSHIFT(hd,8),255),BITAND(hd,255), |
|
BITAND(BITRSHIFT(he,24),255),BITAND(BITRSHIFT(he,16),255),BITAND(BITRSHIFT(he,8),255),BITAND(he,255), |
|
BITAND(BITRSHIFT(hf,24),255),BITAND(BITRSHIFT(hf,16),255),BITAND(BITRSHIFT(hf,8),255),BITAND(hf,255) |
|
) |
|
) |
|
), |
|
|
|
basecode,LAMBDA(bytes, |
|
LET( |
|
alpha,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", |
|
idx,SEQUENCE(1,32), |
|
TEXTJOIN("",TRUE, |
|
MAP(idx, |
|
LAMBDA(i, |
|
LET( |
|
base,QUOTIENT(i-1,4)*3, |
|
pos,MOD(i-1,4), |
|
ba,IF(base+1<=24,INDEX(bytes,1,base+1),0), |
|
bb,IF(base+2<=24,INDEX(bytes,1,base+2),0), |
|
bc,IF(base+3<=24,INDEX(bytes,1,base+3),0), |
|
blk,ba*65536+bb*256+bc, |
|
val,CHOOSE( |
|
pos+1, |
|
BITRSHIFT(blk,18), |
|
BITAND(BITRSHIFT(blk,12),63), |
|
BITAND(BITRSHIFT(blk,6),63), |
|
BITAND(blk,63) |
|
), |
|
MID(alpha,val+1,1) |
|
) |
|
) |
|
) |
|
) |
|
) |
|
), |
|
|
|
msgbytes,utfbytes(input), |
|
msglen,packword(COLUMNS(msgbytes)), |
|
|
|
keybytes,IF(LEN(key)=0,repbyte(0,1),utfbytes(key)), |
|
klen,COLUMNS(keybytes), |
|
keyblock,IF( |
|
klen=0, |
|
repbyte(0,64), |
|
IF( |
|
klen>64, |
|
HSTACK(hashbytes(keybytes,161),repbyte(0,64-24)), |
|
HSTACK(keybytes,repbyte(0,64-klen)) |
|
) |
|
), |
|
|
|
ipad,repbyte(54,64), |
|
opad,repbyte(92,64), |
|
|
|
kip,xorrow(keyblock,ipad), |
|
kop,xorrow(keyblock,opad), |
|
|
|
inner,hashbytes(HSTACK(kip,msglen,msgbytes),17), |
|
outer,hashbytes(HSTACK(kop,packword(24),inner),34), |
|
|
|
basecode(outer) |
|
) |
|
) |