⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 function_lib_c.c

📁 网络中交换节点的上数据的交换和下行数据分发的硬件实现
💻 C
📖 第 1 页 / 共 2 页
字号:
              else
                       cf1 = t[1];
              if ((aa += t[0]) < t[0])
                       cf1++;

              NN_DigitMult (t, xi, y[j]);
              if ((aa+=cf2) < cf2)
                     cf2 = t[1]+1;
              else
                    cf2 = t[1];
              if ((aa += t[0]) < t[0])
                     cf2++;
              if(j)A[j-1]=aa;
       }

        cfLow+=cf1;
        if(cfLow<cf1)cfHigh++;
        cfLow+=cf2;
        if(cfLow<cf2)cfHigh++;
        A[digits-1]=cfLow;
        cfLow=cfHigh;
        cfHigh=0;
     }
 }


/*---------------------------------------------

step3:调整 */
        if(cfLow!=0 || NN_Cmp(A,m,digits)>=0)
                NN_Sub(_A,A,m,digits);
        else NN_Assign(_A,A,digits);
}

  
  
  
  
/* Computes a = b - c. Returns borrow.

   Lengths: a[digits], b[digits], c[digits].
 */
NN_DIGIT NN_Sub (a, b, c, digits)
NN_DIGIT *a, *b, *c;
UINT digits;
{
  NN_DIGIT ai, borrow;
  UINT i;

  borrow = 0;

  for (i = 0; i < digits; i++) {
    if ((ai = b[i] - borrow) > (NN_DIGIT)(MAX_NN_DIGIT - borrow))
      ai = MAX_NN_DIGIT - c[i];
    else if ((ai -= c[i]) >(NN_DIGIT) (MAX_NN_DIGIT - c[i]))
      borrow = 1;
    else
      borrow = 0;
    a[i] = ai;
  }

  return (borrow);
}
       
       
       
       
       
       
       
/*--------------------------------------
   Montgomery约化求A= w*(R逆) mod m
   R=(2^32)^t;
  
   注意 w被修改过,w的长度为m的两倍  

---------------------------------------*/

void MontMod(BIG _A,BIG2 w,BIG m,
                  NN_DIGIT mp,INT digits)
{ 

 void NN_DigitMult();
                                             
NN_DIGIT cf0;
	




 
NN_DIGIT t[2],c;
NN_DIGIT carry,*wi;
INT i,j;
cf0=0;
        for(i=0;i<digits;i++)
        {                                      
            c=w[i]*mp; /* mod b */
	        carry = 0;
		    wi=w+i;              
		    for (j = 0; j < digits; j++,wi++) {
                    NN_DigitMult (t, c, m[j]);  
                    *wi+=carry;
                    if (*wi < carry)
                              carry =t[1]+1;
                    else
                              carry = t[1];
                    if (((*wi) += t[0]) < t[0])
                              carry++;
                }
/*
----------------------------------------------------
     carry=LOW(A)
     if( CF )  adjust
*/
          if(carry)

              for (j=digits+i;j<digits*2;j++)
                {
                        w[j]+=carry;
                        if(w[j]>=carry){carry=0;break;};
                        carry=1;
                }                

           cf0+=carry;
   }                                



			
		NN_Assign(w,w+digits,digits);                      
/*调整*/
        if(cf0>0 || NN_Cmp(w,m,digits)>=0)
                NN_Sub(_A,w,m,digits);
        else NN_Assign(_A,w,digits);
}       

 
 
 
/* Assigns a = 0.

   Lengths: a[digits].
 */
void NN_AssignZero (a, digits)
NN_DIGIT *a;
UINT digits;
{
  UINT i;

  for (i = 0; i < digits; i++)
  a[i]=0;
} 





/* Returns the significant length of a in digits.

   Lengths: a[digits].
 */
UINT NN_Digits (a, digits)
NN_DIGIT *a;
UINT digits;
{
  INT i;
  
  for (i = digits - 1; i >= 0; i--)
    if (a[i])
      break;

  return (i + (INT)1);
}




/* Returns the significant length of a in bits, where a is a digit.
 */
 UINT NN_DigitBits (a)
