/******************************************************************************
*									      *
*  N-WORD ADD								      *
*  04/19/10 (dkc)							      *
*									      *
******************************************************************************/
unsigned int carry(unsigned int a, unsigned int b, unsigned int sum);
void addn(unsigned int *a, unsigned int *b, unsigned int n) {
unsigned int i,s;
unsigned int c[2048];
if (n>2048)
   return;
for (i=n-1; i>0; i--) {
   s=*(a+i)+*(b+i);
   c[i]=carry(*(a+i),*(b+i),s);
   *(b+i)=s;
   }
*b=*a+*b;

for (i=n-2; i>0; i--) {
   s=*(b+i)+c[i+1];
   c[i]+=carry(*(b+i),c[i+1],s);
   *(b+i)=s;
   }
*b=*b+c[1];
return;
}
/******************************************************************************
*									      *
*  N-WORD SUBTRACT							      *
*  04/19/10 (dkc)							      *
*									      *
******************************************************************************/
unsigned int carry(unsigned int a, unsigned int b, unsigned int sum);
void subn(unsigned int *a, unsigned int *b, unsigned int n) {
unsigned int i,s,d;
unsigned int c[2048];
if (n>2048)
   return;
for (i=0; i<n; i++) {
   s=*(b+i);
   *(b+i)=~s;
   }

d=1;
for (i=n-1; i>0; i--) {
   s=*(b+i)+d;
   d=carry(*(b+i),d,s);
   *(b+i)=s;
   }
*b=*b+d;

for (i=n-1; i>0; i--) {
   s=*(a+i)+*(b+i);
   c[i]=carry(*(a+i),*(b+i),s);
   *(b+i)=s;
   }
*b=*a+*b;

for (i=n-2; i>0; i--) {
   s=*(b+i)+c[i+1];
   c[i]+=carry(*(b+i),c[i+1],s);
   *(b+i)=s;
   }
*b=*b+c[1];
return;
}
/*****************************************************************************/
/*									     */
/*  N-WORD RIGHT SHIFT							     */
/*  04/02/10 (dkc)							     */
/*									     */
/*****************************************************************************/
void shiftn(unsigned int *a, unsigned int *b, unsigned int shift, unsigned
	    int n) {
unsigned int i;
for (i=0; i<n; i++)
   *(b+i)=*(a+i);
while (shift>31) {
   for (i=n-1; i>0; i--)
      *(b+i)=*(b+i-1);
   *b=0;
   shift=shift-32;
   }
if (shift==0)
   return;
for (i=n-1; i>0; i--)
   *(b+i)=(*(b+i)>>shift)|(*(b+i-1)<<(32-shift));
*b=*b>>shift;
return;
}
/*****************************************************************************/
/*									     */
/*  N-WORD LEFT SHIFT							     */
/*  10/16/09 (dkc)							     */
/*									     */
/*****************************************************************************/
void lshiftn(unsigned int *a, unsigned int *b, unsigned int shift, unsigned
	     int n) {
unsigned int i;
for (i=0; i<n; i++)
   *(b+i)=*(a+i);
while (shift>31) {
   for (i=0; i<n-1; i++)
      *(b+i)=*(b+i+1);
   *(b+n-1)=0;
   shift=shift-32;
   }
if (shift==0)
   return;
for (i=0; i<n-1; i++)
   *(b+i)=(*(b+i)<<shift)|(*(b+i+1)>>(32-shift));
*(b+n-1)=*(b+n-1)<<shift;
return;
}
/******************************************************************************
*									      *
*  N-WORD NORMALIZATION 						      *
*  04/03/10 (dkc)							      *
*									      *
******************************************************************************/
unsigned int normn(unsigned int *a, unsigned int n) {
unsigned int i,shift,mask;
i=0;
while ((*(a+i)==0)&&(i<n))
   i=i+1;
shift=32*i;
if (i==n)
   return shift;
mask=0x80000000;
while ((*(a+i)&mask)==0) {
   shift=shift+1;
   mask=mask>>1;
   }
return shift;
}
/******************************************************************************
*									      *
*  N-WORD "OR"                                                                *
*  04/02/10 (dkc)							      *
*									      *
******************************************************************************/
unsigned int orn(unsigned int *a, unsigned int n) {
unsigned int i,b;
b=*a;
for (i=1; i<n; i++)
   b=b|*(a+i);
return b;
}
/******************************************************************************
*									      *
*  N-WORD COPY								      *
*  04/02/10 (dkc)							      *
*									      *
******************************************************************************/
void copyn(unsigned int *a, unsigned int *b, unsigned int n) {
unsigned int i;
for (i=0; i<n; i++)
   *(b+i)=*(a+i);
return;
}
/******************************************************************************
*									      *
*  N-WORD CLEAR (AND SET OF LAST WORD)					      *
*  04/02/10 (dkc)							      *
*									      *
******************************************************************************/
void setn(unsigned int *a, unsigned int b, unsigned int n) {
unsigned int i;
for (i=0; i<n-1; i++)
   *(a+i)=0;
*(a+n-1)=b;
return;
}