|
SASC-NG
DVBSoftCAM
|
Inheritance diagram for cMap0101:Protected Member Functions | |
| virtual bool | Map (int f, unsigned char *data, int l) |
Definition at line 118 of file nagra2-0101.c.
| bool cMap0101::Map | ( | int | f, |
| unsigned char * | data, | ||
| int | l | ||
| ) | [protected, virtual] |
Reimplemented from cMapCore.
Definition at line 196 of file nagra2-0101.c.
References cMapMath::A, cMapCore::AddMapCycles(), cMapCore::AddP(), b, cMapMath::B, cMapMath::C, cMapReg::Commit(), cMapMath::ctx, cMapCore::CurveInit(), cMapCore::cycles, cMapMath::D, cMapCore::DoubleP(), cMapReg::GetLE(), cBN::GetLE(), cMapCore::GetOpSize(), i, cMapCore::IMakeJ(), cMapCore::IMonInit(), cMapCore::IMonInit0(), j, cMapMath::J, cMapMath::MakeJ0(), cAuxSrv::Map(), min(), cMapMath::ModSub(), cMapCore::MonExpNeg(), cMapMath::MonFin(), cMapMath::MonMul(), cMapMath::MonMul0(), cBN::PutLE(), cMapReg::PutLE(), cMapCore::Px, cMapCore::Py, cMapCore::Pz, cMapCore::Qx, cMapCore::Qy, cMapCore::Qz, cMapMath::scalar, cMapReg::SetPos(), cMapCore::ToAffine(), cMapCore::ToProjective(), cMapMath::wordsize, WS_END, and WS_START.
{
int sl=l;
l=GetOpSize(l);
switch(f) {
case 0x21:
AddMapCycles(169-6);
IMakeJ();
cycles=898;
break;
case 0x22:
if(BN_is_zero(D)) { cycles=639-6; break; }
l&=0x1fff;
AddMapCycles(376);
BN_zero(B);
AddMapCycles(l>=(BN_num_bits(D)-1)/64*64 ? 244 : 210);
BN_one(B);
B.SetPos(1);
AddMapCycles(17);
for(int i=2; i<=8; i++) { B.SetPos(i); AddMapCycles(9); }
AddMapCycles(44);
BN_mod_lshift(B,B,l,D,ctx);
break;
case 0x23:
AddMapCycles(169);
IMonInit0();
break;
case 0x25:
AddMapCycles(254);
MakeJ0(B,D,C,wordsize<<6);
// valid for wordsize 1 and 2
AddMapCycles(795*wordsize-492);
BN_zero(C);
cycles=49+800*wordsize;
break;
case 0x29:
{
BN_add(B,B,C);
bool b=BN_is_bit_set(B,wordsize<<6);
if(b) BN_mask_bits(B,wordsize<<6);
if(data) data[0]=b;
cycles=501+(8*wordsize+3)/5*5-6;
break;
}
case 0x2a:
{
bool b=ModSub(B,B,D);
if(data) data[0]=b;
BN_zero(C);
break;
}
case 0x2e:
case 0x2F:
if(l<=0) { cycles+=4; l=wordsize; }
else if(l>17) { cycles+=5; l=17; }
scalar.GetLE(data,l<<3);
AddMapCycles(617+30*wordsize);
for(int i=0; i<l; i++) {
if(i&1) {
unsigned char buf[8];
J.PutLE(buf,8);
AddMapCycles(10);
for(int j=0; j<8; j++) {
buf[j]=data[i*8+j];
J.GetLE(buf,8);
J.SetPos(j+1);
AddMapCycles(14);
}
J.SetPos(0);
AddMapCycles(12);
}
else
AddMapCycles(114);
}
AddMapCycles(3);
BN_mul(D,scalar,B,ctx);
if(f&1) BN_add(D,D,C);
BN_rshift(C,D,l<<6);
BN_mask_bits(D,l<<6);
D.Commit(l);
BN_mask_bits(C,wordsize<<6);
break;
case 0x30:
case 0x31:
BN_sqr(D,B,ctx);
if((f&1)) BN_add(D,D,C);
BN_rshift(C,D,wordsize<<6);
BN_rshift(J,B,((wordsize+1)/2)*128-64);
BN_mask_bits(J,64);
break;
case 0x32:
AddMapCycles(1000);
l=min(34,l);
if(!BN_is_zero(D)) {
scalar.GetLE(data,l<<3);
BN_div(C,B,scalar,D,ctx);
BN_rshift(A,C,17*64);
A.Commit(17);
C.Commit(17);
}
BN_zero(J);
break;
case 0x36:
case 0x38:
AddMapCycles(230);
MonMul0(B,f==0x36?A:B,B,C,D,J,wordsize);
AddMapCycles(102);
MonFin(B,D);
break;
case 0x3b:
AddMapCycles(441);
IMakeJ();
AddMapCycles(46);
IMonInit0(wordsize*60+4*l);
scalar.GetLE(data,l<<3);
MonMul(B,scalar,B,l);
cycles=tim3b[wordsize-1][l-1]-6;
break;
case 0x3d:
AddMapCycles(652);
D.GetLE(data,wordsize<<3);
AddMapCycles(514);
IMakeJ();
AddMapCycles(35);
MonMul0(C,B,B,C,D,J,wordsize);
AddMapCycles(143);
BN_copy(A,B);
AddMapCycles(73);
MonExpNeg();
MonMul(B,A,B);
BN_zero(C);
cycles+=rand()%(wordsize*20000)+2000;
break;
case 0x3c:
case 0x3e:
case 0x46:
{
if(f==0x46) l=1; else l=sl;
if(l<=0) { l=wordsize; cycles+=4; }
else if(l>wordsize) { l=wordsize; cycles+=l>17 ? 9:4; }
scalar.GetLE(data,l<<3);
int sbits=BN_num_bits(scalar);
cycles+=3848+((sbits-1)/8)*650 - 11;
int msb=data[(sbits-1)/8];
for(int i=7; i>=1; --i) if(msb&(1<<i)) { cycles+=i*75-15; break; }
for(int i=0; i<sbits; ++i) if(BN_is_bit_set(scalar,i)) cycles+=88;
AddMapCycles(f==0x46 ? 400:441);
if(BN_is_zero(scalar) || BN_num_bits(D)<=1) {
IMakeJ();
if(BN_num_bits(D)==1 || !BN_is_zero(scalar)) BN_zero(B);
else BN_one(B);
BN_one(A);
}
else {
IMonInit();
MonMul0(B,A,B,C,D,J,0);
if(f==0x3c) AddMapCycles(2200+(rand()%(wordsize*2000)));
MonFin(B,D);
}
BN_zero(C);
if(f==0x46) cycles-=37;
}
break;
case 0x4d:
if(-0x018000==l)
BN_mask_bits(B,64);
else {
BN_set_bit(B,(wordsize<<6)-1);
if(-0x028000==l) BN_set_bit(B,(wordsize<<6)-2);
}
BN_set_bit(B,0);
for(int i=0; i<53; i++) data[i]=BN_mod_word(B,primes[i]);
BN_copy(A,B);
BN_zero(C); BN_zero(D); BN_zero(J);
break;
case 0x4e:
case 0x4f:
MakePrime(data,f==0x4f);
break;
case 0x57:
#ifdef HAS_AUXSRV
{
int c=aux.Map(0x57,data,0x60,0x40);
if(c>0) { cycles=c-6; break; }
}
#endif
{
cBN a, b, x, y;
if(l<2 || l>4) l=4;
WS_START(l);
l<<=3;
D.GetLE(data+0*l,l);
x.GetLE(data+1*l,l);
y.GetLE(data+2*l,l);
b.GetLE(data+3*l,l);
a.GetLE(data+4*l,l);
scalar.GetLE(data+5*l,l);
bool doz=false;
int scalarbits=BN_num_bits(scalar);
if(scalarbits>=2) {
if(BN_is_zero(x) && (BN_is_zero(y) || (BN_is_zero(b) && BN_num_bits(y)==1))) {
BN_zero(Px);
BN_copy(Py,y);
BN_zero(Qz);
MakeJ0(J,D);
}
else {
CurveInit(a);
ToProjective(0,x,y);
BN_copy(Qx,Px);
BN_copy(Qy,Py);
for(int i=scalarbits-2; i>=0; i--) {
DoubleP(0);
if(BN_is_bit_set(scalar,i)) {
BN_copy(A,Pz);
if(BN_is_zero(Pz) || BN_is_zero(D)) {
BN_copy(Px,Qx);
BN_copy(Py,Qy);
BN_copy(Pz,Qz);
AddP(1);
}
else {
doz=true;
if(wordsize==4) {
BN_rshift(Py,Py,32);
BN_lshift(Py,Py,32);
BN_rshift(b,Qz,224);
BN_add(Py,Py,b);
}
BN_mask_bits(Px,32);
BN_lshift(b,Qz,32);
BN_add(Px,Px,b);
BN_mask_bits(Px,l<<3);
AddP(0);
}
}
}
ToAffine();
}
}
else {
BN_copy(Px,x);
BN_copy(Py,y);
BN_zero(Qz);
MakeJ0(J,D);
}
memset(data,0,0x40);
Px.PutLE(&data[0x00],l);
if(l<0x20 && doz) {
unsigned char tmp[0x20];
Qz.PutLE(tmp,l);
memcpy(&data[l],&tmp[l-4],4);
}
Py.PutLE(&data[0x20],l);
BN_zero(A);
BN_zero(B);
BN_zero(C);
WS_END();
break;
}
default:
return false;
}
return true;
}