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

📄 apwrx.c

📁 brew代码里面的一个文件
💻 C
📖 第 1 页 / 共 2 页
字号:

      /* subtract p*q from xy */

      for (j = 0; j <= p_mspos; j++)
      {
        tx[0] = p[j];
        WORD_mul(t,tx,q);

        /* subtract from xy, propagating borrow to msw */

        for (k = j-p_mspos+i; k < 2*N; k++)
        {
          if (t[0] > xy[k])
            /* there's a borrow */
            t[1]++;
          xy[k] -= t[0];
          if (t[1] == 0)
            break;
          t[0] = t[1];
          t[1] = 0;
        }
      }
      /* set t again for loop test */
      if (i < xy_order-1)
        t[1] = xy[i+1];
      else
        t[1] = 0;
      t[0] = xy[i];
    } /* while >= d */
  } /* for i */

  return(0);
}

/* set up the Montgomery information.  */

void InitMont(unsigned WORD *m,   /* storage for -1/p */
        unsigned WORD *p)   /* modulus */
{
  unsigned WORD x, t, u;

  /* determine m.  m is such that m*p[0] modulo 2**BITCT is -1.  Note this
     routine only works if p is odd. */

  x = p[0];
  t = 1;
  u = 2;
  while(u) 
  {
    if ((x*t) & u)
      t += u;
    u <<= 1;
  }
  
  *m = (unsigned WORD)(-(WORD)t);  /* this is to avoid compiler complaints */
}

/* Montgomery reduction */

static
void MontRedN(int N,          /* number of unsigned WORDs in p */
        unsigned WORD *xxr,   /* 2N+1 entries */
        unsigned WORD m,      /* -1/p */
        unsigned WORD *p)     /* modulus */
{
  int i,j,k;
  unsigned WORD c, t[2], tx[2];
  unsigned WORD v, w;

  tx[1] = xxr[2*N] = 0;

  for (i = 0; i < N; i++)
  {
    /* create Montgomery term v = xxr[i]*m */

    v = xxr[i]*m;

    /* add v*p to xxr */

    for (j = 0; j < N; j++)
    {
      tx[0] = p[j];
      WORD_mul(t,tx,v);

      for (k = i+j; k <= 2*N; k++)
      {
        xxr[k] += t[0];
        t[0] = t[1] + (xxr[k] < t[0]);
        t[1] = 0;

        if (t[0] == 0)
          break;
      }
    }
  }

  t[0] = xxr[2*N];  /* xxr[2*N] holds any carries off end */

  /* if no carry, compare result to p, subtract if greater than or equal */

  if (t[0] == 0)
  {
    t[0] = 1;
    for (i = N-1; i >= 0; i--)
    {
      if (p[i] != xxr[i+N])
      {
        if (p[i] > xxr[i+N])
          t[0] = 0;
        break;
      }
    } /* falls off end if equal, with t[0] set to 1 */
  }
  else
    t[0] = 2;

  /* if there was a carry off the end or else if p < xxr, subtract p */

  if (t[0])
  {
    c = 0;
    for (k = 0; k < N; k++)
    {
      w = xxr[k+N];
      v = w - c;
      c = (v > w);
      w = v - p[k];
      c += (w > v);
      xxr[k+N] = w;
    }
  }
}

/* Montgomery a**x mod p */

/*  temporary storage:

  pb:   copy of modulus, dimension Nmax
  axb:  intermediate result, dimension Nmax
  at:   temp used for multiplications, dimension 2*Nmax+1
  ap:   window elements, dimension WindowStorage*Nmax

*/

static unsigned WORD apwrxNtemp[1+((4+WindowStorage)*Nmax)];

