update test/md5.nas(still has bug) & add libmd5 in module(written in C++)

This commit is contained in:
ValKmjolnir 2022-03-28 17:14:11 +08:00
parent 617ad03d33
commit dd7740f1fd
5 changed files with 344 additions and 69 deletions

8
module/libmd5.nas Normal file
View File

@ -0,0 +1,8 @@
import("lib.nas");
var md5=func(str){
var lib=dylib.dlopen("./module/libmd5"~(os.platform()=="windows"?".dll":".so"));
var res=dylib.dlcall(dylib.dlsym(lib,"nas_md5"),str);
dylib.dlclose(lib);
return res;
}

View File

@ -11,5 +11,12 @@ libkey.so: keyboard.cpp
libkey.dll: keyboard.cpp libkey.dll: keyboard.cpp
g++ -c -O3 keyboard.cpp -fPIC -o keyboard.o -static g++ -c -O3 keyboard.cpp -fPIC -o keyboard.o -static
g++ -shared -o libkey.dll keyboard.o -static g++ -shared -o libkey.dll keyboard.o -static
libmd5.so: md5.cpp
clang++ -c -O3 md5.cpp -fPIC -o md5.o
clang++ -shared -o libmd5.so md5.o
rm md5.o
libmd5.dll: md5.cpp
g++ -c -O3 md5.cpp -fPIC -o md5.o -static
g++ -shared -o libmd5.dll md5.o -static
clean: clean:
rm *.o *.so *.dll *.dylib rm *.o *.so *.dll *.dylib

105
module/md5.cpp Normal file
View File

@ -0,0 +1,105 @@
#include "../nasal.h"
uint32_t strlength;
uint32_t* add(std::string str)
{
uint32_t num=((str.length()+8)/64)+1;
uint32_t *strByte=new uint32_t[num*16];
strlength=num*16;
for (uint32_t i=0;i<num*16;i++)
strByte[i]=0;
for (uint32_t i=0;i<str.length();i++)
strByte[i>>2]|=(str[i])<<((i%4)*8);
strByte[str.length()>>2]|=0x80<<(((str.length()%4))*8);
strByte[num*16-2]=str.length()*8;
return strByte;
}
std::string changeHex(int a)
{
const char str16[]="0123456789abcdef";
std::string str="";
for(int i=0;i<4;i++)
{
std::string str1="";
int b=((a>>i*8)%(1<<8))&0xff;
for (int j = 0; j < 2; j++)
{
str1.insert(0,1,str16[b%16]);
b=b/16;
}
str+=str1;
}
return str;
}
std::string md5(std::string source)
{
// uint32_t(abs(sin(i+1))*(2pow32))
const uint32_t k[]={
0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,0xa679438e,0x49b40821,
0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,
0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391
};
// left shift
const uint32_t s[]={
7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
};
// index
const uint32_t idx[]={
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, // g=i
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12, // g=(5*i+1)%16;
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2, // g=(3*i+5)%16;
0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9 // g=(7*i)%16;
};
uint32_t atmp=0x67452301,btmp=0xefcdab89;
uint32_t ctmp=0x98badcfe,dtmp=0x10325476;
uint32_t *strByte=add(source);
#define shift(x,n) (((x)<<(n))|((x)>>(32-(n)))) // cycle left shift
#define F(x,y,z) (((x)&(y))|((~x)&(z)))
#define G(x,y,z) (((x)&(z))|((y)&(~z)))
#define H(x,y,z) ((x)^(y)^(z))
#define I(x,y,z) ((y)^((x)|(~z)))
for(uint32_t i=0;i<strlength/16;i++)
{
uint32_t num[16];
for(uint32_t j=0;j<16;j++)
num[j]=strByte[i*16+j];
uint32_t f,g,a=atmp,b=btmp,c=ctmp,d=dtmp;
for(uint32_t i=0;i<64;i++)
{
if(i<16) f=F(b,c,d);
else if(i<32) f=G(b,c,d);
else if(i<48) f=H(b,c,d);
else f=I(b,c,d);
uint32_t tmp=d;
d=c;
c=b;
b=b+shift((a+f+k[i]+num[idx[i]]),s[i]);
a=tmp;
}
atmp+=a;
btmp+=b;
ctmp+=c;
dtmp+=d;
}
delete []strByte;
return changeHex(atmp).append(changeHex(btmp)).append(changeHex(ctmp)).append(changeHex(dtmp));
}
extern "C" nasal_ref nas_md5(std::vector<nasal_ref>& args,nasal_gc& gc){
if(!args.size())
return builtin_err("md5","lack arguments");
nasal_ref str=args[0];
if(str.type!=vm_str)
return builtin_err("md5","\"str\" must be a string");
nasal_ref res=gc.alloc(vm_str);
res.str()=md5(str.str());
return res;
}

