big_num.cpp
上传用户:nbcables
上传日期:2007-01-11
资源大小:1243k
文件大小:13k
源码类别:

钩子与API截获

开发平台:

Visual C++

  1. /*
  2.  * NN.C - natural numbers routines
  3.  */
  4. #include "stdafx.h"
  5. #include "rsaref.h"
  6. #include "big_num.h"
  7. static NN_DIGIT NN_AddDigitMult PROTO_LIST 
  8.   ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT, NN_DIGIT *, unsigned int));
  9. static NN_DIGIT NN_SubDigitMult PROTO_LIST 
  10.   ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT, NN_DIGIT *, unsigned int));
  11. static unsigned int NN_DigitBits PROTO_LIST ((NN_DIGIT));
  12. /* Decodes character string b into a, where character string is ordered
  13.    from most to least significant.
  14.    Lengths: a[digits], b[len].
  15.    Assumes b[i] = 0 for i < len - digits * NN_DIGIT_LEN. (Otherwise most
  16.    significant bytes are truncated.)
  17.  */
  18. void NN_Decode (NN_DIGIT *a, unsigned int digits, unsigned char *b, unsigned int len)
  19. {
  20.   NN_DIGIT t;
  21.   int j;
  22.   unsigned int i, u;
  23.   
  24.   for (i = 0, j = len - 1; i < digits && j >= 0; i++) {
  25.     t = 0;
  26.     for (u = 0; j >= 0 && u < NN_DIGIT_BITS; j--, u += 8)
  27.       t |= ((NN_DIGIT)b[j]) << u;
  28.     a[i] = t;
  29.   }
  30.   
  31.   for (; i < digits; i++)
  32.     a[i] = 0;
  33. }
  34. /* Encodes b into character string a, where character string is ordered
  35.    from most to least significant.
  36.    Lengths: a[len], b[digits].
  37.    Assumes NN_Bits (b, digits) <= 8 * len. (Otherwise most significant
  38.    digits are truncated.)
  39.  */
  40. void NN_Encode (unsigned char *a, unsigned int len, NN_DIGIT *b, unsigned int digits)
  41. {
  42.   NN_DIGIT t;
  43.   int j;
  44.   unsigned int i, u;
  45.   for (i = 0, j = len - 1; i < digits && j >= 0; i++) {
  46.     t = b[i];
  47.     for (u = 0; j >= 0 && u < NN_DIGIT_BITS; j--, u += 8)
  48.       a[j] = (unsigned char)(t >> u);
  49.   }
  50.   for (; j >= 0; j--)
  51.     a[j] = 0;
  52. }
  53. /* Assigns a = b.
  54.    Lengths: a[digits], b[digits].
  55.  */
  56. void NN_Assign (NN_DIGIT *a, NN_DIGIT *b, unsigned int digits)
  57. {
  58.   unsigned int i;
  59.   for (i = 0; i < digits; i++)
  60.     a[i] = b[i];
  61. }
  62. /* Assigns a = 0.
  63.    Lengths: a[digits].
  64.  */
  65. void NN_AssignZero (NN_DIGIT *a, unsigned int digits)
  66. {
  67.   unsigned int i;
  68.   for (i = 0; i < digits; i++)
  69.     a[i] = 0;
  70. }
  71. /* Assigns a = 2^b.
  72.    Lengths: a[digits].
  73.    Requires b < digits * NN_DIGIT_BITS.
  74.  */
  75. void NN_Assign2Exp (NN_DIGIT *a, unsigned int b, unsigned int digits)
  76. {
  77.   NN_AssignZero (a, digits);
  78.   if (b >= digits * NN_DIGIT_BITS)
  79.     return;
  80.   a[b / NN_DIGIT_BITS] = (NN_DIGIT)1 << (b % NN_DIGIT_BITS);
  81. }
  82. /* Computes a = b + c. Returns carry.
  83.    Lengths: a[digits], b[digits], c[digits].
  84.  */
  85. NN_DIGIT NN_Add (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, unsigned int digits)
  86. {
  87.   NN_DIGIT ai, carry;
  88.   unsigned int i;
  89.   carry = 0;
  90.   for (i = 0; i < digits; i++) {
  91.     if ((ai = b[i] + carry) < carry)
  92.       ai = c[i];
  93.     else if ((ai += c[i]) < c[i])
  94.       carry = 1;
  95.     else
  96.       carry = 0;
  97.     a[i] = ai;
  98.   }
  99.   return (carry);
  100. }
  101. /* Computes a = b - c. Returns borrow.
  102.    Lengths: a[digits], b[digits], c[digits].
  103.  */
  104. NN_DIGIT NN_Sub (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, unsigned int digits)
  105. {
  106.   NN_DIGIT ai, borrow;
  107.   unsigned int i;
  108.   borrow = 0;
  109.   for (i = 0; i < digits; i++) {
  110.     if ((ai = b[i] - borrow) > (MAX_NN_DIGIT - borrow))
  111.       ai = MAX_NN_DIGIT - c[i];
  112.     else if ((ai -= c[i]) > (MAX_NN_DIGIT - c[i]))
  113.       borrow = 1;
  114.     else
  115.       borrow = 0;
  116.     a[i] = ai;
  117.   }
  118.   return (borrow);
  119. }
  120. /* Computes a = b * c.
  121.    Lengths: a[2*digits], b[digits], c[digits].
  122.    Assumes digits < MAX_NN_DIGITS.
  123.  */
  124. void NN_Mult (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, unsigned int digits)
  125. {
  126.   NN_DIGIT t[2*MAX_NN_DIGITS];
  127.   unsigned int bDigits, cDigits, i;
  128.   NN_AssignZero (t, 2 * digits);
  129.   
  130.   bDigits = NN_Digits (b, digits);
  131.   cDigits = NN_Digits (c, digits);
  132.   for (i = 0; i < bDigits; i++)
  133.     t[i+cDigits] += NN_AddDigitMult (&t[i], &t[i], b[i], c, cDigits);
  134.   
  135.   NN_Assign (a, t, 2 * digits);
  136.   
  137.   /* Zeroize potentially sensitive information.
  138.    */
  139.   R_memset ((POINTER)t, 0, sizeof (t));
  140. }
  141. /* Computes a = b * 2^c (i.e., shifts left c bits), returning carry.
  142.    Lengths: a[digits], b[digits].
  143.    Requires c < NN_DIGIT_BITS.
  144.  */
  145. NN_DIGIT NN_LShift (NN_DIGIT *a, NN_DIGIT *b, unsigned int c, unsigned int digits)
  146. {
  147.   NN_DIGIT bi, carry;
  148.   unsigned int i, t;
  149.   
  150.   if (c >= NN_DIGIT_BITS)
  151.     return (0);
  152.   
  153.   t = NN_DIGIT_BITS - c;
  154.   carry = 0;
  155.   for (i = 0; i < digits; i++) {
  156.     bi = b[i];
  157.     a[i] = (bi << c) | carry;
  158.     carry = c ? (bi >> t) : 0;
  159.   }
  160.   
  161.   return (carry);
  162. }
  163. /* Computes a = c div 2^c (i.e., shifts right c bits), returning carry.
  164.    Lengths: a[digits], b[digits].
  165.    Requires: c < NN_DIGIT_BITS.
  166.  */
  167. NN_DIGIT NN_RShift (NN_DIGIT *a, NN_DIGIT *b, unsigned int c, unsigned int digits)
  168. {
  169.   NN_DIGIT bi, carry;
  170.   int i;
  171.   unsigned int t;
  172.   
  173.   if (c >= NN_DIGIT_BITS)
  174.     return (0);
  175.   
  176.   t = NN_DIGIT_BITS - c;
  177.   carry = 0;
  178.   for (i = digits - 1; i >= 0; i--) {
  179.     bi = b[i];
  180.     a[i] = (bi >> c) | carry;
  181.     carry = c ? (bi << t) : 0;
  182.   }
  183.   
  184.   return (carry);
  185. }
  186. /* Computes a = c div d and b = c mod d.
  187.    Lengths: a[cDigits], b[dDigits], c[cDigits], d[dDigits].
  188.    Assumes d > 0, cDigits < 2 * MAX_NN_DIGITS,
  189.            dDigits < MAX_NN_DIGITS.
  190.  */
  191. void NN_Div (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, unsigned int cDigits, NN_DIGIT *d, unsigned int dDigits)
  192. {
  193.   NN_DIGIT ai, cc[2*MAX_NN_DIGITS+1], dd[MAX_NN_DIGITS], t;
  194.   int i;
  195.   unsigned int ddDigits, shift;
  196.   
  197.   ddDigits = NN_Digits (d, dDigits);
  198.   if (ddDigits == 0)
  199.     return;
  200.   
  201.   /* Normalize operands.
  202.    */
  203.   shift = NN_DIGIT_BITS - NN_DigitBits (d[ddDigits-1]);
  204.   NN_AssignZero (cc, ddDigits);
  205.   cc[cDigits] = NN_LShift (cc, c, shift, cDigits);
  206.   NN_LShift (dd, d, shift, ddDigits);
  207.   t = dd[ddDigits-1];
  208.   
  209.   NN_AssignZero (a, cDigits);
  210.   for (i = cDigits-ddDigits; i >= 0; i--) {
  211.     /* Underestimate quotient digit and subtract.
  212.      */
  213.     if (t == MAX_NN_DIGIT)
  214.       ai = cc[i+ddDigits];
  215.     else
  216.       NN_DigitDiv (&ai, &cc[i+ddDigits-1], t + 1);
  217.     cc[i+ddDigits] -= NN_SubDigitMult (&cc[i], &cc[i], ai, dd, ddDigits);
  218.     /* Correct estimate.
  219.      */
  220.     while (cc[i+ddDigits] || (NN_Cmp (&cc[i], dd, ddDigits) >= 0)) {
  221.       ai++;
  222.       cc[i+ddDigits] -= NN_Sub (&cc[i], &cc[i], dd, ddDigits);
  223.     }
  224.     
  225.     a[i] = ai;
  226.   }
  227.   
  228.   /* Restore result.
  229.    */
  230.   NN_AssignZero (b, dDigits);
  231.   NN_RShift (b, cc, shift, ddDigits);
  232.   /* Zeroize potentially sensitive information.
  233.    */
  234.   R_memset ((POINTER)cc, 0, sizeof (cc));
  235.   R_memset ((POINTER)dd, 0, sizeof (dd));
  236. }
  237. /* Computes a = b mod c.
  238.    Lengths: a[cDigits], b[bDigits], c[cDigits].
  239.    Assumes c > 0, bDigits < 2 * MAX_NN_DIGITS, cDigits < MAX_NN_DIGITS.
  240.  */
  241. void NN_Mod (NN_DIGIT *a, NN_DIGIT *b, unsigned int bDigits, NN_DIGIT *c, unsigned int cDigits)
  242. {
  243.   NN_DIGIT t[2 * MAX_NN_DIGITS];
  244.   
  245.   NN_Div (t, a, b, bDigits, c, cDigits);
  246.   
  247.   /* Zeroize potentially sensitive information.
  248.    */
  249.   R_memset ((POINTER)t, 0, sizeof (t));
  250. }
  251. /* Computes a = b * c mod d.
  252.    Lengths: a[digits], b[digits], c[digits], d[digits].
  253.    Assumes d > 0, digits < MAX_NN_DIGITS.
  254.  */
  255. void NN_ModMult (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, NN_DIGIT *d, unsigned int digits)
  256. {
  257.   NN_DIGIT t[2*MAX_NN_DIGITS];
  258.   NN_Mult (t, b, c, digits);
  259.   NN_Mod (a, t, 2 * digits, d, digits);
  260.   
  261.   /* Zeroize potentially sensitive information.
  262.    */
  263.   R_memset ((POINTER)t, 0, sizeof (t));
  264. }
  265. /* Computes a = b^c mod d.
  266.    Lengths: a[dDigits], b[dDigits], c[cDigits], d[dDigits].
  267.    Assumes d > 0, cDigits > 0, dDigits < MAX_NN_DIGITS.
  268.  */
  269. /* PGP 2.5's mpilib contains a faster modular exponentiation routine, mp_modexp.
  270.    If USEMPILIB is defined, NN_ModExp is replaced in the PGP 2.5 sources with a 
  271.    stub call to mp_modexp.  If USEMPILIB is not defined, we'll get a pure (albeit
  272.    slower) RSAREF implementation.
  273.    The RSAREF 2.0 license, clause 1(c), permits "...modify[ing] the Program in any
  274.    manner for porting or performance improvement purposes..." */
  275. #ifndef USEMPILIB
  276. void NN_ModExp (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, unsigned int cDigits, NN_DIGIT *d, unsigned int dDigits)
  277. {
  278.   NN_DIGIT bPower[3][MAX_NN_DIGITS], ci, t[MAX_NN_DIGITS];
  279.   int i;
  280.   unsigned int ciBits, j, s;
  281.   /* Store b, b^2 mod d, and b^3 mod d.
  282.    */
  283.   NN_Assign (bPower[0], b, dDigits);
  284.   NN_ModMult (bPower[1], bPower[0], b, d, dDigits);
  285.   NN_ModMult (bPower[2], bPower[1], b, d, dDigits);
  286.   
  287.   NN_ASSIGN_DIGIT (t, 1, dDigits);
  288.   cDigits = NN_Digits (c, cDigits);
  289.   for (i = cDigits - 1; i >= 0; i--) {
  290.     ci = c[i];
  291.     ciBits = NN_DIGIT_BITS;
  292.     
  293.     /* Scan past leading zero bits of most significant digit.
  294.      */
  295.     if (i == (int)(cDigits - 1)) {
  296.       while (! DIGIT_2MSB (ci)) {
  297.         ci <<= 2;
  298.         ciBits -= 2;
  299.       }
  300.     }
  301.     for (j = 0; j < ciBits; j += 2, ci <<= 2) {
  302.       /* Compute t = t^4 * b^s mod d, where s = two MSB's of ci.
  303.        */
  304.       NN_ModMult (t, t, t, d, dDigits);
  305.       NN_ModMult (t, t, t, d, dDigits);
  306.       if ((s = DIGIT_2MSB (ci)) != 0)
  307.         NN_ModMult (t, t, bPower[s-1], d, dDigits);
  308.     }
  309.   }
  310.   
  311.   NN_Assign (a, t, dDigits);
  312.   
  313.   /* Zeroize potentially sensitive information.
  314.    */
  315.   R_memset ((POINTER)bPower, 0, sizeof (bPower));
  316.   R_memset ((POINTER)t, 0, sizeof (t));
  317. }
  318. #endif
  319. /* Compute a = 1/b mod c, assuming inverse exists.
  320.    
  321.    Lengths: a[digits], b[digits], c[digits].
  322.    Assumes gcd (b, c) = 1, digits < MAX_NN_DIGITS.
  323.  */
  324. void NN_ModInv (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, unsigned int digits)
  325. {
  326.   NN_DIGIT q[MAX_NN_DIGITS], t1[MAX_NN_DIGITS], t3[MAX_NN_DIGITS],
  327.     u1[MAX_NN_DIGITS], u3[MAX_NN_DIGITS], v1[MAX_NN_DIGITS],
  328.     v3[MAX_NN_DIGITS], w[2*MAX_NN_DIGITS];
  329.   int u1Sign;
  330.   /* Apply extended Euclidean algorithm, modified to avoid negative
  331.      numbers.
  332.    */
  333.   NN_ASSIGN_DIGIT (u1, 1, digits);
  334.   NN_AssignZero (v1, digits);
  335.   NN_Assign (u3, b, digits);
  336.   NN_Assign (v3, c, digits);
  337.   u1Sign = 1;
  338.   while (! NN_Zero (v3, digits)) {
  339.     NN_Div (q, t3, u3, digits, v3, digits);
  340.     NN_Mult (w, q, v1, digits);
  341.     NN_Add (t1, u1, w, digits);
  342.     NN_Assign (u1, v1, digits);
  343.     NN_Assign (v1, t1, digits);
  344.     NN_Assign (u3, v3, digits);
  345.     NN_Assign (v3, t3, digits);
  346.     u1Sign = -u1Sign;
  347.   }
  348.   
  349.   /* Negate result if sign is negative.
  350.     */
  351.   if (u1Sign < 0)
  352.     NN_Sub (a, c, u1, digits);
  353.   else
  354.     NN_Assign (a, u1, digits);
  355.   /* Zeroize potentially sensitive information.
  356.    */
  357.   R_memset ((POINTER)q, 0, sizeof (q));
  358.   R_memset ((POINTER)t1, 0, sizeof (t1));
  359.   R_memset ((POINTER)t3, 0, sizeof (t3));
  360.   R_memset ((POINTER)u1, 0, sizeof (u1));
  361.   R_memset ((POINTER)u3, 0, sizeof (u3));
  362.   R_memset ((POINTER)v1, 0, sizeof (v1));
  363.   R_memset ((POINTER)v3, 0, sizeof (v3));
  364.   R_memset ((POINTER)w, 0, sizeof (w));
  365. }
  366. /* Computes a = gcd(b, c).
  367.    Lengths: a[digits], b[digits], c[digits].
  368.    Assumes b > c, digits < MAX_NN_DIGITS.
  369.  */
  370. void NN_Gcd (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, unsigned int digits)
  371. {
  372.   NN_DIGIT t[MAX_NN_DIGITS], u[MAX_NN_DIGITS], v[MAX_NN_DIGITS];
  373.   NN_Assign (u, b, digits);
  374.   NN_Assign (v, c, digits);
  375.   while (! NN_Zero (v, digits)) {
  376.     NN_Mod (t, u, digits, v, digits);
  377.     NN_Assign (u, v, digits);
  378.     NN_Assign (v, t, digits);
  379.   }
  380.   NN_Assign (a, u, digits);
  381.   /* Zeroize potentially sensitive information.
  382.    */
  383.   R_memset ((POINTER)t, 0, sizeof (t));
  384.   R_memset ((POINTER)u, 0, sizeof (u));
  385.   R_memset ((POINTER)v, 0, sizeof (v));
  386. }
  387. /* Returns sign of a - b.
  388.    Lengths: a[digits], b[digits].
  389.  */
  390. int NN_Cmp (NN_DIGIT *a, NN_DIGIT *b, unsigned int digits)
  391. {
  392.   int i;
  393.   
  394.   for (i = digits - 1; i >= 0; i--) {
  395.     if (a[i] > b[i])
  396.       return (1);
  397.     if (a[i] < b[i])
  398.       return (-1);
  399.   }
  400.   return (0);
  401. }
  402. /* Returns nonzero iff a is zero.
  403.    Lengths: a[digits].
  404.  */
  405. int NN_Zero (NN_DIGIT *a, unsigned int digits)
  406. {
  407.   unsigned int i;
  408.   
  409.   for (i = 0; i < digits; i++)
  410.     if (a[i])
  411.       return (0);
  412.     
  413.   return (1);
  414. }
  415. /* Returns the significant length of a in bits.
  416.    Lengths: a[digits].
  417.  */
  418. unsigned int NN_Bits (NN_DIGIT *a, unsigned int digits)
  419. {
  420.   if ((digits = NN_Digits (a, digits)) == 0)
  421.     return (0);
  422.   return ((digits - 1) * NN_DIGIT_BITS + NN_DigitBits (a[digits-1]));
  423. }
  424. /* Returns the significant length of a in digits.
  425.    Lengths: a[digits].
  426.  */
  427. unsigned int NN_Digits (NN_DIGIT *a, unsigned int digits)
  428. {
  429.   int i;
  430.   
  431.   for (i = digits - 1; i >= 0; i--)
  432.     if (a[i])
  433.       break;
  434.   return (i + 1);
  435. }
  436. /* Computes a = b + c*d, where c is a digit. Returns carry.
  437.    Lengths: a[digits], b[digits], d[digits].
  438.  */
  439. static NN_DIGIT NN_AddDigitMult (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT c, NN_DIGIT *d, unsigned int digits)
  440. {
  441.   NN_DIGIT carry, t[2];
  442.   unsigned int i;
  443.   if (c == 0)
  444.     return (0);
  445.   carry = 0;
  446.   for (i = 0; i < digits; i++) {
  447.     NN_DigitMult (t, c, d[i]);
  448.     if ((a[i] = b[i] + carry) < carry)
  449.       carry = 1;
  450.     else
  451.       carry = 0;
  452.     if ((a[i] += t[0]) < t[0])
  453.       carry++;
  454.     carry += t[1];
  455.   }
  456.   
  457.   return (carry);
  458. }
  459. /* Computes a = b - c*d, where c is a digit. Returns borrow.
  460.    Lengths: a[digits], b[digits], d[digits].
  461.  */
  462. static NN_DIGIT NN_SubDigitMult (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT c, NN_DIGIT *d, unsigned int digits)
  463. {
  464.   NN_DIGIT borrow, t[2];
  465.   unsigned int i;
  466.   if (c == 0)
  467.     return (0);
  468.   borrow = 0;
  469.   for (i = 0; i < digits; i++) {
  470.     NN_DigitMult (t, c, d[i]);
  471.     if ((a[i] = b[i] - borrow) > (MAX_NN_DIGIT - borrow))
  472.       borrow = 1;
  473.     else
  474.       borrow = 0;
  475.     if ((a[i] -= t[0]) > (MAX_NN_DIGIT - t[0]))
  476.       borrow++;
  477.     borrow += t[1];
  478.   }
  479.   
  480.   return (borrow);
  481. }
  482. /* Returns the significant length of a in bits, where a is a digit.
  483.  */
  484. static unsigned int NN_DigitBits (NN_DIGIT a)
  485. {
  486.   unsigned int i;
  487.   
  488.   for (i = 0; i < NN_DIGIT_BITS; i++, a >>= 1)
  489.     if (a == 0)
  490.       break;
  491.     
  492.   return (i);
  493. }