Scoobydooo
01-20-2009, 11:47 AM
This seems to be working.
Thanks to mpc30 for the new map code.
Thanks to ALL cemu coders who keep cemu alive!
{ // module 1 for NA (20080502 [1,2,3,4,5,6,7,8,9,10,11,12,13,14])
//
/*
If your wondering what m and A00[3] are...
m = the map call to check for. In Chief's example m = 0x3B, so we know we have a map 0x3B
interrupt were working with.
A00[3] is the value that gets loaded into timer 2 latch, or register 0x15. In this case
it's 0x6A. That register along with register 0x16, timer 2 prescale register, which
basically determines how many clock cycles it takes to decrement register 0x15, determine
how many cycles the timer is allowed to run before it reaches 0 and interrupts the map call.
Together, we get a unique signature for where we want to direct the flow of the code and
handle the interrupt.
fb
*/
BIGNUM *A=BN_new(); BIGNUM *B=BN_new(); BIGNUM *C=BN_new(); BIGNUM *D=BN_new();
BIGNUM *J=BN_new(); BIGNUM *Z=BN_new(); BN_CTX *ctx=BN_CTX_new();
unsigned char *_a=hw,*_b=&hw[0x10],*_c=&hw[0x20],*_d=&hw[0x30],*_j=&hw[0x40],*_z=hw;
unsigned int m=0x27+0x72+(A00[4]&0x3F)-0x79;
unsigned char xr=((A00[2]-1)&3)+0x0A;
A00[0]|=A00[9];
memset(hw,0,sizeof(hw));
memcpy(hw,A00,0x05);
ExpandInput(hw);
printf("\nhw=%s\n", GetBufStr(hw,72));
RotateBytes(_a,0x10); BN_bin2bn(_a,0x10,A); RotateBytes(_a,0x10);
RotateBytes(_b,0x10); BN_bin2bn(_b,0x10,B);
RotateBytes(_c,0x10); BN_bin2bn(_c,0x10,C);
RotateBytes(_d,0x10); BN_bin2bn(_d,0x10,D);
RotateBytes(_j,0x08); BN_bin2bn(_j,0x08,J);
char buf[128];
char * pbuf = &buf[0];
// char * pbuf = new char(128);
pbuf = BN_bn2hex(A);
printf("A=%s\n", pbuf);
pbuf = BN_bn2hex(B);
printf("B=%s\n", pbuf);
pbuf = BN_bn2hex(C);
printf("C=%s\n", pbuf);
pbuf = BN_bn2hex(D);
printf("D=%s\n", pbuf);
pbuf = BN_bn2hex(J);
printf("J=%s\n", pbuf);
// delete pbuf;
unsigned int hexcode = ((m << 8) | A00[3]); //mpc
printf("Map call %04X\n", hexcode);
if ((hexcode >= 0x2100) && (hexcode <= 0x21FF)) hexcode = 0x21FF; //mpc fix case range prob
// switch ((m<<8)|A00[3])
switch (hexcode) //mpc
{
case 0x395A:
{
BN_zero(C);
BN_zero(B);
BN_set_bit(B,64);
BN_copy(Z,B);
memset(_z,0,0x10);
}
break;
case 0x3963:
case 0x3967:
case 0x393E:
BN_rshift(Z,C,64);
BN_lshift(Z,Z,64);
memset(_z,0,0x10);
break;
case 0x3B6A:
case 0x3B89:
{
BIGNUM *v=BN_new();
BN_zero(v);
BN_set_bit(v,128);
BN_mod(Z,v,D,ctx);
memset(_z,0,0x10);
BN_free(v);
}
break;
case 0x3A75:
BN_mask_bits(B,64);
BN_copy(Z,B);
memset(_z,0,8);
break;
case 0x3A81:
{
BIGNUM *s = BN_new();
BIGNUM *x = BN_new();
BIGNUM *y = BN_new();
BIGNUM *v = BN_new();
BN_zero(v);
BN_sub(J,v,D);
BN_set_bit(J,0);
BN_set_bit(v,64);
BN_mod_inverse(J,J,v,ctx);
BN_mask_bits(J,64);
BN_zero(v);
BN_set_bit(v,136);
BN_mod(B,v,D,ctx);
for (int j=0;j<1;j++)
{
int Boctets=(BN_num_bytes(B)+7)>>3;
BN_zero(s);
for (int i=0; i<Boctets; i++)
{
BN_rshift(x,B,i<<6);
BN_mask_bits(x,64);
BN_mul(x,x,B,ctx);
BN_add(s,s,x);
BN_copy(x,s);
BN_mask_bits(x,64);
BN_mul(x,x,J,ctx);
BN_lshift(C,x,64);
BN_add(C,C,x);
BN_rshift(C,C,2);
BN_add(C,C,s);
BN_rshift(C,C,52);
BN_mask_bits(C,12);
BN_mask_bits(x,64);
BN_mul(x,x,D,ctx);
BN_add(s,s,x);
BN_lshift(y,s,12);
BN_add(C,C,y);
BN_mask_bits(C,128);
BN_rshift(s,s,64);
BN_copy(Z,s);
BN_mod(s,s,D,ctx);
}
BN_copy(B,s);
}
if (xr==0x0C)
{
BN_copy(Z,C);
}
BN_mask_bits(Z,128);
memset(_z,0,0x10);
BN_free(s); BN_free(x); BN_free(y); BN_free(v);
}
break;
case 0x3A9C:
{
BIGNUM *s = BN_new();
BIGNUM *x = BN_new();
BIGNUM *y = BN_new();
BIGNUM *v = BN_new();
BN_zero(v);
BN_sub(J,v,D);
BN_set_bit(J,0);
BN_set_bit(v,64);
BN_mod_inverse(J,J,v,ctx);
BN_mask_bits(J,64);
BN_zero(v);
BN_set_bit(v,136);
BN_mod(B,v,D,ctx);
for (int j=0;j<4;j++)
{
int Boctets=(BN_num_bytes(B)+7)>>3;
BN_zero(s);
for (int i=0; i<Boctets; i++)
{
BN_rshift(x,B,i<<6);
BN_mask_bits(x,64);
BN_mul(x,x,B,ctx);
BN_add(s,s,x);
BN_copy(x,s);
BN_mask_bits(x,64);
BN_mul(x,x,J,ctx);
BN_lshift(C,x,64);
BN_add(C,C,x);
BN_rshift(C,C,2);
BN_add(C,C,s);
BN_rshift(C,C,52);
BN_mask_bits(C,12);
BN_mask_bits(x,64);
BN_mul(x,x,D,ctx);
BN_add(s,s,x);
BN_lshift(y,s,12);
BN_add(C,C,y);
BN_mask_bits(C,128);
BN_rshift(s,s,64);
BN_copy(Z,s);
BN_mod(s,s,D,ctx);
}
BN_copy(B,s);
}
BN_zero(s);
for (int i=0; i<2; i++)
{
BN_rshift(x,A,i<<6);
BN_mask_bits(x,64);
BN_mul(x,x,B,ctx);
BN_add(s,s,x);
BN_copy(x,s);
BN_mask_bits(x,64);
BN_mul(x,x,J,ctx);
BN_lshift(C,x,64);
BN_add(C,C,x);
BN_rshift(C,C,2);
BN_add(C,C,s);
BN_rshift(C,C,52);
BN_mask_bits(C,12);
BN_mask_bits(x,64);
BN_mul(x,x,D,ctx);
BN_add(s,s,x);
BN_lshift(y,s,12);
BN_add(C,C,y);
BN_mask_bits(C,128);
BN_rshift(s,s,64);
BN_copy(Z,s);
BN_mod(s,s,D,ctx);
}
BN_copy(B,s);
if (xr==0x0C)
{
BN_copy(Z,C);
}
BN_mask_bits(Z,128);
memset(_z,0,0x10);
BN_free(s); BN_free(x); BN_free(y); BN_free(v);
}
break;
case 0x3AC9:
{
BIGNUM *tmp1 = BN_new();
BIGNUM *tmp2 = BN_new();
BIGNUM *tmp3 = BN_new();
BN_rshift(tmp1,D,64);
BN_mask_bits(tmp1,64);
BN_lshift(tmp1,tmp1,64);
BN_copy(tmp2,D);
BN_mask_bits(tmp2,64);
BN_rshift(tmp2,tmp2,16);
BN_copy(tmp3,D);
BN_mask_bits(tmp3,16);
BN_lshift(tmp3,tmp3,48);
BN_copy(D,tmp1);
BN_add(D,D,tmp2);
BN_add(D,D,tmp3);
BN_copy(Z,D);
memset(_z,0,8);
BN_free(tmp1);
BN_free(tmp2);
BN_free(tmp3);
}
break;
case 0x3AF7:
{
BN_zero(Z); //doesn't work reliably due to RotateBytes with len=0 <- made it conditional at end of module1
// BN_set_bit(Z,128);
memset(_z,0,0x10);
}
break;
case 0x3986:
case 0x3A58:
case 0x3E68:
case 0x3E8C:
{
BIGNUM *v=BN_new();
BN_zero(v);
BN_set_bit(v,136);
BN_mod(Z,v,D,ctx);
memset(_z,0,0x10);
BN_free(v);
}
break;
//case 0x2100 ... 0x21FF: //mpc
case 0x21FF: //mpc
case 0x39B0:
case 0x3BB0:
case 0x3EAE:
{
BIGNUM *v=BN_new();
BN_zero(v);
BN_sub(J,v,D);
BN_set_bit(J,0);
BN_set_bit(v,64);
BN_mod_inverse(J,J,v,ctx); //J = ~(J % v) maybe?
BN_mask_bits(J,64);
BN_mod(D,D,v,ctx);
BN_mul(C,J,D,ctx);
BN_rshift(C,C,64);
BN_mask_bits(C,64);
BN_copy(Z,C);
memset(_z,0,8);
BN_free(v);
}
break;
case 0x25AB:
{
BIGNUM *v=BN_new();
BN_zero(v);
BN_sub(B,v,D);
BN_set_bit(B,0);
BN_set_bit(v,128);
BN_mod_inverse(B,B,v,ctx);
BN_mask_bits(B,128);
BN_mod(D,D,v,ctx);
BN_mul(C,B,D,ctx);
BN_rshift(C,C,128);
BN_mask_bits(C,128);
BN_copy(Z,C);
memset(_z,0,0x10);
BN_free(v);
}
break;
case 0x3846:
{
BIGNUM *s = BN_new();
BIGNUM *x = BN_new();
int Boctets=(BN_num_bytes(B)+7)>>3;
BN_zero(s);
for(int i=0; i<Boctets; i++) {
BN_rshift(x,B,i<<6);
BN_mask_bits(x,64);
BN_mul(x,x,B,ctx);
BN_add(s,s,x);
BN_copy(x,s);
BN_mask_bits(x,64);
BN_mul(x,x,J,ctx);
BN_mask_bits(x,64);
BN_mul(x,x,D,ctx);
BN_add(s,s,x);
BN_rshift(s,s,64);
BN_copy(Z,s);
if(BN_cmp(s,D)==1) BN_sub(s,s,D);
}
BN_mask_bits(Z,128);
memset(_z,0,0x10);
BN_free(s); BN_free(x);
}
break;
case 0x3E92:
BN_copy(Z,A);
memset(_z,0,0x10);
break;
case 0x3E90:
case 0x3E95:
case 0x3C9F:
case 0x3CA5:
case 0x3CAA:
{
BIGNUM *s = BN_new();
BIGNUM *x = BN_new();
BIGNUM *y = BN_new();
BIGNUM *v = BN_new();
BN_zero(v);
BN_sub(J,v,D);
BN_set_bit(J,0);
BN_set_bit(v,64);
BN_mod_inverse(J,J,v,ctx);
BN_mask_bits(J,64);
BN_zero(v);
BN_set_bit(v,136);
BN_mod(B,v,D,ctx); //B = v % D
for(int j=0;j<((A00[3]-0x85)>>3);j++) { //loops - 3e90/5=1, 3c9f=2, 3ca5=3, 3caa=3
//Following code is equivalent of MonMul3e(B,B,B)
int Boctets=(BN_num_bytes(B)+7)>>3;
BN_zero(s);
for(int i=0; i<Boctets; i++) {
BN_rshift(x,B,i<<6); //x = B >> (i*64)
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,B,ctx); //x = x * B
BN_add(s,s,x); //s = s + x
BN_copy(x,s); //x = s
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,J,ctx); //x = x * J
BN_lshift(C,x,64); //C = x << 64
BN_add(C,C,x); //C = C + x
BN_rshift(C,C,2); //C = C >> 2
BN_add(C,C,s); //C = C + s
BN_rshift(C,C,52); //C = C >> 52
BN_mask_bits(C,12); //C & 0FFF
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,D,ctx); //x = x * D
BN_add(s,s,x); //s = s + x
BN_lshift(y,s,12); //y = s << 12
BN_add(C,C,y); //C = C + y
BN_mask_bits(C,128); //C & 128bits
BN_rshift(s,s,64); //s = s >> 64
BN_copy(Z,s); //Z = s //in MonMul3e this is BN_copy(H,s);
BN_mod(s,s,D,ctx); //s = s % D
}
BN_copy(B,s);
}
if (A00[3] == 0xAA)
{ //following code is equivalent of MonMul3e(B,A,B)
int Aoctets=(BN_num_bytes(A)+7)>>3;
BN_zero(s);
for(int i=0; i<Aoctets; i++) {
BN_rshift(x,A,i<<6); //x = B >> (i*64)
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,B,ctx); //x = x * B
BN_add(s,s,x); //s = s + x
BN_copy(x,s); //x = s
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,J,ctx); //x = x * J
BN_lshift(C,x,64); //C = x << 64
BN_add(C,C,x); //C = C + x
BN_rshift(C,C,2); //C = C >> 2
BN_add(C,C,s); //C = C + s
BN_rshift(C,C,52); //C = C >> 52
BN_mask_bits(C,12); //C & 0FFF
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,D,ctx); //x = x * D
BN_add(s,s,x); //s = s + x
BN_lshift(y,s,12); //y = s << 12
BN_add(C,C,y); //C = C + y
BN_mask_bits(C,128); //C & 128bits
BN_rshift(s,s,64); //s = s >> 64
BN_copy(Z,s); //Z = s //in MonMul3e this is BN_copy(H,s);
BN_mod(s,s,D,ctx); //s = s % D
}
}
if (xr==0x0C) BN_copy(Z,C);
BN_mask_bits(Z,128);
memset(_z,0,0x10);
BN_free(s); BN_free(x); BN_free(y); BN_free(v);
}
break;
case 0x3D6D:
{
BIGNUM *s = BN_new();
BIGNUM *x = BN_new();
BIGNUM *i1 = BN_new();
BIGNUM *i2 = BN_new();
BIGNUM *o = BN_new();
//D.GetLE(data,16); //could be. same thing for this case
//D.GetLE(data,(l<=0? l:wordsize)<<3);
RotateBytes(&hw[0x50],0x10);
BN_bin2bn(&hw[0x50],0x10,D);
BN_copy(i1,B);
BN_copy(i2,B);
//MakeJ();
BN_zero(x);
BN_sub(J,x,D);
BN_set_bit(J,0);
BN_set_bit(x,64);
BN_mod_inverse(J,J,x,ctx);
BN_mask_bits(J,64);
//MonMul3d(C,B,B);
//int Boctets=(BN_num_bytes(B)+7)>>3;
BN_zero(s);
for (int i=0; i<2; i++)
{
BN_rshift(x,i1,i<<6);
BN_mask_bits(x,64);
BN_mul(x,x,i2,ctx);
BN_add(s,s,x);
BN_copy(x,s);
BN_mask_bits(x,64);
BN_mul(x,x,J,ctx);
BN_mask_bits(x,64);
BN_mul(x,x,D,ctx);
BN_add(s,s,x);
BN_rshift(s,s,64);
BN_copy(o,s);
if (BN_cmp(s,D)==1)
{
BN_copy(x,s);
BN_sub(s,x,D);
}
}
BN_mask_bits(o,128);
BN_copy(Z,o);
memset(_z,0,0x10);
BN_free(s); BN_free(x); BN_free(i1); BN_free(i2); BN_free(o);
}
break;
case 0x4692:
{
BIGNUM *s = BN_new();
BIGNUM *x = BN_new();
BIGNUM *y = BN_new();
BIGNUM *v = BN_new();
BN_zero(v);
BN_sub(J,v,D);
BN_set_bit(J,0);
BN_set_bit(v,64);
BN_mod_inverse(J,J,v,ctx);
BN_mask_bits(J,64);
BN_zero(v);
BN_set_bit(v,136);
BN_mod(B,v,D,ctx); //B = v % D
for(int j=0;j<2;j++) {
//Following code is equivalent to MonMul3e(B,B,B)
int Boctets=(BN_num_bytes(B)+7)>>3;
BN_zero(s);
for(int i=0; i<Boctets; i++) {
BN_rshift(x,B,i<<6); //x = B >> (i*64)
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,B,ctx); //x = x * B
BN_add(s,s,x); //s = s + x
BN_copy(x,s); //x = s
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,J,ctx); //x = x * J
BN_lshift(C,x,64); //C = x << 64
BN_add(C,C,x); //C = C + x
BN_rshift(C,C,2); //C = C >> 2
BN_add(C,C,s); //C = C + s
BN_rshift(C,C,52); //C = C >> 52
BN_mask_bits(C,12); //C & 0FFF
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,D,ctx); //x = x * D
BN_add(s,s,x); //s = s + x
BN_lshift(y,s,12); //y = s << 12
BN_add(C,C,y); //C = C + y
BN_mask_bits(C,128); //C & 128bits
BN_rshift(s,s,64); //s = s >> 64
BN_copy(Z,s); //Z = s //in MonMul3e this is BN_copy(H,s);
BN_mod(s,s,D,ctx); //s = s % D
}
BN_copy(B,s);
}
if (xr==0x0C) BN_copy(Z,C);
BN_mask_bits(Z,128);
memset(_z,0,0x10);
BN_free(s); BN_free(x); BN_free(y); BN_free(v);
}
break;
default:
// unsigned int hexcode = ((m << 8) | A00[3]); //mpc
printf("Unknown Map call %04X\n", hexcode); //mpc
BN_copy(Z,A); //need this else debugger barfs with stack corruption
memset(_z,0,0x10); //may need this too
break;
}
BN_bn2bin(Z,_z);
if (BN_num_bytes(Z) > 0) RotateBytes(_z,BN_num_bytes(Z));
for (int i=11;i>-1;i--) hw[i]^=hw[i+4]; memset(&hw[4],0,0x7C);
BN_free(A); BN_free(B); BN_free(C); BN_free(D);
BN_free(J); BN_free(Z); BN_CTX_free(ctx);
}
Scoob
Thanks to mpc30 for the new map code.
Thanks to ALL cemu coders who keep cemu alive!
{ // module 1 for NA (20080502 [1,2,3,4,5,6,7,8,9,10,11,12,13,14])
//
/*
If your wondering what m and A00[3] are...
m = the map call to check for. In Chief's example m = 0x3B, so we know we have a map 0x3B
interrupt were working with.
A00[3] is the value that gets loaded into timer 2 latch, or register 0x15. In this case
it's 0x6A. That register along with register 0x16, timer 2 prescale register, which
basically determines how many clock cycles it takes to decrement register 0x15, determine
how many cycles the timer is allowed to run before it reaches 0 and interrupts the map call.
Together, we get a unique signature for where we want to direct the flow of the code and
handle the interrupt.
fb
*/
BIGNUM *A=BN_new(); BIGNUM *B=BN_new(); BIGNUM *C=BN_new(); BIGNUM *D=BN_new();
BIGNUM *J=BN_new(); BIGNUM *Z=BN_new(); BN_CTX *ctx=BN_CTX_new();
unsigned char *_a=hw,*_b=&hw[0x10],*_c=&hw[0x20],*_d=&hw[0x30],*_j=&hw[0x40],*_z=hw;
unsigned int m=0x27+0x72+(A00[4]&0x3F)-0x79;
unsigned char xr=((A00[2]-1)&3)+0x0A;
A00[0]|=A00[9];
memset(hw,0,sizeof(hw));
memcpy(hw,A00,0x05);
ExpandInput(hw);
printf("\nhw=%s\n", GetBufStr(hw,72));
RotateBytes(_a,0x10); BN_bin2bn(_a,0x10,A); RotateBytes(_a,0x10);
RotateBytes(_b,0x10); BN_bin2bn(_b,0x10,B);
RotateBytes(_c,0x10); BN_bin2bn(_c,0x10,C);
RotateBytes(_d,0x10); BN_bin2bn(_d,0x10,D);
RotateBytes(_j,0x08); BN_bin2bn(_j,0x08,J);
char buf[128];
char * pbuf = &buf[0];
// char * pbuf = new char(128);
pbuf = BN_bn2hex(A);
printf("A=%s\n", pbuf);
pbuf = BN_bn2hex(B);
printf("B=%s\n", pbuf);
pbuf = BN_bn2hex(C);
printf("C=%s\n", pbuf);
pbuf = BN_bn2hex(D);
printf("D=%s\n", pbuf);
pbuf = BN_bn2hex(J);
printf("J=%s\n", pbuf);
// delete pbuf;
unsigned int hexcode = ((m << 8) | A00[3]); //mpc
printf("Map call %04X\n", hexcode);
if ((hexcode >= 0x2100) && (hexcode <= 0x21FF)) hexcode = 0x21FF; //mpc fix case range prob
// switch ((m<<8)|A00[3])
switch (hexcode) //mpc
{
case 0x395A:
{
BN_zero(C);
BN_zero(B);
BN_set_bit(B,64);
BN_copy(Z,B);
memset(_z,0,0x10);
}
break;
case 0x3963:
case 0x3967:
case 0x393E:
BN_rshift(Z,C,64);
BN_lshift(Z,Z,64);
memset(_z,0,0x10);
break;
case 0x3B6A:
case 0x3B89:
{
BIGNUM *v=BN_new();
BN_zero(v);
BN_set_bit(v,128);
BN_mod(Z,v,D,ctx);
memset(_z,0,0x10);
BN_free(v);
}
break;
case 0x3A75:
BN_mask_bits(B,64);
BN_copy(Z,B);
memset(_z,0,8);
break;
case 0x3A81:
{
BIGNUM *s = BN_new();
BIGNUM *x = BN_new();
BIGNUM *y = BN_new();
BIGNUM *v = BN_new();
BN_zero(v);
BN_sub(J,v,D);
BN_set_bit(J,0);
BN_set_bit(v,64);
BN_mod_inverse(J,J,v,ctx);
BN_mask_bits(J,64);
BN_zero(v);
BN_set_bit(v,136);
BN_mod(B,v,D,ctx);
for (int j=0;j<1;j++)
{
int Boctets=(BN_num_bytes(B)+7)>>3;
BN_zero(s);
for (int i=0; i<Boctets; i++)
{
BN_rshift(x,B,i<<6);
BN_mask_bits(x,64);
BN_mul(x,x,B,ctx);
BN_add(s,s,x);
BN_copy(x,s);
BN_mask_bits(x,64);
BN_mul(x,x,J,ctx);
BN_lshift(C,x,64);
BN_add(C,C,x);
BN_rshift(C,C,2);
BN_add(C,C,s);
BN_rshift(C,C,52);
BN_mask_bits(C,12);
BN_mask_bits(x,64);
BN_mul(x,x,D,ctx);
BN_add(s,s,x);
BN_lshift(y,s,12);
BN_add(C,C,y);
BN_mask_bits(C,128);
BN_rshift(s,s,64);
BN_copy(Z,s);
BN_mod(s,s,D,ctx);
}
BN_copy(B,s);
}
if (xr==0x0C)
{
BN_copy(Z,C);
}
BN_mask_bits(Z,128);
memset(_z,0,0x10);
BN_free(s); BN_free(x); BN_free(y); BN_free(v);
}
break;
case 0x3A9C:
{
BIGNUM *s = BN_new();
BIGNUM *x = BN_new();
BIGNUM *y = BN_new();
BIGNUM *v = BN_new();
BN_zero(v);
BN_sub(J,v,D);
BN_set_bit(J,0);
BN_set_bit(v,64);
BN_mod_inverse(J,J,v,ctx);
BN_mask_bits(J,64);
BN_zero(v);
BN_set_bit(v,136);
BN_mod(B,v,D,ctx);
for (int j=0;j<4;j++)
{
int Boctets=(BN_num_bytes(B)+7)>>3;
BN_zero(s);
for (int i=0; i<Boctets; i++)
{
BN_rshift(x,B,i<<6);
BN_mask_bits(x,64);
BN_mul(x,x,B,ctx);
BN_add(s,s,x);
BN_copy(x,s);
BN_mask_bits(x,64);
BN_mul(x,x,J,ctx);
BN_lshift(C,x,64);
BN_add(C,C,x);
BN_rshift(C,C,2);
BN_add(C,C,s);
BN_rshift(C,C,52);
BN_mask_bits(C,12);
BN_mask_bits(x,64);
BN_mul(x,x,D,ctx);
BN_add(s,s,x);
BN_lshift(y,s,12);
BN_add(C,C,y);
BN_mask_bits(C,128);
BN_rshift(s,s,64);
BN_copy(Z,s);
BN_mod(s,s,D,ctx);
}
BN_copy(B,s);
}
BN_zero(s);
for (int i=0; i<2; i++)
{
BN_rshift(x,A,i<<6);
BN_mask_bits(x,64);
BN_mul(x,x,B,ctx);
BN_add(s,s,x);
BN_copy(x,s);
BN_mask_bits(x,64);
BN_mul(x,x,J,ctx);
BN_lshift(C,x,64);
BN_add(C,C,x);
BN_rshift(C,C,2);
BN_add(C,C,s);
BN_rshift(C,C,52);
BN_mask_bits(C,12);
BN_mask_bits(x,64);
BN_mul(x,x,D,ctx);
BN_add(s,s,x);
BN_lshift(y,s,12);
BN_add(C,C,y);
BN_mask_bits(C,128);
BN_rshift(s,s,64);
BN_copy(Z,s);
BN_mod(s,s,D,ctx);
}
BN_copy(B,s);
if (xr==0x0C)
{
BN_copy(Z,C);
}
BN_mask_bits(Z,128);
memset(_z,0,0x10);
BN_free(s); BN_free(x); BN_free(y); BN_free(v);
}
break;
case 0x3AC9:
{
BIGNUM *tmp1 = BN_new();
BIGNUM *tmp2 = BN_new();
BIGNUM *tmp3 = BN_new();
BN_rshift(tmp1,D,64);
BN_mask_bits(tmp1,64);
BN_lshift(tmp1,tmp1,64);
BN_copy(tmp2,D);
BN_mask_bits(tmp2,64);
BN_rshift(tmp2,tmp2,16);
BN_copy(tmp3,D);
BN_mask_bits(tmp3,16);
BN_lshift(tmp3,tmp3,48);
BN_copy(D,tmp1);
BN_add(D,D,tmp2);
BN_add(D,D,tmp3);
BN_copy(Z,D);
memset(_z,0,8);
BN_free(tmp1);
BN_free(tmp2);
BN_free(tmp3);
}
break;
case 0x3AF7:
{
BN_zero(Z); //doesn't work reliably due to RotateBytes with len=0 <- made it conditional at end of module1
// BN_set_bit(Z,128);
memset(_z,0,0x10);
}
break;
case 0x3986:
case 0x3A58:
case 0x3E68:
case 0x3E8C:
{
BIGNUM *v=BN_new();
BN_zero(v);
BN_set_bit(v,136);
BN_mod(Z,v,D,ctx);
memset(_z,0,0x10);
BN_free(v);
}
break;
//case 0x2100 ... 0x21FF: //mpc
case 0x21FF: //mpc
case 0x39B0:
case 0x3BB0:
case 0x3EAE:
{
BIGNUM *v=BN_new();
BN_zero(v);
BN_sub(J,v,D);
BN_set_bit(J,0);
BN_set_bit(v,64);
BN_mod_inverse(J,J,v,ctx); //J = ~(J % v) maybe?
BN_mask_bits(J,64);
BN_mod(D,D,v,ctx);
BN_mul(C,J,D,ctx);
BN_rshift(C,C,64);
BN_mask_bits(C,64);
BN_copy(Z,C);
memset(_z,0,8);
BN_free(v);
}
break;
case 0x25AB:
{
BIGNUM *v=BN_new();
BN_zero(v);
BN_sub(B,v,D);
BN_set_bit(B,0);
BN_set_bit(v,128);
BN_mod_inverse(B,B,v,ctx);
BN_mask_bits(B,128);
BN_mod(D,D,v,ctx);
BN_mul(C,B,D,ctx);
BN_rshift(C,C,128);
BN_mask_bits(C,128);
BN_copy(Z,C);
memset(_z,0,0x10);
BN_free(v);
}
break;
case 0x3846:
{
BIGNUM *s = BN_new();
BIGNUM *x = BN_new();
int Boctets=(BN_num_bytes(B)+7)>>3;
BN_zero(s);
for(int i=0; i<Boctets; i++) {
BN_rshift(x,B,i<<6);
BN_mask_bits(x,64);
BN_mul(x,x,B,ctx);
BN_add(s,s,x);
BN_copy(x,s);
BN_mask_bits(x,64);
BN_mul(x,x,J,ctx);
BN_mask_bits(x,64);
BN_mul(x,x,D,ctx);
BN_add(s,s,x);
BN_rshift(s,s,64);
BN_copy(Z,s);
if(BN_cmp(s,D)==1) BN_sub(s,s,D);
}
BN_mask_bits(Z,128);
memset(_z,0,0x10);
BN_free(s); BN_free(x);
}
break;
case 0x3E92:
BN_copy(Z,A);
memset(_z,0,0x10);
break;
case 0x3E90:
case 0x3E95:
case 0x3C9F:
case 0x3CA5:
case 0x3CAA:
{
BIGNUM *s = BN_new();
BIGNUM *x = BN_new();
BIGNUM *y = BN_new();
BIGNUM *v = BN_new();
BN_zero(v);
BN_sub(J,v,D);
BN_set_bit(J,0);
BN_set_bit(v,64);
BN_mod_inverse(J,J,v,ctx);
BN_mask_bits(J,64);
BN_zero(v);
BN_set_bit(v,136);
BN_mod(B,v,D,ctx); //B = v % D
for(int j=0;j<((A00[3]-0x85)>>3);j++) { //loops - 3e90/5=1, 3c9f=2, 3ca5=3, 3caa=3
//Following code is equivalent of MonMul3e(B,B,B)
int Boctets=(BN_num_bytes(B)+7)>>3;
BN_zero(s);
for(int i=0; i<Boctets; i++) {
BN_rshift(x,B,i<<6); //x = B >> (i*64)
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,B,ctx); //x = x * B
BN_add(s,s,x); //s = s + x
BN_copy(x,s); //x = s
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,J,ctx); //x = x * J
BN_lshift(C,x,64); //C = x << 64
BN_add(C,C,x); //C = C + x
BN_rshift(C,C,2); //C = C >> 2
BN_add(C,C,s); //C = C + s
BN_rshift(C,C,52); //C = C >> 52
BN_mask_bits(C,12); //C & 0FFF
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,D,ctx); //x = x * D
BN_add(s,s,x); //s = s + x
BN_lshift(y,s,12); //y = s << 12
BN_add(C,C,y); //C = C + y
BN_mask_bits(C,128); //C & 128bits
BN_rshift(s,s,64); //s = s >> 64
BN_copy(Z,s); //Z = s //in MonMul3e this is BN_copy(H,s);
BN_mod(s,s,D,ctx); //s = s % D
}
BN_copy(B,s);
}
if (A00[3] == 0xAA)
{ //following code is equivalent of MonMul3e(B,A,B)
int Aoctets=(BN_num_bytes(A)+7)>>3;
BN_zero(s);
for(int i=0; i<Aoctets; i++) {
BN_rshift(x,A,i<<6); //x = B >> (i*64)
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,B,ctx); //x = x * B
BN_add(s,s,x); //s = s + x
BN_copy(x,s); //x = s
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,J,ctx); //x = x * J
BN_lshift(C,x,64); //C = x << 64
BN_add(C,C,x); //C = C + x
BN_rshift(C,C,2); //C = C >> 2
BN_add(C,C,s); //C = C + s
BN_rshift(C,C,52); //C = C >> 52
BN_mask_bits(C,12); //C & 0FFF
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,D,ctx); //x = x * D
BN_add(s,s,x); //s = s + x
BN_lshift(y,s,12); //y = s << 12
BN_add(C,C,y); //C = C + y
BN_mask_bits(C,128); //C & 128bits
BN_rshift(s,s,64); //s = s >> 64
BN_copy(Z,s); //Z = s //in MonMul3e this is BN_copy(H,s);
BN_mod(s,s,D,ctx); //s = s % D
}
}
if (xr==0x0C) BN_copy(Z,C);
BN_mask_bits(Z,128);
memset(_z,0,0x10);
BN_free(s); BN_free(x); BN_free(y); BN_free(v);
}
break;
case 0x3D6D:
{
BIGNUM *s = BN_new();
BIGNUM *x = BN_new();
BIGNUM *i1 = BN_new();
BIGNUM *i2 = BN_new();
BIGNUM *o = BN_new();
//D.GetLE(data,16); //could be. same thing for this case
//D.GetLE(data,(l<=0? l:wordsize)<<3);
RotateBytes(&hw[0x50],0x10);
BN_bin2bn(&hw[0x50],0x10,D);
BN_copy(i1,B);
BN_copy(i2,B);
//MakeJ();
BN_zero(x);
BN_sub(J,x,D);
BN_set_bit(J,0);
BN_set_bit(x,64);
BN_mod_inverse(J,J,x,ctx);
BN_mask_bits(J,64);
//MonMul3d(C,B,B);
//int Boctets=(BN_num_bytes(B)+7)>>3;
BN_zero(s);
for (int i=0; i<2; i++)
{
BN_rshift(x,i1,i<<6);
BN_mask_bits(x,64);
BN_mul(x,x,i2,ctx);
BN_add(s,s,x);
BN_copy(x,s);
BN_mask_bits(x,64);
BN_mul(x,x,J,ctx);
BN_mask_bits(x,64);
BN_mul(x,x,D,ctx);
BN_add(s,s,x);
BN_rshift(s,s,64);
BN_copy(o,s);
if (BN_cmp(s,D)==1)
{
BN_copy(x,s);
BN_sub(s,x,D);
}
}
BN_mask_bits(o,128);
BN_copy(Z,o);
memset(_z,0,0x10);
BN_free(s); BN_free(x); BN_free(i1); BN_free(i2); BN_free(o);
}
break;
case 0x4692:
{
BIGNUM *s = BN_new();
BIGNUM *x = BN_new();
BIGNUM *y = BN_new();
BIGNUM *v = BN_new();
BN_zero(v);
BN_sub(J,v,D);
BN_set_bit(J,0);
BN_set_bit(v,64);
BN_mod_inverse(J,J,v,ctx);
BN_mask_bits(J,64);
BN_zero(v);
BN_set_bit(v,136);
BN_mod(B,v,D,ctx); //B = v % D
for(int j=0;j<2;j++) {
//Following code is equivalent to MonMul3e(B,B,B)
int Boctets=(BN_num_bytes(B)+7)>>3;
BN_zero(s);
for(int i=0; i<Boctets; i++) {
BN_rshift(x,B,i<<6); //x = B >> (i*64)
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,B,ctx); //x = x * B
BN_add(s,s,x); //s = s + x
BN_copy(x,s); //x = s
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,J,ctx); //x = x * J
BN_lshift(C,x,64); //C = x << 64
BN_add(C,C,x); //C = C + x
BN_rshift(C,C,2); //C = C >> 2
BN_add(C,C,s); //C = C + s
BN_rshift(C,C,52); //C = C >> 52
BN_mask_bits(C,12); //C & 0FFF
BN_mask_bits(x,64); //x & 64bits
BN_mul(x,x,D,ctx); //x = x * D
BN_add(s,s,x); //s = s + x
BN_lshift(y,s,12); //y = s << 12
BN_add(C,C,y); //C = C + y
BN_mask_bits(C,128); //C & 128bits
BN_rshift(s,s,64); //s = s >> 64
BN_copy(Z,s); //Z = s //in MonMul3e this is BN_copy(H,s);
BN_mod(s,s,D,ctx); //s = s % D
}
BN_copy(B,s);
}
if (xr==0x0C) BN_copy(Z,C);
BN_mask_bits(Z,128);
memset(_z,0,0x10);
BN_free(s); BN_free(x); BN_free(y); BN_free(v);
}
break;
default:
// unsigned int hexcode = ((m << 8) | A00[3]); //mpc
printf("Unknown Map call %04X\n", hexcode); //mpc
BN_copy(Z,A); //need this else debugger barfs with stack corruption
memset(_z,0,0x10); //may need this too
break;
}
BN_bn2bin(Z,_z);
if (BN_num_bytes(Z) > 0) RotateBytes(_z,BN_num_bytes(Z));
for (int i=11;i>-1;i--) hw[i]^=hw[i+4]; memset(&hw[4],0,0x7C);
BN_free(A); BN_free(B); BN_free(C); BN_free(D);
BN_free(J); BN_free(Z); BN_CTX_free(ctx);
}
Scoob