View File

@ -227,7 +227,7 @@ void nasal_vm::stackinfo(const uint32_t limit=10)
printf("%ld):\n",top-bottom+1); printf("%ld):\n",top-bottom+1);
for(uint32_t i=0;i<limit && top>=bottom;++i,--top) for(uint32_t i=0;i<limit && top>=bottom;++i,--top)
{ {
printf("0x%.8lx",top-gc.stack); printf(" 0x%.8lx",top-gc.stack);
valinfo(top[0]); valinfo(top[0]);
} }
} }
@ -238,7 +238,7 @@ void nasal_vm::global_state()
printf("global(0x%lx<sp+0>):\n",(uint64_t)gc.stack); printf("global(0x%lx<sp+0>):\n",(uint64_t)gc.stack);
for(uint32_t i=0;i<bytecode[0].num;++i) for(uint32_t i=0;i<bytecode[0].num;++i)
{ {
printf("0x%.8x",i); printf(" 0x%.8x",i);
valinfo(gc.stack[i]); valinfo(gc.stack[i]);
} }
} }
@ -250,7 +250,7 @@ void nasal_vm::local_state()
printf("local(0x%lx<sp+%ld>):\n",(uint64_t)localr,localr-gc.stack); printf("local(0x%lx<sp+%ld>):\n",(uint64_t)localr,localr-gc.stack);
for(uint32_t i=0;i<lsize;++i) for(uint32_t i=0;i<lsize;++i)
{ {
printf("0x%.8x",i); printf(" 0x%.8x",i);
valinfo(localr[i]); valinfo(localr[i]);
} }
} }
@ -262,7 +262,7 @@ void nasal_vm::upval_state()
auto& upval=gc.funcr.func().upvalue; auto& upval=gc.funcr.func().upvalue;
for(uint32_t i=0;i<upval.size();++i) for(uint32_t i=0;i<upval.size();++i)
{ {
printf("-> upval[%u]:\n",i); printf(" -> upval[%u]:\n",i);
auto& uv=upval[i].upval(); auto& uv=upval[i].upval();
for(uint32_t j=0;j<uv.size;++j) for(uint32_t j=0;j<uv.size;++j)
{ {
@ -273,12 +273,12 @@ void nasal_vm::upval_state()
} }
void nasal_vm::detail() void nasal_vm::detail()
{ {
printf("maddr(0x%lx)\n",(uint64_t)mem_addr); printf("maddr:\n (0x%lx)\n",(uint64_t)mem_addr);
printf("localr(0x%lx)\n",(uint64_t)localr); printf("localr:\n (0x%lx)\n",(uint64_t)localr);
if(gc.funcr.type==vm_nil) if(gc.funcr.type==vm_nil)
printf("funcr(nil)\n"); printf("funcr:\n (nil)\n");
else else
printf("funcr(<0x%lx> entry:0x%x)\n", printf("funcr:\n (<0x%lx> entry:0x%x)\n",
(uint64_t)gc.funcr.value.gcobj, (uint64_t)gc.funcr.value.gcobj,
gc.funcr.func().entry); gc.funcr.func().entry);
global_state(); global_state();

View File

@ -1,90 +1,156 @@
import("lib.nas"); import("lib.nas");
var check=func(x){
return x-int(x/0x100000000)*0x100000000;
}
var bits_and=func(x,y){
x=check(x);
y=check(y);
var (res,op)=(0,1);
for(var i=0;i<32;i+=1){
var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2);
res+=op*(tmpx==1 and tmpy==1);
x=int(x/2);
y=int(y/2);
op*=2;
}
return res;
}
var bits_or=func(x,y){
x=check(x);
y=check(y);
var (res,op)=(0,1);
for(var i=0;i<32;i+=1){
var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2);
res+=op*(tmpx==1 or tmpy==1);
x=int(x/2);
y=int(y/2);
op*=2;
}
return res;
}
var bits_xor=func(x,y){
x=check(x);
y=check(y);
var (res,op)=(0,1);
for(var i=0;i<32;i+=1){
var (tmpx,tmpy)=(x-int(x/2)*2,y-int(y/2)*2);
res+=op*(tmpx!=tmpy);
x=int(x/2);
y=int(y/2);
op*=2;
}
return res;
}
var bits_not=func(x){
x=check(x);
var (res,op)=(0,1);
for(var i=0;i<32;i+=1){
res+=op*((x-int(x/2)*2)==1?0:1);
x=int(x/2);
op*=2;
}
return res;
}
var hex32str=func(num){
var ch="0123456789abcdef";
var res="";
for(var i=0;i<4;i+=1){
var tmp="";
for(var j=0;j<2;j+=1){
tmp=chr(ch[bits_and(num,0x0f)])~tmp;
num=int(num/16);
}
res~=tmp;
}
return res;
}
var md5=func(s){ var md5=func(s){
var K=[ var K=[
0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee, 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244,
0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,
0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314,
0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391
]; ];
var S=[ var S=[
7,12,17,22, 7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
7,12,17,22, 5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
7,12,17,22, 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
7,12,17,22, 6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
5,9,14,20,
5,9,14,20,
5,9,14,20,
5,9,14,20,
4,11,16,23,
4,11,16,23,
4,11,16,23,
4,11,16,23,
6,10,15,21,
6,10,15,21,
6,10,15,21,
6,10,15,21
]; ];
var idx=[
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
];
var l=func(num,cx){ var l=func(num,cx){
for(var i=0;i<cx;i+=1) for(var i=0;i<cx;i+=1){
num=bits.bitand(0xffffffff,num*2); num=check(num*2);
}
return num; return num;
} }
var r=func(num,cx){ var r=func(num,cx){
for(var i=0;i<cx;i+=1) num=check(num);
num=int(num/2); for(var i=0;i<cx;i+=1){
return num; num=num/2;
}
return int(num);
} }
var rol=func(num,cx){ var rol=func(num,cx){
if(cx>32) return bits_or(l(num,cx),r(num,32-cx));
cx=cx-int(cx/32)*32;
return bits.bitor(l(num,cx),r(num,32-cx));
} }
# round 1
var F=func(x,y,z){ var F=func(x,y,z){
return bits.bitor( return bits_or(
bits.bitand(x,y), bits_and(x,y),
bits.bitand(bits.bitnot(x),z) bits_and(bits_not(x),z)
); );
} }
# round 2
var G=func(x,y,z){ var G=func(x,y,z){
return bits.bitor( return bits_or(
bits.bitand(x,z), bits_and(x,z),
bits.bitand(y,bits.bitnot(z)) bits_and(y,bits_not(z))
); );
} }
# round 3
var H=func(x,y,z){ var H=func(x,y,z){
return bits.bitxor(bits.bitxor(x,y),z); return bits_xor(bits_xor(x,y),z);
} }
# round 4
var I=func(x,y,z){ var I=func(x,y,z){
return bits.bitor( return bits_xor(
bits.bitxor(x,y), y,
bits.bitnot(z) bits_or(x,bits_not(z))
); );
} }
var len=size(s); var len=size(s)*8;
var res=[]; var res=[];
var v=[256,128,64,32,16,8,4,2,1]; var v=[128,64,32,16,8,4,2,1];
for(var i=0;i<size(s);i+=1){ for(var i=0;i<size(s);i+=1){
var c=s[i]; var c=s[i];
foreach(var j;v){ foreach(var j;v){
append(res,bits.bitand(c,j)?1:0); append(res,bits.bitand(c,j)?1:0);
} }
} }
# +------len------+--1~512--+--64--+
# | text | fill | size |
# +---------------+---------+------+ N*512
var mod=size(res)-int(size(res)/512)*512; var mod=size(res)-int(size(res)/512)*512;
if(mod==0){ if(mod==448){
append(res,1); append(res,1);
mod+=1; for(var i=0;i<511;i+=1)
for(;mod<448;mod+=1)
append(res,0); append(res,0);
}elsif(mod<448){ }elsif(mod<448){
append(res,1); append(res,1);
@ -94,16 +160,105 @@ var md5=func(s){
}elsif(mod>448){ }elsif(mod>448){
append(res,1); append(res,1);
mod+=1; mod+=1;
for(;mod<512+448;mod+=1) # 512+448=960
for(;mod<960;mod+=1)
append(res,0); append(res,0);
} }
var tmp=[]; var (tmp,cnt,t)=([],0,0);
foreach(var i;res){
if(!cnt)
t=i;
else
t=t*2+i;
cnt+=1;
if(cnt==8){
cnt=0;
append(tmp,t);
}
}
var A=0x01234567; # little endian, this may have number overflow bug
var B=0x89abcdef; # if the number is too large
var C=0xfedcba98; var (lower32,higher32)=(check(len),check(len/math.pow(2,32)));
var D=0x76543210; for(var i=0;i<4;i+=1){
println(res,' ',size(res)); append(tmp,int(lower32-int(lower32/256)*256));
lower32=int(lower32/256);
}
for(var i=0;i<4;i+=1){
append(tmp,int(higher32-int(higher32/256)*256));
higher32=int(higher32/256);
}
res=tmp;
# 1 block=>16 uint32=>64 byte=>512 bit
tmp=[];
for(var i=0;i<size(res);i+=4){
append(tmp,
res[i+3]*math.pow(2,24)+
res[i+2]*math.pow(2,16)+
res[i+1]*math.pow(2,8)+
res[i]
);
}
res=tmp;
var A=0x67452301;
var B=0xefcdab89;
var C=0x98badcfe;
var D=0x10325476;
for(var i=0;i<size(res);i+=16){
var (f,a,b,c,d)=(0,A,B,C,D);
for(var j=0;j<64;j+=1){
if(j<16){
f=F(b,c,d);
}elsif(j<32){
f=G(b,c,d);
}elsif(j<48){
f=H(b,c,d);
}else{
f=I(b,c,d);
}
var tmp=d;
d=c;
c=b;
b=check(b+rol(a+f+K[j]+res[idx[j]],S[j]));
a=tmp;
}
A=check(a+A);
B=check(b+B);
C=check(c+C);
D=check(d+D);
}
return hex32str(A)~hex32str(B)~hex32str(C)~hex32str(D);
} }
md5("helloworld"); func(){
var test_set=[
"github.com",
"helloworld",
"abc",
"https://www.github.com/ValKmjolnir/Nasal-Interpreter",
"https://github.com/andyross/nasal",
"var (lower32,higher32)=(check(len),check(len/math.pow(2,32)));",
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
];
var result=[
"99cd2175108d157588c04758296d1cfc",
"fc5e038d38a57032085441e7fe7010b0",
"900150983cd24fb0d6963f7d28e17f72",
"6b3a7bbc2240046c4fb1b0b3a4ed8181",
"14a6afca5f3a7b239c56b5a9678c428e",
"f499377c9ae8454c6c8a21ddba7f00de",
"fdacad297f72956e0619002cecffc8e3"
];
forindex(var i;test_set)
if(cmp(md5(test_set[i]),result[i]))
println(
"md5 cannot work:\n",
" test \""~test_set[i]~"\"\n",
" result \""~result[i]~"\"\n",
" but get \""~md5(test_set[i])~"\"\n"
);
}();