// -- cMapReg ------------------------------------------------------------------
-cMapReg::cMapReg(const int *Ws, const char *Name)
+cMapReg::cMapReg(int *_defwordsize, int _maxwordsize)
{
- ws=Ws; name=Name;
+ SetDefWordSize(_defwordsize);
+ SetMaxWordSize(_maxwordsize);
+ wordsize=DEF_WORDSIZE;
}
-void cMapReg::Save(int size)
+BIGNUM *cMapReg::Value(int wsize, bool mask)
{
- 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 %s size=%d\n",name,size);
-fprintf(stderr,"reg : "); BN_print_fp(stderr,reg); fprintf(stderr,"\n");
-fprintf(stderr,"save: "); BN_print_fp(stderr,save); fprintf(stderr,"\n");
-#endif
+ wsize=OpWordSize(wsize);
+ if(wordsize!=wsize) {
+ Commit();
+ Reload();
}
+ else if(mask)
+ BN_mask_bits(reg,wsize*64);
+ return reg;
}
-void cMapReg::Restore(int size)
+void cMapReg::ClearReg(int wsize)
{
- if(touched && ws) {
- if(size<=0) size=*ws;
-#ifdef MR_DEBUG
-fprintf(stderr,"restore %s size=%d\n",name,size);
-fprintf(stderr,"reg : "); BN_print_fp(stderr,reg); fprintf(stderr,"\n");
-fprintf(stderr,"save: "); 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
-fprintf(stderr,"reg : "); BN_print_fp(stderr,reg); fprintf(stderr,"\n");
-#endif
+ BN_rshift(reg,reg,wsize*64);
+ BN_lshift(reg,reg,wsize*64);
+}
+
+void cMapReg::ClearFullReg(int wsize)
+{
+ BN_rshift(fullreg,fullreg,wsize*64);
+ BN_lshift(fullreg,fullreg,wsize*64);
+}
+
+void cMapReg::PrepTmp(BIGNUM *val, int wsize)
+{
+ if(val->neg) {
+ BN_clear(tmp);
+ BN_set_bit(tmp,wsize*64);
+ BN_add(tmp,tmp,val);
}
+ else
+ BN_copy(tmp,val);
+ BN_mask_bits(tmp,wsize*64);
}
-// -- cMapMath -----------------------------------------------------------------
+void cMapReg::Commit(int wsize, int resync)
+{
+ if(resync<0 && wsize<0) resync=1;
+ wsize=OpWordSize(wsize>=0?wsize:wordsize);
+ ClearFullReg(wsize);
+ PrepTmp(reg,wsize);
+ BN_add(fullreg,fullreg,tmp);
+ if(resync) {
+ if(wordsize==wsize) BN_mask_bits(reg,wsize*64);
+ else wordsize=wsize;
+ }
+}
-const int cMapMath::ws1=1;
+void cMapReg::Reload(int wsize)
+{
+ wsize=OpWordSize(wsize>=0?wsize:wordsize);
+ wordsize=wsize;
+ BN_copy(reg,fullreg);
+ BN_mask_bits(reg,64*wsize);
+}
-cMapMath::cMapMath(void)
-:A(&wordsize,"A"),B(&wordsize,"B"),C(&wordsize,"C"),D(&wordsize,"D"),J(&ws1,"J"),I(0,"I")
+void cMapReg::GetLE(const unsigned char *in, int n)
{
- wordsize=DEF_WORDSIZE;
+ int wsize=OpWordSize(n<=0?n:(n+7)/8);
+ if(wordsize>wsize) Commit();
+ reg.GetLE(in,wsize*8);
+ Commit(wsize);
}
-void cMapMath::Finalise(void)
+void cMapReg::PutLE(unsigned char *out, int n)
{
-#ifdef MR_DEBUG
-fprintf(stderr,"finalise\n");
-#endif
- A.Restore(); B.Restore(); C.Restore(); D.Restore();
+ int wsize=OpWordSize(n<=0?n:(n+7)/8);
+ Commit();
+ fullreg.PutLE(out,wsize*8);
}
-void cMapMath::WClear(BIGNUM *r, int w)
+void cMapReg::Set(BIGNUM *val, int wsize)
{
- if(!w) w=wordsize;
- BN_rshift(r,r,w<<6);
- BN_lshift(r,r,w<<6);
+ wsize=OpWordSize(wsize);
+ if(wordsize!=wsize) Commit();
+ ClearReg(wsize);
+ PrepTmp(val,wsize);
+ if(wordsize!=wsize) {
+ ClearFullReg(wsize);
+ BN_add(fullreg,fullreg,tmp);
+ }
+ BN_add(reg,reg,tmp);
+}
+
+void cMapReg::Clear(int wsize)
+{
+ wsize=OpWordSize(wsize);
+ if(wordsize!=wsize) {
+ Commit();
+ ClearFullReg(wsize);
+ }
+ ClearReg(wsize);
+}
+
+// -- cMapMath -----------------------------------------------------------------
+
+cMapMath::cMapMath(void)
+:A(&wordsize),B(&wordsize),C(&wordsize),D(&wordsize),J(0,1),I(&wordsize)
+{
+ wordsize=DEF_WORDSIZE;
}
bool cMapMath::ModAdd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *d)
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:
last=f-SWAP_A+1;
e.GetLE(data,dl);
regs[last]->PutLE(data,dl);
- BN_copy(*regs[last],e);
+ regs[last]->Set(e,l1);
break;
case CLEAR_A:
case CLEAR_C:
case CLEAR_D:
cycles=462+(8*l1+3)/5*5-6;
- last=f-CLEAR_A+1; BN_zero(*regs[last]);
+ last=f-CLEAR_A+1;
+ regs[last]->Clear(l1);
break;
case COPY_A_B:
- last=2; BN_copy(B,A); cycles=462+(8*l1+3)/5*5-6; break;
+ last=2; B.Set(A,l1); cycles=462+(8*l1+3)/5*5-6; break;
case COPY_B_A:
- last=1; BN_copy(A,B); cycles=462+(8*l1+3)/5*5-6; break;
+ last=1; A.Set(B,l1); cycles=462+(8*l1+3)/5*5-6; break;
case COPY_A_C:
- last=3; BN_copy(C,A); cycles=462+(8*l1+3)/5*5-6; break;
+ last=3; C.Set(A,l1); cycles=462+(8*l1+3)/5*5-6; break;
case COPY_C_A:
- last=1; BN_copy(A,C); cycles=462+(8*l1+3)/5*5-6; break;
+ last=1; A.Set(C,l1); cycles=462+(8*l1+3)/5*5-6; break;
case COPY_C_D:
- last=4; BN_copy(D,C); cycles=462+(8*l1+3)/5*5-6; break;
+ last=4; D.Set(C,l1); cycles=462+(8*l1+3)/5*5-6; break;
case COPY_D_C:
- last=3; BN_copy(C,D); cycles=462+(8*l1+3)/5*5-6; break;
+ last=3; C.Set(D,l1); cycles=462+(8*l1+3)/5*5-6; break;
case 0x39:
case 0x3a:
default:
return false;
}
- Finalise();
return true;
}
// ----------------------------------------------------------------
-//#define MR_DEBUG
+#define DEF_WORDSIZE 4
+#define DEF_MAXWORDSIZE 17
class cMapReg {
private:
- cBN reg, save, tmp;
- const int *ws;
- const char *name;
- bool touched;
+ cBN fullreg, reg, tmp;
+ int wordsize, maxwordsize, *defwordsize;
+ //
+ int DefWordSize() const { return defwordsize ? *defwordsize:DEF_WORDSIZE; }
+ int OpWordSize(int wsize) const { int sz=wsize>0 ? wsize:DefWordSize(); return sz>maxwordsize ? maxwordsize:sz; }
+// int OpWordSize() const { return wordsize; }
+ void ClearReg(int wsize);
+ void ClearFullReg(int wsize);
+ void PrepTmp(BIGNUM *val, int wsize);
+protected:
+ void SetMaxWordSize(int max) { maxwordsize=max; }
+ void SetDefWordSize(int *_defwordsize) { defwordsize=_defwordsize; }
public:
- cMapReg(const int *Ws, const char *Name);
- 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);
+ cMapReg(int *_defwordsize=0, int _maxwordsize=DEF_MAXWORDSIZE);
+ operator BIGNUM* () { return Value(); }
+ BIGNUM *operator->() { return Value(); }
+ BIGNUM *Value(int wsize=0, bool mask=false);
+ void Commit(int wsize=-1, int resync=-1);
+ void Reload(int wsize=0);
+ void GetLE(const unsigned char *in, int n=0);
+ void PutLE(unsigned char *out, int n=0);
+ void Set(BIGNUM *val, int wsize);
+ void Clear(int wsize);
};
// ----------------------------------------------------------------
-#define DEF_WORDSIZE 4
-
#define WS_START(x) { int __oldws=wordsize; wordsize=(x);
#define WS_END() wordsize=__oldws; }
private:
cBN x, y, s;
int words;
- static const int ws1;
protected:
int wordsize;
cMapReg A, B, C, D, J, I;
void MonMul(BIGNUM *o, BIGNUM *a, BIGNUM *b, BIGNUM *c, BIGNUM *d, BIGNUM *j, int w);
void MonStart(int w);
void MonLoop(BIGNUM *o, BIGNUM *a, BIGNUM *b, BIGNUM *c, BIGNUM *d, BIGNUM *j);
- void WClear(BIGNUM *r, int w=0);
// 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);
};