#include "cryptlib.h"
#include "bn_lcl.h"
-#ifdef BN_LLONG
+#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
-BN_ULONG bn_mul_add_words(rp,ap,num,w)
-BN_ULONG *rp,*ap;
-int num;
-BN_ULONG w;
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
{
BN_ULONG c1=0;
bn_check_num(num);
if (num <= 0) return(c1);
- for (;;)
+ while (num&~3)
{
mul_add(rp[0],ap[0],w,c1);
- if (--num == 0) break;
mul_add(rp[1],ap[1],w,c1);
- if (--num == 0) break;
mul_add(rp[2],ap[2],w,c1);
- if (--num == 0) break;
mul_add(rp[3],ap[3],w,c1);
- if (--num == 0) break;
- ap+=4;
- rp+=4;
+ ap+=4; rp+=4; num-=4;
+ }
+ if (num)
+ {
+ mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1;
+ mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1;
+ mul_add(rp[2],ap[2],w,c1); return c1;
}
return(c1);
}
-BN_ULONG bn_mul_words(rp,ap,num,w)
-BN_ULONG *rp,*ap;
-int num;
-BN_ULONG w;
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
{
BN_ULONG c1=0;
bn_check_num(num);
if (num <= 0) return(c1);
- for (;;)
+ while (num&~3)
{
mul(rp[0],ap[0],w,c1);
- if (--num == 0) break;
mul(rp[1],ap[1],w,c1);
- if (--num == 0) break;
mul(rp[2],ap[2],w,c1);
- if (--num == 0) break;
mul(rp[3],ap[3],w,c1);
- if (--num == 0) break;
- ap+=4;
- rp+=4;
+ ap+=4; rp+=4; num-=4;
+ }
+ if (num)
+ {
+ mul(rp[0],ap[0],w,c1); if (--num == 0) return c1;
+ mul(rp[1],ap[1],w,c1); if (--num == 0) return c1;
+ mul(rp[2],ap[2],w,c1);
}
return(c1);
}
-void bn_sqr_words(r,a,n)
-BN_ULONG *r,*a;
-int n;
+void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
{
bn_check_num(n);
if (n <= 0) return;
- for (;;)
+ while (n&~3)
{
- BN_ULLONG t;
-
- t=(BN_ULLONG)(a[0])*(a[0]);
- r[0]=Lw(t); r[1]=Hw(t);
- if (--n == 0) break;
-
- t=(BN_ULLONG)(a[1])*(a[1]);
- r[2]=Lw(t); r[3]=Hw(t);
- if (--n == 0) break;
-
- t=(BN_ULLONG)(a[2])*(a[2]);
- r[4]=Lw(t); r[5]=Hw(t);
- if (--n == 0) break;
-
- t=(BN_ULLONG)(a[3])*(a[3]);
- r[6]=Lw(t); r[7]=Hw(t);
- if (--n == 0) break;
-
- a+=4;
- r+=8;
+ sqr(r[0],r[1],a[0]);
+ sqr(r[2],r[3],a[1]);
+ sqr(r[4],r[5],a[2]);
+ sqr(r[6],r[7],a[3]);
+ a+=4; r+=8; n-=4;
+ }
+ if (n)
+ {
+ sqr(r[0],r[1],a[0]); if (--n == 0) return;
+ sqr(r[2],r[3],a[1]); if (--n == 0) return;
+ sqr(r[4],r[5],a[2]);
}
}
#else
-BN_ULONG bn_mul_add_words(rp,ap,num,w)
-BN_ULONG *rp,*ap;
-int num;
-BN_ULONG w;
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
{
BN_ULONG c=0;
BN_ULONG bl,bh;
return(c);
}
-BN_ULONG bn_mul_words(rp,ap,num,w)
-BN_ULONG *rp,*ap;
-int num;
-BN_ULONG w;
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
{
BN_ULONG carry=0;
BN_ULONG bl,bh;
return(carry);
}
-void bn_sqr_words(r,a,n)
-BN_ULONG *r,*a;
-int n;
+void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
{
bn_check_num(n);
if (n <= 0) return;
#if defined(BN_LLONG) && defined(BN_DIV2W)
-BN_ULONG bn_div_words(h,l,d)
-BN_ULONG h,l,d;
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
{
return((BN_ULONG)(((((BN_ULLONG)h)<<BN_BITS2)|l)/(BN_ULLONG)d));
}
/* Divide h-l by d and return the result. */
/* I need to test this some more :-( */
-BN_ULONG bn_div_words(h,l,d)
-BN_ULONG h,l,d;
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
{
BN_ULONG dh,dl,q,ret=0,th,tl,t;
int i,count=2;
else
q=h/dh;
+ th=q*dh;
+ tl=dl*q;
for (;;)
{
- t=(h-q*dh);
+ t=h-th;
if ((t&BN_MASK2h) ||
- ((dl*q) <= (
- (t<<BN_BITS4)+
+ ((tl) <= (
+ (t<<BN_BITS4)|
((l&BN_MASK2h)>>BN_BITS4))))
break;
q--;
+ th-=dh;
+ tl-=dl;
}
- th=q*dh;
- tl=q*dl;
t=(tl>>BN_BITS4);
tl=(tl<<BN_BITS4)&BN_MASK2h;
th+=t;
#endif
#ifdef BN_LLONG
-BN_ULONG bn_add_words(r,a,b,n)
-BN_ULONG *r,*a,*b;
-int n;
+BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
{
BN_ULLONG ll=0;
return((BN_ULONG)ll);
}
#else
-BN_ULONG bn_add_words(r,a,b,n)
-BN_ULONG *r,*a,*b;
-int n;
+BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
{
BN_ULONG c,l,t;
}
#endif
-BN_ULONG bn_sub_words(r,a,b,n)
-BN_ULONG *r,*a,*b;
-int n;
+BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
{
BN_ULONG t1,t2;
int c=0;
#define sqr_add_c2(a,i,j,c0,c1,c2) \
mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+#elif defined(BN_UMULT_HIGH)
+
+#define mul_add_c(a,b,c0,c1,c2) { \
+ BN_ULONG ta=(a),tb=(b); \
+ t1 = ta * tb; \
+ t2 = BN_UMULT_HIGH(ta,tb); \
+ c0 += t1; t2 += (c0<t1)?1:0; \
+ c1 += t2; c2 += (c1<t2)?1:0; \
+ }
+
+#define mul_add_c2(a,b,c0,c1,c2) { \
+ BN_ULONG ta=(a),tb=(b),t0; \
+ t1 = BN_UMULT_HIGH(ta,tb); \
+ t0 = ta * tb; \
+ t2 = t1+t1; c2 += (t2<t1)?1:0; \
+ t1 = t0+t0; t2 += (t1<t0)?1:0; \
+ c0 += t1; t2 += (c0<t1)?1:0; \
+ c1 += t2; c2 += (c1<t2)?1:0; \
+ }
+
+#define sqr_add_c(a,i,c0,c1,c2) { \
+ BN_ULONG ta=(a)[i]; \
+ t1 = ta * ta; \
+ t2 = BN_UMULT_HIGH(ta,ta); \
+ c0 += t1; t2 += (c0<t1)?1:0; \
+ c1 += t2; c2 += (c1<t2)?1:0; \
+ }
+
+#define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
#else
#define mul_add_c(a,b,c0,c1,c2) \
t1=LBITS(a); t2=HBITS(a); \
mul_add_c2((a)[i],(a)[j],c0,c1,c2)
#endif
-void bn_mul_comba8(r,a,b)
-BN_ULONG *r,*a,*b;
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
{
#ifdef BN_LLONG
BN_ULLONG t;
r[15]=c1;
}
-void bn_mul_comba4(r,a,b)
-BN_ULONG *r,*a,*b;
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
{
#ifdef BN_LLONG
BN_ULLONG t;
r[7]=c2;
}
-void bn_sqr_comba8(r,a)
-BN_ULONG *r,*a;
+void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
{
#ifdef BN_LLONG
BN_ULLONG t,tt;
r[15]=c1;
}
-void bn_sqr_comba4(r,a)
-BN_ULONG *r,*a;
+void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
{
#ifdef BN_LLONG
BN_ULLONG t,tt;
/* hmm... is it faster just to do a multiply? */
#undef bn_sqr_comba4
-void bn_sqr_comba4(r,a)
-BN_ULONG *r,*a;
+void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
{
BN_ULONG t[8];
bn_sqr_normal(r,a,4,t);
}
#undef bn_sqr_comba8
-void bn_sqr_comba8(r,a)
-BN_ULONG *r,*a;
+void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
{
BN_ULONG t[16];
bn_sqr_normal(r,a,8,t);
}
-void bn_mul_comba4(r,a,b)
-BN_ULONG *r,*a,*b;
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
{
r[4]=bn_mul_words( &(r[0]),a,4,b[0]);
r[5]=bn_mul_add_words(&(r[1]),a,4,b[1]);
r[7]=bn_mul_add_words(&(r[3]),a,4,b[3]);
}
-void bn_mul_comba8(r,a,b)
-BN_ULONG *r,*a,*b;
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
{
r[ 8]=bn_mul_words( &(r[0]),a,8,b[0]);
r[ 9]=bn_mul_add_words(&(r[1]),a,8,b[1]);