~cBN() { BN_free(&big); }
operator BIGNUM* () { return &big; }
BIGNUM *operator->() { return &big; }
+ BIGNUM *BN(void) { return &big; }
bool Get(const unsigned char *in, int n);
bool GetLE(const unsigned char *in, int n);
int Put(unsigned char *out, int n) const;
PRINTF(L_SYS_MAP,"0101: calling function %02X",f);
l=GetOpSize(l);
cycles=0; interrupted=false;
+#ifdef MR_DEBUG
+fprintf(stderr,"map %x l=%d\n",f,l);
+#endif
switch(f) {
case 0x21:
MAP_IRQ_BEGIN();
AddMapCycles(288);
- WS_START(1);
MakeJ0(J,D);
AddMapCycles(282);
- WClear(C);
+ WClear(C,1);
AddMapCycles(898-282-288);
- WS_END();
MAP_IRQ_END();
break;
case 0x22:
PRINTF(L_SYS_MAP,"0101: unsupported call %02x",f);
break;
}
+ Finalise();
}
// -- cN2Prov0101 --------------------------------------------------------------
return initDone;
}
+// -- cMapReg ------------------------------------------------------------------
+
+cMapReg::cMapReg(const int *Ws)
+{
+ ws=Ws;
+}
+
+void cMapReg::Save(int size)
+{
+ if(!touched && ws) {
+ if(size<=0) size=*ws;
+ BN_copy(save,reg);
+ BN_mask_bits(reg,size<<6);
+ touched=true;
+#ifdef MR_DEBUG
+fprintf(stderr,"saved %p size=%d\n",this,size);
+BN_print_fp(stderr,reg); fprintf(stderr,"\n");
+BN_print_fp(stderr,save); fprintf(stderr,"\n");
+#endif
+ }
+}
+
+void cMapReg::Restore(int size)
+{
+ if(touched && ws) {
+ if(size<=0) size=*ws;
+#ifdef MR_DEBUG
+fprintf(stderr,"restore %p size=%d\n",this,size);
+BN_print_fp(stderr,reg); fprintf(stderr,"\n");
+BN_print_fp(stderr,save); fprintf(stderr,"\n");
+#endif
+ if(reg->neg) {
+ BN_zero(tmp);
+ BN_set_bit(tmp,size<<6);
+ BN_add(reg,tmp,reg);
+ }
+ BN_rshift(tmp,save,size<<6);
+ BN_lshift(tmp,tmp,size<<6);
+ BN_mask_bits(reg,size<<6);
+ BN_add(reg,reg,tmp);
+ touched=false;
+#ifdef MR_DEBUG
+BN_print_fp(stderr,reg); fprintf(stderr,"\n");
+#endif
+ }
+}
+
// -- cMapMath -----------------------------------------------------------------
+const int cMapMath::ws1=1;
+
cMapMath::cMapMath(void)
+:A(&wordsize),B(&wordsize),C(&wordsize),D(&wordsize),J(&ws1),I(0)
{
wordsize=DEF_WORDSIZE;
}
+void cMapMath::Finalise(void)
+{
+#ifdef MR_DEBUG
+fprintf(stderr,"finalise\n");
+#endif
+ A.Restore(); B.Restore(); C.Restore(); D.Restore();
+}
+
void cMapMath::WClear(BIGNUM *r, int w)
{
if(!w) w=wordsize;
cycles=890-6;
last=0;
regs[0]->GetLE(data,8);
+ regs[0]->Restore(1);
break;
case IMPORT_A:
case IMPORT_B:
cycles+=771+160*l-6;
last=f-IMPORT_J;
regs[last]->GetLE(data,l<<3);
+ regs[last]->Restore(l);
break;
case IMPORT_LAST:
if(l>16) { l=1; cycles+=5; }
else if(l<=0) l=1;
cycles=656+160*l-6;
regs[last]->GetLE(data,(last==0?1:l)<<3);
+ regs[last]->Restore((last==0?1:l));
break;
case EXPORT_J:
default:
return false;
}
+ Finalise();
return true;
}
// ----------------------------------------------------------------
+//#define MR_DEBUG
+
+class cMapReg {
+private:
+ cBN reg, save, tmp;
+ const int *ws;
+ bool touched;
+public:
+ cMapReg(const int *Ws);
+ operator BIGNUM* () { Save(); return reg.BN(); }
+ BIGNUM *operator->() { Save(); return reg.BN(); }
+ bool Get(const unsigned char *in, int n) { Save(); return reg.Get(in,n); }
+ bool GetLE(const unsigned char *in, int n) { Save(); return reg.GetLE(in,n); }
+ int Put(unsigned char *out, int n) const { return reg.Put(out,n); }
+ int PutLE(unsigned char *out, int n) const { return reg.PutLE(out,n); }
+ void Save(int size=0);
+ void Restore(int size=0);
+ };
+
+// ----------------------------------------------------------------
+
#define DEF_WORDSIZE 4
#define WS_START(x) { int __oldws=wordsize; wordsize=(x);
private:
cBN x, y, s;
int words;
+ static const int ws1;
protected:
int wordsize;
- cBN A, B, C, D, J, I;
+ cMapReg A, B, C, D, J, I;
cBNctx ctx;
SHA_CTX sctx;
// stateless
// statefull
void MonMul(BIGNUM *o, BIGNUM *a, BIGNUM *b);
void MonMul(BIGNUM *o, BIGNUM *a, BIGNUM *b, int w);
+ void Finalise(void);
public:
cMapMath(void);
};
private:
int last;
cBN e;
- cBN *regs[5];
+ cMapReg *regs[5];
protected:
unsigned int cycles;
cBN Px, Py, Pz,Qx, Qy, Qz; // 0x00,0x20,0x40,0x60,0x80,0x180