break;
case 0x3e:
{
- I.GetLE(data,l<<3);
- BN_mod_exp(B,A,I,D,ctx);
- BN_one(A);
- int end=BN_num_bits(I);
+ cBN scalar;
+ scalar.GetLE(data,l<<3);
+ if(BN_is_zero(scalar) || BN_num_bits(D)<=1) {
+ MakeJ0(J,D);
+ if(BN_num_bits(D)==1 || !BN_is_zero(scalar)) BN_zero(B);
+ else BN_one(B);
+ BN_one(A);
+ }
+ else {
+ MonInit();
+ MonMul(B,A,B);
+ MonExp(scalar);
+ }
+ BN_zero(C);
+ int end=BN_num_bits(scalar);
int msb=data[(end-1)/8];
cycles=3848 + ((end-1)/8)*650 - 11;
for(int i=8; --i>=1;) if(msb&(1<<i)) { cycles+=(i*75)-15; break; }
- for(int i=end; --i>=0;) if(BN_is_bit_set(I,i)) cycles+=88;
+ for(int i=end; --i>=0;) if(BN_is_bit_set(scalar,i)) cycles+=88;
break;
}
case 0x4d:
for(int i=0; i<4; i++) MonMul(B,B,B);
}
+void cMapCore::MonExp(BIGNUM *scalar)
+{
+ if(BN_is_zero(D)) { BN_one(A); return; }
+ BN_copy(A,B);
+ for(int i=BN_num_bits(scalar)-2; i>-1; i--) {
+ MonMul(B,B,B);
+ if(BN_is_bit_set(scalar,i)) MonMul(B,A,B);
+ }
+ BN_one(A);
+ MonMul(B,A,B);
+}
+
void cMapCore::MonExpNeg(void)
{
if(BN_is_zero(D)) { BN_set_word(A,1); return; }
cBN sA0, sC0, sE0, s100, s120, s140, s160;
// statefull
void MonInit(int bits=0);
+ void MonExp(BIGNUM *scalar);
void MonExpNeg(void);
// ECC
void DoubleP(int temp);