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

📄 mpi.c

📁 椭圆曲线Elliptic Curve)加密算法(
💻 C
📖 第 1 页 / 共 5 页
字号:
/* {{{ s_mp_alloc(nb, ni) */#if MP_MACRO == 0/* Allocate ni records of nb bytes each, and return a pointer to that     */void    *s_mp_alloc(size_t nb, size_t ni){  return calloc(nb, ni);} /* end s_mp_alloc() */#endif/* }}} *//* {{{ s_mp_free(ptr) */#if MP_MACRO == 0/* Free the memory pointed to by ptr                                      */void     s_mp_free(void *ptr){  if(ptr)    free(ptr);} /* end s_mp_free() */#endif/* }}} *//* {{{ s_mp_clamp(mp) *//* Remove leading zeroes from the given value                             */void     s_mp_clamp(mp_int *mp){  mp_size   du = USED(mp);  mp_digit *zp = DIGITS(mp) + du - 1;  while(du > 1 && !*zp--)    --du;  USED(mp) = du;} /* end s_mp_clamp() *//* }}} *//* {{{ s_mp_exch(a, b) *//* Exchange the data for a and b; (b, a) = (a, b)                         */void     s_mp_exch(mp_int *a, mp_int *b){  mp_int   tmp;  tmp = *a;  *a = *b;  *b = tmp;} /* end s_mp_exch() *//* }}} *//* }}} *//* {{{ Arithmetic helpers *//* {{{ s_mp_lshd(mp, p) *//*    Shift mp leftward by p digits, growing if needed, and zero-filling   the in-shifted digits at the right end.  This is a convenient   alternative to multiplication by powers of the radix */   mp_err   s_mp_lshd(mp_int *mp, mp_size p){  mp_err   res;  mp_size  pos;  mp_digit *dp;  int     ix;  if(p == 0)    return MP_OKAY;  if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)    return res;  pos = USED(mp) - 1;  dp = DIGITS(mp);  /* Shift all the significant figures over as needed */  for(ix = pos - p; ix >= 0; ix--)     dp[ix + p] = dp[ix];  /* Fill the bottom digits with zeroes */  for(ix = 0; ix < p; ix++)    dp[ix] = 0;  return MP_OKAY;} /* end s_mp_lshd() *//* }}} *//* {{{ s_mp_rshd(mp, p) *//*    Shift mp rightward by p digits.  Maintains the invariant that   digits above the precision are all zero.  Digits shifted off the   end are lost.  Cannot fail. */void     s_mp_rshd(mp_int *mp, mp_size p){  mp_size  ix;  mp_digit *dp;  if(p == 0)    return;  /* Shortcut when all digits are to be shifted off */  if(p >= USED(mp)) {    s_mp_setz(DIGITS(mp), ALLOC(mp));    USED(mp) = 1;    SIGN(mp) = MP_ZPOS;    return;  }  /* Shift all the significant figures over as needed */  dp = DIGITS(mp);  for(ix = p; ix < USED(mp); ix++)    dp[ix - p] = dp[ix];  /* Fill the top digits with zeroes */  ix -= p;  while(ix < USED(mp))    dp[ix++] = 0;  /* Strip off any leading zeroes    */  s_mp_clamp(mp);} /* end s_mp_rshd() *//* }}} *//* {{{ s_mp_div_2(mp) *//* Divide by two -- take advantage of radix properties to do it fast      */void     s_mp_div_2(mp_int *mp){  s_mp_div_2d(mp, 1);} /* end s_mp_div_2() *//* }}} *//* {{{ s_mp_mul_2(mp) */mp_err s_mp_mul_2(mp_int *mp){  mp_size  ix;  mp_digit kin = 0, kout, *dp = DIGITS(mp);  mp_err   res;  /* Shift digits leftward by 1 bit */  for(ix = 0; ix < USED(mp); ix++) {    kout = (dp[ix] >> (DIGIT_BIT - 1)) & 1;    dp[ix] = (dp[ix] << 1) | kin;    kin = kout;  }  /* Deal with rollover from last digit */  if(kin) {    if(ix >= ALLOC(mp)) {      if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY)	return res;      dp = DIGITS(mp);    }    dp[ix] = kin;    USED(mp) += 1;  }  return MP_OKAY;} /* end s_mp_mul_2() *//* }}} *//* {{{ s_mp_mod_2d(mp, d) *//*  Remainder the integer by 2^d, where d is a number of bits.  This  amounts to a bitwise AND of the value, and does not require the full  division code */void     s_mp_mod_2d(mp_int *mp, mp_digit d){  unsigned int  ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);  unsigned int  ix;  mp_digit      dmask, *dp = DIGITS(mp);  if(ndig >= USED(mp))    return;  /* Flush all the bits above 2^d in its digit */  dmask = (1 << nbit) - 1;  dp[ndig] &= dmask;  /* Flush all digits above the one with 2^d in it */  for(ix = ndig + 1; ix < USED(mp); ix++)    dp[ix] = 0;  s_mp_clamp(mp);} /* end s_mp_mod_2d() *//* }}} *//* {{{ s_mp_mul_2d(mp, d) *//*  Multiply by the integer 2^d, where d is a number of bits.  This  amounts to a bitwise shift of the value, and does not require the  full multiplication code. */mp_err    s_mp_mul_2d(mp_int *mp, mp_digit d){  mp_err   res;  mp_digit save, next, mask, *dp;  mp_size  used;  mp_size  ix;  if((res = s_mp_lshd(mp, d / DIGIT_BIT)) != MP_OKAY)    return res;  dp = DIGITS(mp); used = USED(mp);  d %= DIGIT_BIT;  mask = (1 << d) - 1;  /* If the shift requires another digit, make sure we've got one to     work with */  if((dp[used - 1] >> (DIGIT_BIT - d)) & mask) {    if((res = s_mp_grow(mp, used + 1)) != MP_OKAY)      return res;    dp = DIGITS(mp);  }  /* Do the shifting... */  save = 0;  for(ix = 0; ix < used; ix++) {    next = (dp[ix] >> (DIGIT_BIT - d)) & mask;    dp[ix] = (dp[ix] << d) | save;    save = next;  }  /* If, at this point, we have a nonzero carryout into the next     digit, we'll increase the size by one digit, and store it...   */  if(save) {    dp[used] = save;    USED(mp) += 1;  }  s_mp_clamp(mp);  return MP_OKAY;} /* end s_mp_mul_2d() *//* }}} *//* {{{ s_mp_div_2d(mp, d) *//*  Divide the integer by 2^d, where d is a number of bits.  This  amounts to a bitwise shift of the value, and does not require the  full division code (used in Barrett reduction, see below) */void     s_mp_div_2d(mp_int *mp, mp_digit d){  int       ix;  mp_digit  save, next, mask, *dp = DIGITS(mp);  s_mp_rshd(mp, d / DIGIT_BIT);  d %= DIGIT_BIT;  mask = (1 << d) - 1;  save = 0;  for(ix = USED(mp) - 1; ix >= 0; ix--) {    next = dp[ix] & mask;    dp[ix] = (dp[ix] >> d) | (save << (DIGIT_BIT - d));    save = next;  }  s_mp_clamp(mp);} /* end s_mp_div_2d() *//* }}} *//* {{{ s_mp_norm(a, b) *//*  s_mp_norm(a, b)  Normalize a and b for division, where b is the divisor.  In order  that we might make good guesses for quotient digits, we want the  leading digit of b to be at least half the radix, which we  accomplish by multiplying a and b by a constant.  This constant is  returned (so that it can be divided back out of the remainder at the  end of the division process).  We multiply by the smallest power of 2 that gives us a leading digit  at least half the radix.  By choosing a power of 2, we simplify the   multiplication and division steps to simple shifts. */mp_digit s_mp_norm(mp_int *a, mp_int *b){  mp_digit  t, d = 0;  t = DIGIT(b, USED(b) - 1);  while(t < (RADIX / 2)) {    t <<= 1;    ++d;  }      if(d != 0) {    s_mp_mul_2d(a, d);    s_mp_mul_2d(b, d);  }  return d;} /* end s_mp_norm() *//* }}} *//* }}} *//* {{{ Primitive digit arithmetic *//* {{{ s_mp_add_d(mp, d) *//* Add d to |mp| in place                                                 */mp_err   s_mp_add_d(mp_int *mp, mp_digit d)    /* unsigned digit addition */{  mp_word   w, k = 0;  mp_size   ix = 1, used = USED(mp);  mp_digit *dp = DIGITS(mp);  w = dp[0] + d;  dp[0] = ACCUM(w);  k = CARRYOUT(w);  while(ix < used && k) {    w = dp[ix] + k;    dp[ix] = ACCUM(w);    k = CARRYOUT(w);    ++ix;  }  if(k != 0) {    mp_err  res;    if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)      return res;    DIGIT(mp, ix) = k;  }  return MP_OKAY;} /* end s_mp_add_d() *//* }}} *//* {{{ s_mp_sub_d(mp, d) *//* Subtract d from |mp| in place, assumes |mp| > d                        */mp_err   s_mp_sub_d(mp_int *mp, mp_digit d)    /* unsigned digit subtract */{  mp_word   w, b = 0;  mp_size   ix = 1, used = USED(mp);  mp_digit *dp = DIGITS(mp);  /* Compute initial subtraction    */  w = (RADIX + dp[0]) - d;  b = CARRYOUT(w) ? 0 : 1;  dp[0] = ACCUM(w);  /* Propagate borrows leftward     */  while(b && ix < used) {    w = (RADIX + dp[ix]) - b;    b = CARRYOUT(w) ? 0 : 1;    dp[ix] = ACCUM(w);    ++ix;  }  /* Remove leading zeroes          */  s_mp_clamp(mp);  /* If we have a borrow out, it's a violation of the input invariant */  if(b)    return MP_RANGE;  else    return MP_OKAY;} /* end s_mp_sub_d() *//* }}} *//* {{{ s_mp_mul_d(a, d) *//* Compute a = a * d, single digit multiplication                         */mp_err   s_mp_mul_d(mp_int *a, mp_digit d){  mp_word w, k = 0;  mp_size ix, max;  mp_err  res;  mp_digit *dp = DIGITS(a);  /*    Single-digit multiplication will increase the precision of the    output by at most one digit.  However, we can detect when this    will happen -- if the high-order digit of a, times d, gives a    two-digit result, then the precision of the result will increase;    otherwise it won't.  We use this fact to avoid calling s_mp_pad()    unless absolutely necessary.   */  max = USED(a);  w = dp[max - 1] * d;  if(CARRYOUT(w) != 0) {    if((res = s_mp_pad(a, max + 1)) != MP_OKAY)      return res;    dp = DIGITS(a);  }  for(ix = 0; ix < max; ix++) {    w = (dp[ix] * d) + k;    dp[ix] = ACCUM(w);    k = CARRYOUT(w);  }  /* If there is a precision increase, take care of it here; the above     test guarantees we have enough storage to do this safely.   */  if(k) {    dp[max] = k;     USED(a) = max + 1;  }  s_mp_clamp(a);  return MP_OKAY;  } /* end s_mp_mul_d() *//* }}} *//* {{{ s_mp_div_d(mp, d, r) *//*  s_mp_div_d(mp, d, r)  Compute the quotient mp = mp / d and remainder r = mp mod d, for a  single digit d.  If r is null, the remainder will be discarded. */mp_err   s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r){  mp_word   w = 0, t;  mp_int    quot;  mp_err    res;  mp_digit *dp = DIGITS(mp), *qp;  int       ix;  if(d == 0)    return MP_RANGE;  /* Make room for the quotient */  if((res = mp_init_size(&quot, USED(mp))) != MP_OKAY)    return res;  USED(&quot) = USED(mp); /* so clamping will work below */  qp = DIGITS(&quot);  /* Divide without subtraction */  for(ix = USED(mp) - 1; ix >= 0; ix--) {    w = (w << DIGIT_BIT) | dp[ix];    if(w >= d) {      t = w / d;      w = w % d;    } else {      t = 0;    }    qp[ix] = t;  }  /* Deliver the remainder, if desired */  if(r)    *r = w;  s_mp_clamp(&quot);  mp_exch(&quot, mp);  mp_clear(&quot);  return MP_OKAY;} /* end s_mp_div_d() *//* }}} *//* }}} *//* {{{ Primitive full arithmetic *//* {{{ s_mp_add(a, b) *//* Compute a = |a| + |b|                                                  */mp_err   s_mp_add(mp_int *a, mp_int *b)        /* magnitude addition      */{  mp_word   w = 0;  mp_digit *pa, *pb;  mp_size   ix, used = USED(b);  mp_err    res;  /* Make sure a has enough precision for the output value */  if((used > USED(a)) && (res = s_mp_pad(a, used)) != MP_OKAY)    return res;  /*    Add up all digits up to the precision of b.  If b had initially    the same precision as a, or greater, we took care of it by the    padding step above, so there is no problem.  If b had initially    less precision, we'll have to make sure the carry out is duly    propagated upward among the higher-order digits of the sum.   */  pa = DIGITS(a);  pb = DIGITS(b);  for(ix = 0; ix < used; ++ix) {    w += *pa + *pb++;    *pa++ = ACCUM(w);    w = CARRYOUT(w);  }  /* If we run out of 'b' digits before we're actually done, make     sure the carries get propagated upward...     */  used = USED(a);  while(w && ix < used) {    w += *pa;    *pa++ = ACCUM(w);    w = CARRYOUT(w);    ++ix;  }  /* If there's an overall carry out, increase precision and include     it.  We could have done this initially, but why touch the memory     allocator unless we're sure we have to?   */  if(w) {    if((res = s_mp_pad(a, used + 1)) != MP_OKAY)      return res;    DIGIT(a, ix) = w;  /* pa may not be valid after s_mp_pad() call */  }  return MP_OKAY;} /* end s_mp_add() *//* }}} *//* {{{ s_mp_sub(a, b) *//* Compute a = |a| - |b|, assumes |a| >= |b|                              */mp_err   s_mp_sub(mp_int *a, mp_int *b)        /* magnitude subtract      */{  mp_word   w = 0;  mp_digit *pa, *pb;  mp_size   ix, used = USED(b);  /*    Subtract and propagate borrow.  Up to the precision of b, this    accounts for the digits of b; after that, we just make sure the    carries get to the right place.  This saves having to pad b out to    the precision of a just to make the loops work right...   */  pa = DIGITS(a);  pb = DIGITS(b);  for(ix = 0; ix < used; ++ix) {    w = (RADIX + *pa) - w - *pb++;    *pa++ = ACCUM(w);    w = CARRYOUT(w) ? 0 : 1;  }  used = USED(a);  while(ix < used) {    w = RADIX + *pa - w;    *pa++ = ACCUM(w);    w = CARRYOUT(w) ? 0 : 1;    ++ix;  }  /* Clobber any leading zeroes we created    */  s_mp_clamp(a);  /*      If there was a borrow out, then |b| > |a| in violation     of our input invariant.  We've already done the work,     but we'll at least complain about it...   */  if(w)    return MP_RANGE;  else    return MP_OKAY;} /* end s_mp_sub() *//* }}} *//* {{{ s_mp_mul(a, b) *//* Compute a = |a| * |b|                                                  */mp_err   s_mp_mul(mp_int *a, mp_int *b){  mp_word   w, k = 0;  mp_int    tmp;  mp_err    res;  mp_size   ix, jx, ua = USED(a), ub = USED(b);  mp_digit *pa, *pb, *pt, *pbt;  if((res = mp_init_size(&tmp, ua + ub)) != MP_OKAY)    return res;  /* This has the effect of left-padding with zeroes... */  USED(&tmp) = ua + ub;  /* We're going to need the base value each iteration */  pbt

⌨️ 快捷键说明

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