NN_DIGIT a;
{
  UINT i;
  
  for (i = 0; i < NN_DIGIT_BITS; i++, a >>= 1)
    if (a == 0)
      break;
    
  return (i);
}




/* Computes a = b * 2^c (i.e., shifts left c bits), returning carry.

   Lengths: a[digits], b[digits].
   Requires c < NN_DIGIT_BITS.
 */
 NN_DIGIT NN_LShift (a, b, c, digits)
NN_DIGIT *a, *b;
UINT c, digits;
{
  NN_DIGIT bi, carry;
  UINT i, t;
  
  if (c >= NN_DIGIT_BITS)
    return (0);
  
  t = NN_DIGIT_BITS - c;

  carry = 0;

  for (i = 0; i < digits; i++) {
    bi = b[i];
    a[i] = (bi << c) | carry;
    carry = c ? (bi >> t) : 0;
  }
  
  return (carry);
}




/* Computes a = c div 2^c (i.e., shifts right c bits), returning carry.

   Lengths: a[digits], b[digits].
   Requires: c < NN_DIGIT_BITS.
 */
 NN_DIGIT NN_RShift (a, b, c, digits)
NN_DIGIT *a, *b;
UINT c, digits;
{
  NN_DIGIT bi, carry;
  INT i;
  UINT t;
  
  if (c >= NN_DIGIT_BITS)
    return (0);
  
  t = NN_DIGIT_BITS - c;

  carry = 0;

  for (i = digits - 1; i >= 0; i--) {
    bi = b[i];
    a[i] = (bi >> c) | carry;
    carry = c ? (bi << t) : 0;
  }
  
  return (carry);
}




/* Sets a = b / c, where a and c are digits.

   Lengths: b[2].
   Assumes b[1] < c and HIGH_HALF (c) > 0. For efficiency, c should be
   normalized.
 */


void NN_DigitDiv (a, b, c)
NN_DIGIT *a, b[2], c;
{
  NN_DIGIT t[2], u, v;
  NN_HALF_DIGIT aHigh, aLow, cHigh, cLow;

  cHigh = HIGH_HALF (c);
  cLow = LOW_HALF (c);

  t[0] = b[0];
  t[1] = b[1];
  /* Underestimate high half of quotient and subtract.
   */
  if (cHigh == MAX_NN_HALF_DIGIT)
    aHigh = HIGH_HALF (t[1]);
  else
    aHigh = (NN_HALF_DIGIT)(t[1] /(NN_DIGIT) (cHigh + 1));
  u = (NN_DIGIT)aHigh * (NN_DIGIT)cLow;
  v = (NN_DIGIT)aHigh * (NN_DIGIT)cHigh;
  if ((t[0] -= TO_HIGH_HALF (u)) >(NN_DIGIT) (MAX_NN_DIGIT - TO_HIGH_HALF (u)))
    t[1]--;
  t[1] -= HIGH_HALF (u);
  t[1] -= v;

  /* Correct estimate.
   */
  while ((t[1] > cHigh) ||
         ((t[1] == cHigh) && (t[0] >=(NN_DIGIT) TO_HIGH_HALF (cLow)))) {
    if ((t[0] -= TO_HIGH_HALF (cLow)) >
                 (NN_DIGIT)( MAX_NN_DIGIT - TO_HIGH_HALF (cLow)))
      t[1]--;
    t[1] -= cHigh;
    aHigh++;
  }

  /* Underestimate low half of quotient and subtract.
   */
  if (cHigh == MAX_NN_HALF_DIGIT)
    aLow = LOW_HALF (t[1]);
  else
    aLow =
      (NN_HALF_DIGIT)
        ((NN_DIGIT)(TO_HIGH_HALF (t[1]) + HIGH_HALF (t[0])) /(NN_DIGIT) (cHigh + 1));
  u = (NN_DIGIT)aLow * (NN_DIGIT)cLow;
  v = (NN_DIGIT)aLow * (NN_DIGIT)cHigh;
  if ((t[0] -= u) >(NN_DIGIT) (MAX_NN_DIGIT - u))
    t[1]--;
  if ((t[0] -= TO_HIGH_HALF (v)) >(NN_DIGIT) (MAX_NN_DIGIT - TO_HIGH_HALF (v)))
    t[1]--;
  t[1] -= HIGH_HALF (v);

  /* Correct estimate.
   */
  while ((t[1] > 0) || ((t[1] == 0) && t[0] >= c)) {
    if ((t[0] -= c) >(NN_DIGIT) (MAX_NN_DIGIT - c))
      t[1]--;
    aLow++;
  }
  
  *a = TO_HIGH_HALF (aHigh) + aLow;
}


 
 
 
/* Computes a = b - c*d, where c is a digit. Returns borrow.

   Lengths: a[digits], b[digits], d[digits].
 */
 NN_DIGIT NN_SubDigitMult (a, b, c, d, digits)
