/******************************************************************************/
/*									      */
/* N-WORD SQUARE ROOT							      */
/* 04/05/14 (dkc)							      */
/*									      */
/******************************************************************************/
void addn(unsigned int *a, unsigned int *b, unsigned int n);
void subn(unsigned int *a, unsigned int *b, unsigned int n);
void shiftn(unsigned int *a, unsigned int *b, unsigned int shift, unsigned
	    int n);
void setn(unsigned int *a, unsigned int b, unsigned int n);
unsigned int normn(unsigned int *a, unsigned int n);
unsigned int orn(unsigned int *a, unsigned int n);
void lshiftn(unsigned int *a, unsigned int *b, unsigned int shift, unsigned
	     int n);
void copyn(unsigned int *a, unsigned int *b, unsigned int n);
//
unsigned int sqrtn(unsigned int num, unsigned int *R, unsigned int m) {
unsigned int count,o;
unsigned int B[64],N[64],T[64],U[64];
if (m>64)
   return(0);
//
// unsigned int res=0;
// unsigned int bit=1<<30;
// while (bit>num)
//    bit>>=2;
// while (bit!=0) {
//    if (num>=res+bit) {
//	 num-=res+bit;
//	 res=(res>>1)+bit;
//	 }
//    else
//	 res>>=1;
//    bit>>=2;
//    }
//
setn(R,0,m);	  // res=0
setn(B,0,m);
B[0]=1<<30;	  // bit=1<<30
setn(N,num,m);
count=normn(N,m);
count=count-1;
if ((count&1)!=0)
   count=count-1;
lshiftn(N,T,count,m);
copyn(T,N,m);
o=orn(B,m);
while (o!=0) {
   copyn(R,T,m);
   addn(B,T,m);    // res+bit
   copyn(T,U,m);   // save res+bit
   subn(N,U,m);    // num-(res+bit)
   if ((U[0]&0x80000000)==0) {
      copyn(U,N,m);   // num-=res+bit
      shiftn(R,R,1,m);	// res>>1
      addn(B,R,m);  // res=(res>>1)+bit
      }
   else
      shiftn(R,R,1,m);	// res>>1
   shiftn(B,B,2,m);   // bit=bit>>2
   o=orn(B,m);
   }
shiftn(R,R,count/2-m*16+32,m);
return(1);
}