/****************************************************************************** * * * 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; }