NN_DIGIT *a, *b, c, *d;
UINT digits;
{ 
  void NN_DigitMult();

  NN_DIGIT borrow, t[2];
  UINT i;

  if (c == 0)
    return (0);

  borrow = 0;
  for (i = 0; i < digits; i++) {
    NN_DigitMult (t, c, d[i]);
    if ((a[i] = b[i] - borrow) >(NN_DIGIT) (MAX_NN_DIGIT - borrow))
      borrow = 1;
    else
      borrow = 0;
    if ((a[i] -= t[0]) >(NN_DIGIT) (MAX_NN_DIGIT - t[0]))
      borrow++;
    borrow += t[1];
  }

  return (borrow);
}




/*
  计算m'=-(m[0]逆) (mod 2^16)
  此函数值为后面的约化函数使用
  函数接口如下:
	输入:大数 BIG _m
	输出:一个整数,其值为_m[0]的逆,即其值与_m[0]的乘积模2^16余1
  说明:
	此函数调用很少,无须汇编优化
  兼容性:
		C语言可移植
*/

NN_DIGIT   m2mp(BIG _m)
{
  NN_DIGIT   m0,mp,a,i;
  m0=_m[0];
  a=_m[0];
  mp=1;
  for(i=2;i!=(NN_DIGIT)0;i<<=1)
  {
          m0<<=1;
          if(((m0+a)&i)==0){
                  a+=m0;
                  mp|=i;
          }

  }
return (NN_DIGIT)((NN_DIGIT)0-mp);    

}




/* Computes a = b * c.

   Lengths: a[2*digits], b[digits], c[digits].
   Assumes digits < MAX_NN_DIGITS.
 */
void NN_Mult (a, b, c, digits)
NN_DIGIT *a, *b, *c;
UINT digits;
{
  NN_DIGIT t[2*MAX_NN_DIGITS];
  UINT bDigits, cDigits, i; 
  
  NN_DIGIT NN_AddDigitMult();

  NN_AssignZero (t, 2 * digits);
  
  bDigits = NN_Digits (b, digits);
  cDigits = NN_Digits (c, digits);

  for (i = 0; i < bDigits; i++)
    t[i+cDigits] += NN_AddDigitMult (&t[i], &t[i], b[i], c, cDigits);
  
  NN_Assign (a, t, 2 * digits);
  
} 




/* Computes a = b * c, where b and c are digits.

   Lengths: a[2].
 */

void NN_DigitMult (a, b, c)
NN_DIGIT a[2], b, c;
{
NN_DIGIT t, u;
NN_HALF_DIGIT bHigh, bLow, cHigh, cLow;

  bHigh = HIGH_HALF (b);
  bLow = LOW_HALF (b);
  cHigh = HIGH_HALF (c);
  cLow = LOW_HALF (c);

  a[0] = (NN_DIGIT)bLow * (NN_DIGIT)cLow;
  t = (NN_DIGIT)bLow * (NN_DIGIT)cHigh;
  u = (NN_DIGIT)bHigh * (NN_DIGIT)cLow;
  a[1] = (NN_DIGIT)bHigh * (NN_DIGIT)cHigh;

  if ((t += u) < u)
    a[1] += TO_HIGH_HALF (1);
  u = TO_HIGH_HALF (t);

  if ((a[0] += u) < u)
    a[1]++;
  a[1] += HIGH_HALF (t);

}


 
 
 
/* Computes a = b + c*d, where c is a digit. Returns carry.

   Lengths: a[digits], b[digits], d[digits].
 */