int apwrxN(int n,       /* number of bits in p */
       unsigned WORD *a,  /* generator */
       unsigned WORD *x,  /* exponent */
       unsigned WORD *ax, /* result */
       unsigned WORD *p   /* modulus */
      )
{
  int i,j, N;
  int xsize, xisone;
  unsigned WORD mask, m;
  unsigned WORD *axb, *pb, *at, *ap;
  word sigs;  /* Mask of signals returned by rex */


  /* if p is not an odd number, return error */

  if (!(p[0] & 1))
    return(-1);

  /* compute number of unsigned WORDs in n */

  N = (n+BITCT-1)/BITCT;

  if (N > Nmax)
    return(-1);

  /* set pointers */

  axb = apwrxNtemp;
  pb = axb+N;
  at = pb+N;
  ap = at + 2*N+1;

  /* copy the modulus into the buffer; this is to ensure that all arguments
     to the assembly routines have the same segment offset. */

  memcpy(pb, p, N*sizeof(unsigned WORD));

  /* note that by making R and R2 static one could avoid repeating the init step
     for the second exponentiation of Diffie-Hellman */

  InitMont(&m, pb);

  /* compute aR = a*(2**(BITCT*N)) mod p and save in ap[0] */

  memcpy(&at[N], a, N*sizeof(unsigned WORD));
  memset(at, 0, N*sizeof(unsigned WORD));
  if (modpN(N,at,pb,2*N))
    return(-1);
  memcpy(ap, at, N*sizeof(unsigned WORD));

  /* set axb to R mod p */

  memset(at, 0, N*sizeof(unsigned WORD));
  at[N] = 1;
  if (modpN(N,at,pb,N+1))
    return(-1);
  memcpy(axb, at, N*sizeof(unsigned WORD));

  xisone = 1;

  /* set xsize as bit shift to last nonzero word of x */

  /* find leftmost nonzero word */
  for (i = N-1; i >= 0; i--)
    if (x[i] != 0)
      break;

  if (i < 0)
  /* x is zero, the answer is 1 */
  {
    memset(&ax[1], 0, (N-1)*sizeof(unsigned WORD));
    ax[0] = 1;
    return(0);
  }

  /* set xsize to number of bits in nonzero words */

  xsize = (BITCT/WindowSize)*(i+1);
  
  /* adjust to most significant nonzero bit of x[i] */
  
  mask = (unsigned WORD)WindowMask << (BITCT - WindowSize);
  while (mask != 0)
  {
    if (x[i] & mask)
      break;
    xsize--;
    mask >>= WindowSize;
  }

  /* initialize the x**n values */

  for (i = 0; i < WindowStorage/2; i++)
  {
    /* square the value at i (x**(i+1)) to produce the value at 2*i+1 */

    squareN(N, &ap[N*i], at);
    MontRedN(N, at, m, pb);
    memcpy(&ap[N*(2*i+1)], &at[N], N*sizeof(unsigned WORD));

    /* multiply the value at 0 by the value at 2*i+1 to produce
       the value at 2*i+2 */

    mulN(N, ap, &ap[N*(2*i+1)], at);
    MontRedN(N, at, m, pb);
    memcpy(&ap[N*(2*i+2)], &at[N], N*sizeof(unsigned WORD));
  }

  /* multiply by appropriate power of a for each nonzero bit of x */

  for (i = xsize-1; i >= 0; i--)
  {
    if (!xisone)
    {
      for (j = 0; j < WindowSize; j++)
      {
        squareN(N,axb,at);
        MontRedN(N,at,m,pb);
        memcpy(axb, &at[N], N*sizeof(unsigned WORD));
      }
    }

    j = (x[i/(BITCT/WindowSize)] >> WindowSize*(i%(BITCT/WindowSize))) & WindowMask;
    
    if (j)
    /* multiply ax by a**n (depending on window), result in ax */
    {
      xisone = 0;

      /* multiply axb by ap[0]**j, mod p */
      
      mulN(N, &ap[N*(j-1)], axb, at);
      MontRedN(N, at, m, pb);
      memcpy(axb, &at[N], N*sizeof(unsigned WORD));
    }

    sigs = rex_get_sigs(&dh_tcb);
    if ((sigs & DH_RPT_TIMER_SIG) != 0)
    {
       /* -----------------------------
       ** Kick watchdog and reset timer
       ** ----------------------------- */
       dog_report(DOG_DH_RPT);
       (void) rex_set_timer( &dh_rpt_timer, DOG_DH_RPT_TIME );
    }

    if ((sigs & DH_RAND_USED_SIG) != 0)
    {
       /* -----------------------------
       ** Generate random number
       ** ----------------------------- */
       MSG_MED(" RAND_USED_SIG received",0,0,0);
       (void) rex_clr_sigs( &dh_tcb, DH_RAND_USED_SIG );
       generate_rand();
    }

    if ((sigs & DH_ABORT_EXP_SIG) != 0)
    {
       /* -------------------------------
       ** Abort the processing and return
       ** ----------------------------- */
       MSG_MED(" DH_ABORT_EXP_SIG received",0,0,0);
       (void) rex_clr_sigs( &dh_tcb, DH_ABORT_EXP_SIG );
       return(0);
    }
    if ((sigs & TASK_STOP_SIG) != 0)
    {
       /* -------------------------------
       ** ACK the STOP signal and return
       ** ----------------------------- */
       MSG_MED(" TASK_STOP_SIG received",0,0,0);
       (void) rex_clr_sigs( &dh_tcb, TASK_STOP_SIG );
       (void) rex_set_sigs( &mc_tcb, MC_ACK_SIG);
       return(0);
    }
    if ((sigs & TASK_OFFLINE_SIG) != 0)
    {
       /* -------------------------------
       ** ACK the OFFLINE signal and return
       ** ----------------------------- */
       MSG_MED(" TASK_OFFLINE_SIG received",0,0,0);
       (void) rex_clr_sigs( &dh_tcb, TASK_OFFLINE_SIG );
       (void) rex_set_sigs( &mc_tcb, MC_ACK_SIG);
       return(0);
    }
  }

  /* last reduction removes R */

  memcpy(at, axb, N*sizeof(unsigned WORD));
  memset(&at[N], 0, N*sizeof(unsigned WORD));
  MontRedN(N, at, m, pb);

  /* store result in actual ax */

  memcpy(ax, &at[N], N*sizeof(unsigned WORD));

  return(0);
}
#endif /* FEATURE_DH and FEATURE_DH_EXP */

⌨️ 快捷键说明

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