NN_DIGIT NN_AddDigitMult (a, b, c, d, digits)
NN_DIGIT *a, *b, c, *d;
UINT digits;
{
  NN_DIGIT carry, t[2];
  UINT i;

  if (c == 0)
    return (0);

  carry = 0;
  for (i = 0; i < digits; i++) {
    NN_DigitMult (t, c, d[i]);
    if ((a[i] = b[i] + carry) < carry)
      carry = 1;
    else
      carry = 0;
    if ((a[i] += t[0]) < t[0])
      carry++;
    carry += t[1];
  }
  
  return (carry);
}




/* Compute a = 1/b mod c, assuming inverse exists.
   
   Lengths: a[digits], b[digits], c[digits].
   Assumes gcd (b, c) = 1, digits < MAX_NN_DIGITS.
 */
void NN_ModInv (a, b, c, digits)
NN_DIGIT *a, *b, *c;
UINT digits;
{
  NN_DIGIT q[MAX_NN_DIGITS], t1[MAX_NN_DIGITS], t3[MAX_NN_DIGITS],
    u1[MAX_NN_DIGITS], u3[MAX_NN_DIGITS], v1[MAX_NN_DIGITS],
    v3[MAX_NN_DIGITS], w[2*MAX_NN_DIGITS];
  INT  u1Sign; 
  
  NN_DIGIT NN_Add();

  /* Apply extended Euclidean algorithm, modified to avoid negative
     numbers.
   */
  NN_ASSIGN_DIGIT (u1, 1, digits);
  NN_AssignZero (v1, digits);
  NN_Assign (u3, b, digits);
  NN_Assign (v3, c, digits);
  u1Sign = 1;

  while (! NN_Zero (v3, digits)) {
    NN_Div (q, t3, u3, digits, v3, digits);
    NN_Mult (w, q, v1, digits);
    NN_Add (t1, u1, w, digits);
    NN_Assign (u1, v1, digits);
    NN_Assign (v1, t1, digits);
    NN_Assign (u3, v3, digits);
    NN_Assign (v3, t3, digits);
    u1Sign = -u1Sign;
  }
  
  /* Negate result if sign is negative.
    */
  if (u1Sign < 0)
    NN_Sub (a, c, u1, digits);
  else
    NN_Assign (a, u1, digits);

}



/*Returns the significant length of a in bytes.
  Lengths:a[bytes].
*/
   unsigned char NN_Bytes(a,bytes)
   unsigned char *a;
   int bytes;
   {
    int i;
    
    for(i=bytes-1;i>=0;i--)
     {  if(a[i])
       break;
     } 
       return (unsigned char)(i+(int)1);
    }
    
    
    
   /* Computes a = b + c. Returns carry.

   Lengths: a[digits], b[digits], c[digits].
 */
NN_DIGIT NN_Add (a, b, c, digits)
NN_DIGIT *a, *b, *c;
UINT digits;
{
  NN_DIGIT ai, carry;
  UINT  i;

  carry = 0;

  for (i = 0; i < digits; i++) {
    if ((ai = b[i] + carry) < carry)
      ai = c[i];
    else if ((ai += c[i]) < c[i])
      carry = 1;
    else
      carry = 0;
    a[i] = ai;
  }

  return (carry);
}
   
   

/* 生产随机大数 */
void erandbig(BIG a,INT ww)
{ 

extern NN_DIGIT  exrandx();

INT i;
for(i=0;i<ww;i++)a[i]=exrandx();
}







/**********************************************
                混同余生产随机数
        X(i+1)=0x5deece66d*X(i)+11;
**********************************************/

static NN_DIGIT  rand_seed[4]={1,2,3,4};  
static NN_DIGIT  rand_a[2]={0xdeece66d,0x5}; 
static NN_DIGIT  rand_c[2]={11,0};  

NN_DIGIT  exrandx()
{
NN_DIGIT a;

void NN_Mult();
NN_DIGIT NN_Add();



        NN_Mult(rand_seed,rand_seed,rand_a,2);
        NN_Add(rand_seed,rand_seed,rand_c,2);
        a=(rand_seed[0]>>16)^(rand_seed[1]<<16);
        return a;
}

  
void InitData( )
{


static short highseed = 0x5533 ;
       
       rand_seed[1] = highseed;
       rand_seed[0] = time(NULL);
       
}
   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -