信息安全——ELGamal数字签名方案的实现

来源:互联网 发布:中国电信网络营业厅 编辑:程序博客网 时间:2024/05/19 09:12

转载:http://blog.csdn.net/lishuhuakai/article/details/9117619

ELGamal数字签名方案的实现

1. 问题描述

为简化问题,我们取p=19,g=2,私钥x=9,则公钥y=29 mod 19=18。消息m的ELGamal签名为(r,s),其中r=gk mod p,s=(h(m)-xr)k-1 mod (p-1)

2.基本要求

   考虑p取大素数的情况。

3. 实现提示

①     模n求逆a-1modn运算。

②     模n的大数幂乘运算

       由于大素数的本原元要求得很费事,所以签名所需要的数值我已经事先给出,当然这些数值比较小,有兴趣的同学可以自行将数值变大.

       ELGamal离不开大数包的支持!

BigInteger.h

[cpp] view plain copy
print?
  1. #pragma once  
  2. #include <cstring>  
  3. #include <string>  
  4. #include <algorithm>  
  5. #include <assert.h>  
  6. #include <ctime>  
  7. #include <iostream>  
  8.   
  9. using namespace std;  
  10. const int maxLength = 512;  
  11. const int primeLength = 30;  
  12. const int primesBelow2000[303] = {  
  13.     2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,  
  14.     101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,  
  15.     211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293,  
  16.     307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397,  
  17.     401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499,  
  18.     503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599,  
  19.     601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691,  
  20.     701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797,  
  21.     809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887,  
  22.     907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,  
  23.     1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097,  
  24.     1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193,  
  25.     1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297,  
  26.     1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,  
  27.     1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499,  
  28.     1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597,  
  29.     1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699,  
  30.     1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,  
  31.     1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889,  
  32.     1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999 };  
  33.   
  34. class BigInteger  
  35. {  
  36.     typedef unsigned char byte;  
  37. public:  
  38.     BigInteger(void);  
  39.     BigInteger(__int64 value);  
  40.     BigInteger(unsigned __int64 value);  
  41.     BigInteger(const BigInteger &bi);  
  42.     BigInteger(string value, int radix);  
  43.     BigInteger(byte inData[], int inLen);  
  44.     BigInteger(unsigned int inData[], int inLen);  
  45.   
  46.     BigInteger operator -();  
  47.     BigInteger operator =(const BigInteger &bi2);  
  48.   
  49.     BigInteger operator +(BigInteger &bi2);  
  50.     BigInteger operator -(BigInteger bi2);  
  51.   
  52.     BigInteger operator /(BigInteger bi2);  
  53.     BigInteger operator (BigInteger bi2);  
  54.     void singleByteDivide(BigInteger &bi1, BigInteger &bi2, BigInteger &outQuotient, BigInteger &outRemainder);  
  55.     void multiByteDivide(BigInteger &bi1, BigInteger &bi2, BigInteger &outQuotient, BigInteger &outRemainder);  
  56.   
  57.     BigInteger operator %(BigInteger bi2);  
  58.   
  59.     BigInteger operator +=(BigInteger bi2);  
  60.     BigInteger operator -=(BigInteger bi2);  
  61.   
  62.     int bitCount();  
  63.     BigInteger modPow(BigInteger exp, BigInteger n);  
  64.       
  65.   
  66.     friend ostream& operator<<(ostream& output, BigInteger &bi1);  
  67.     friend BigInteger GetPrime();  
  68.     friend bool Miller_Robin(BigInteger &bi1);  
  69.     friend BigInteger MultipInverse(BigInteger &bi1, BigInteger &n);  
  70.     friend BigInteger extended_euclidean(BigInteger n, BigInteger m, BigInteger &x, BigInteger &y);   
  71.     friend BigInteger MultipInverse(BigInteger &bi1, BigInteger &n);   //求乘法逆  
  72.     friend BigInteger Gcd(BigInteger &bi1, BigInteger &bi2);   //求最大公约数  
  73.     friend bool IsPrime (BigInteger &obj);  
  74.   
  75.     BigInteger BarrettReduction(BigInteger x, BigInteger n, BigInteger constant);  
  76.   
  77.     bool operator >=(BigInteger bi2)  
  78.     {  
  79.         return ((this) == bi2 || (*this) > bi2);  
  80.     }  
  81.   
  82.     bool operator >(BigInteger bi2);  
  83.     bool operator ==(BigInteger bi2);  
  84.     bool operator !=(BigInteger bi2);  
  85.       
  86.       
  87.     int shiftRight(unsigned int buffer[], int bufLen, int shiftVal);  
  88.     BigInteger operator <<(int shiftVal);  
  89.     int shiftLeft(unsigned int buffer[], int bufLen, int shiftVal);  
  90.     bool operator <(BigInteger bi2);  
  91.   
  92.     string DecToHex(unsigned int value, string format);  
  93.     string ToHexString();  
  94.   
  95. public:  
  96.     ~BigInteger(void);    
  97.   
  98. public:  
  99.     int dataLength;  
  100.         // number of actual chars used  
  101.     unsigned int *data;  
  102. };  
#pragma once

#include <cstring>#include <string>#include <algorithm>#include <assert.h>#include <ctime>#include <iostream>using namespace std;const int maxLength = 512;const int primeLength = 30;const int primesBelow2000[303] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999 };class BigInteger{ typedef unsigned char byte;public: BigInteger(void); BigInteger(__int64 value); BigInteger(unsigned __int64 value); BigInteger(const BigInteger &bi); BigInteger(string value, int radix); BigInteger(byte inData[], int inLen); BigInteger(unsigned int inData[], int inLen); BigInteger operator -(); BigInteger operator =(const BigInteger &bi2); BigInteger operator +(BigInteger &bi2); BigInteger operator -(BigInteger bi2); BigInteger operator /(BigInteger bi2); BigInteger operator *(BigInteger bi2); void singleByteDivide(BigInteger &bi1, BigInteger &bi2, BigInteger &outQuotient, BigInteger &outRemainder); void multiByteDivide(BigInteger &bi1, BigInteger &bi2, BigInteger &outQuotient, BigInteger &outRemainder); BigInteger operator %(BigInteger bi2); BigInteger operator +=(BigInteger bi2); BigInteger operator -=(BigInteger bi2); int bitCount(); BigInteger modPow(BigInteger exp, BigInteger n); friend ostream& operator<<(ostream& output, BigInteger &bi1); friend BigInteger GetPrime(); friend bool Miller_Robin(BigInteger &bi1); friend BigInteger MultipInverse(BigInteger &bi1, BigInteger &n); friend BigInteger extended_euclidean(BigInteger n, BigInteger m, BigInteger &x, BigInteger &y); friend BigInteger MultipInverse(BigInteger &bi1, BigInteger &n); //求乘法逆 friend BigInteger Gcd(BigInteger &bi1, BigInteger &bi2); //求最大公约数 friend bool IsPrime (BigInteger &obj); BigInteger BarrettReduction(BigInteger x, BigInteger n, BigInteger constant); bool operator >=(BigInteger bi2) { return ((*this) == bi2 || (*this) > bi2); } bool operator >(BigInteger bi2); bool operator ==(BigInteger bi2); bool operator !=(BigInteger bi2); int shiftRight(unsigned int buffer[], int bufLen, int shiftVal); BigInteger operator <<(int shiftVal); int shiftLeft(unsigned int buffer[], int bufLen, int shiftVal); bool operator <(BigInteger bi2); string DecToHex(unsigned int value, string format); string ToHexString();public: ~BigInteger(void); public: int dataLength; // number of actual chars used unsigned int *data;};
BigInteger.cpp

[cpp] view plain copy
print?
  1. #include “BigInteger.h”  
  2.   
  3. BigInteger::BigInteger(void)   //默认的构造函数  
  4. : dataLength(0), data(0)  
  5. {  
  6.     data = new unsigned int[maxLength];  
  7.     memset(data, 0, maxLength * sizeof(unsigned int));  
  8.     dataLength = 1;  
  9. }  
  10.   
  11. BigInteger::BigInteger(__int64 value)   //用一个64位的值来初始化大数  
  12. {  
  13.     data = new unsigned int[maxLength];  
  14.     memset(data, 0, maxLength * sizeof(unsigned int));   //先清零  
  15.     __int64 tempVal = value;  
  16.   
  17.     dataLength = 0;  
  18.     while (value != 0 && dataLength < maxLength)  
  19.     {  
  20.         data[dataLength] = (unsigned int)(value & 0xFFFFFFFF);   //取低位  
  21.         value = value >> 32;   //进位  
  22.         dataLength++;  
  23.     }  
  24.   
  25.     if (tempVal > 0)         // overflow check for +ve value  
  26.     {  
  27.         if (value != 0 || (data[maxLength - 1] & 0x80000000) != 0)  
  28.             assert(false);  
  29.     }  
  30.     else if (tempVal < 0)    // underflow check for -ve value  
  31.     {  
  32.         if (value != -1 || (data[dataLength - 1] & 0x80000000) == 0)  
  33.             assert(false);  
  34.     }  
  35.   
  36.     if (dataLength == 0)  
  37.         dataLength = 1;  
  38. }  
  39.   
  40. BigInteger::BigInteger(unsigned __int64 value)   //用一个无符号的64位整数来初始化大数  
  41. {  
  42.     data = new unsigned int[maxLength];  
  43.     memset(data, 0, maxLength * sizeof(unsigned int));  
  44.   
  45.     dataLength = 0;  
  46.     while (value != 0 && dataLength < maxLength)  
  47.     {  
  48.         data[dataLength] = (unsigned int)(value & 0xFFFFFFFF);  
  49.         value >>= 32;  
  50.         dataLength++;  
  51.     }  
  52.   
  53.     if (value != 0 || (data[maxLength - 1] & 0x80000000) != 0)  
  54.         assert(false);  
  55.   
  56.     if (dataLength == 0)   //防止输入的value=0  
  57.         dataLength = 1;  
  58. }  
  59.   
  60. BigInteger::BigInteger(const BigInteger &bi)   //用大数初始化大数  
  61. {  
  62.     data = new unsigned int[maxLength];  
  63.     dataLength = bi.dataLength;  
  64.   
  65.     for (int i = 0; i < maxLength; i++)   //考虑到有负数的情况,所以每一位都要复制  
  66.         data[i] = bi.data[i];  
  67. }  
  68.   
  69. BigInteger::~BigInteger(void)  
  70. {  
  71.     if (data != NULL)  
  72.     {  
  73.         delete []data;  
  74.     }  
  75. }  
  76.   
  77. BigInteger::BigInteger(string value, int radix)   //输入转换函数,将字符串转换成对应进制的大数  
  78. {   //一般不处理负数  
  79.     BigInteger multiplier((__int64)1);  
  80.     BigInteger result;  
  81.     transform(value.begin(), value.end(), value.begin(), toupper);   //将小写字母转换成为大写  
  82.   
  83.     int limit = 0;  
  84.   
  85.     if (value[0] == ‘-‘)     
  86.         limit = 1;  
  87.   
  88.     for (int i = value.size() - 1; i >= limit; i–)  
  89.     {  
  90.         int posVal = (int)value[i];  
  91.   
  92.         if (posVal >= ‘0’ && posVal <= ‘9’)  //将字符转换成数字  
  93.             posVal -= ’0’;  
  94.         else if (posVal >= ‘A’ && posVal <= ‘Z’)  
  95.             posVal = (posVal - ’A’) + 10;  
  96.         else  
  97.             posVal = 9999999;       // arbitrary large 输入别的字符  
  98.   
  99.   
  100.         if (posVal >= radix)   //不能大于特定的进制,否则终止  
  101.         {  
  102.             assert(false);  
  103.         }  
  104.         else  
  105.         {  
  106.             result = result + (multiplier * BigInteger((__int64)posVal));  
  107.   
  108.             if ((i - 1) >= limit)   //没有到达尾部  
  109.                 multiplier = multiplier * BigInteger((__int64)radix);  
  110.         }  
  111.     }  
  112.       
  113.     if (value[0] == ‘-‘)   //符号最后再处理  
  114.        result = -result;  
  115.   
  116.     if (value[0] == ‘-‘)     //输入为负数,但得到的结果为正数,可能溢出了  
  117.     {  
  118.         if ((result.data[maxLength - 1] & 0x80000000) == 0)     
  119.             assert(false);  
  120.     }  
  121.     else    //或者说,输入为正数,得到的结果为负数,也可能溢出了  
  122.     {  
  123.         if ((result.data[maxLength - 1] & 0x80000000) != 0)    
  124.             assert(false);  
  125.     }  
  126.   
  127.   
  128.     data = new unsigned int[maxLength];  
  129.     //memset(data, 0, maxLength * sizeof(unsigned int));  
  130.     for (int i = 0; i < maxLength; i++)  
  131.         data[i] = result.data[i];  
  132.   
  133.     dataLength = result.dataLength;  
  134. }  
  135.   
  136. BigInteger::BigInteger(byte inData[], int inLen)   //用一个char类型的数组来初始化大数  
  137. {  
  138.     dataLength = inLen >> 2;   //一个unsigned int占32位,而一个unsigned char只占8位  
  139.     //因此dataLength应该是至少是inLen/4,不一定整除  
  140.   
  141.     int leftOver = inLen & 0x3;    
  142.     //取最低两位的数值,为什么要这样干呢?实际上是为了探测len是不是4的倍数,好确定dataLength的长度  
  143.     if (leftOver != 0)    //不能整除的话,dataLength要加1  
  144.         dataLength++;  
  145.   
  146.   
  147.     if (dataLength > maxLength)  
  148.         assert(false);  
  149.   
  150.     data = new unsigned int[maxLength];  
  151.     memset(data, 0, maxLength * sizeof(unsigned int));  
  152.   
  153.     for (int i = inLen - 1, j = 0; i >= 3; i -= 4, j++)     
  154.     {  
  155.         data[j] = (unsigned int)((inData[i - 3] << 24) + (inData[i - 2] << 16) + (inData[i - 1] << 8) + inData[i]);  
  156. //我们知道:一个unsigned int占32位,而一个unsigned char只占8位,因此四个unsigned char才能组成一个unsigned int  
  157. //因此取inData[i - 3]为前32-25位,inData[i - 2]为前24-17~~~  
  158. //i % 4 = 0 or 1 or 2 or 3 余0表示恰好表示完  
  159.     }  
  160.   
  161.     if (leftOver == 1)  
  162.         data[dataLength - 1] = (unsigned int)inData[0];  
  163.     else if (leftOver == 2)  
  164.         data[dataLength - 1] = (unsigned int)((inData[0] << 8) + inData[1]);  
  165.     else if (leftOver == 3)  
  166.         data[dataLength - 1] = (unsigned int)((inData[0] << 16) + (inData[1] << 8) + inData[2]);  
  167.   
  168.   
  169.     while (dataLength > 1 && data[dataLength - 1] == 0)  
  170.         dataLength–;  
  171. }  
  172.   
  173. BigInteger::BigInteger(unsigned int inData[], int inLen)   //用一个unsigned int型数组初始化大数  
  174. {  
  175.     dataLength = inLen;  
  176.   
  177.     if (dataLength > maxLength)  
  178.         assert(false);  
  179.   
  180.     data = new unsigned int[maxLength];  
  181.     memset(data, 0, maxLength * sizeof(maxLength));  
  182.   
  183.     for (int i = dataLength - 1, j = 0; i >= 0; i–, j++)  
  184.         data[j] = inData[i];  
  185.   
  186.     while (dataLength > 1 && data[dataLength - 1] == 0)  
  187.         dataLength–;  
  188. }  
  189.   
  190. BigInteger BigInteger::operator *(BigInteger bi2)   //乘法的重载  
  191. {  
  192.     BigInteger bi1(*this);  
  193.     int lastPos = maxLength - 1;  
  194.     bool bi1Neg = false, bi2Neg = false;  
  195.   
  196.     //首先对两个乘数取绝对值  
  197.     try  
  198.     {  
  199.         if ((this->data[lastPos] & 0x80000000) != 0)     //bi1为负数  
  200.         {  
  201.             bi1Neg = true;   
  202.             bi1 = -bi1;  
  203.         }  
  204.         if ((bi2.data[lastPos] & 0x80000000) != 0)     //bi2为负数  
  205.         {  
  206.             bi2Neg = true; bi2 = -bi2;  
  207.         }  
  208.     }  
  209.     catch (…) { }  
  210.   
  211.     BigInteger result;  
  212.   
  213.     //绝对值相乘  
  214.     try  
  215.     {  
  216.         for (int i = 0; i < bi1.dataLength; i++)  
  217.         {  
  218.             if (bi1.data[i] == 0) continue;  
  219.   
  220.             unsigned __int64 mcarry = 0;  
  221.             for (int j = 0, k = i; j < bi2.dataLength; j++, k++)  
  222.             {  
  223.                 // k = i + j  
  224.                 unsigned __int64 val = ((unsigned __int64)bi1.data[i] * (unsigned __int64)bi2.data[j]) + (unsigned __int64)result.data[k] + mcarry;  
  225.                 result.data[k] = (unsigned __int64)(val & 0xFFFFFFFF);   //取低位  
  226.                 mcarry = (val >> 32);   //进位  
  227.             }  
  228.   
  229.             if (mcarry != 0)  
  230.             result.data[i + bi2.dataLength] = (unsigned int)mcarry;  
  231.         }  
  232.     }  
  233.     catch (…)  
  234.     {  
  235.         assert(false);  
  236.     }  
  237.   
  238.   
  239.     result.dataLength = bi1.dataLength + bi2.dataLength;  
  240.     if (result.dataLength > maxLength)  
  241.         result.dataLength = maxLength;  
  242.   
  243.     while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0)  
  244.         result.dataLength–;  
  245.   
  246.     // overflow check (result is -ve)溢出检查  
  247.     if ((result.data[lastPos] & 0x80000000) != 0)  //结果为负数  
  248.     {  
  249.         if (bi1Neg != bi2Neg && result.data[lastPos] == 0x80000000)    //两乘数符号不同  
  250.         {  
  251.             // handle the special case where multiplication produces  
  252.             // a max negative number in 2’s complement.  
  253.   
  254.             if (result.dataLength == 1)  
  255.                 return result;  
  256.             else  
  257.             {  
  258.                 bool isMaxNeg = true;  
  259.                 for (int i = 0; i < result.dataLength - 1 && isMaxNeg; i++)  
  260.                 {  
  261.                     if (result.data[i] != 0)  
  262.                         isMaxNeg = false;  
  263.                 }  
  264.   
  265.                 if (isMaxNeg)  
  266.                     return result;  
  267.             }  
  268.         }  
  269.   
  270.         assert(false);  
  271.     }  
  272.   
  273.     //两乘数符号不同,结果为负数  
  274.     if (bi1Neg != bi2Neg)  
  275.         return -result;  
  276.   
  277.     return result;  
  278. }  
  279.   
  280. BigInteger BigInteger::operator =(const BigInteger &bi2)  
  281. {  
  282.     if (&bi2 == this)  
  283.     {  
  284.         return *this;  
  285.     }  
  286.     if (data != NULL)  
  287.     {  
  288.         delete []data;  
  289.         data = NULL;  
  290.     }  
  291.     data = new unsigned int[maxLength];  
  292.     memset(data, 0, maxLength * sizeof(unsigned int));  
  293.   
  294.     dataLength = bi2.dataLength;  
  295.   
  296.     for (int i = 0; i < maxLength; i++)  
  297.         data[i] = bi2.data[i];  
  298.     return *this;  
  299. }  
  300.   
  301. BigInteger BigInteger::operator +(BigInteger &bi2)  
  302. {  
  303.     int lastPos = maxLength - 1;  
  304.     bool bi1Neg = false, bi2Neg = false;  
  305.     BigInteger bi1(*this);  
  306.     BigInteger result;  
  307.   
  308.     if ((this->data[lastPos] & 0x80000000) != 0)     //bi1为负数  
  309.           bi1Neg = true;   
  310.     if ((bi2.data[lastPos] & 0x80000000) != 0)     //bi2为负数  
  311.             bi2Neg = true;   
  312.   
  313.     if(bi1Neg == false && bi2Neg == false)   //bi1与bi2都是正数  
  314.     {  
  315.         result.dataLength = (this->dataLength > bi2.dataLength) ? this->dataLength : bi2.dataLength;  
  316.   
  317.         __int64 carry = 0;  
  318.         for (int i = 0; i < result.dataLength; i++)   //从低位开始,逐位相加  
  319.         {  
  320.             __int64 sum = (__int64)this->data[i] + (__int64)bi2.data[i] + carry;  
  321.             carry = sum >> 32;   //进位  
  322.             result.data[i] = (unsigned int)(sum & 0xFFFFFFFF);  //取低位结果  
  323.         }  
  324.   
  325.         if (carry != 0 && result.dataLength < maxLength)  
  326.         {  
  327.             result.data[result.dataLength] = (unsigned int)(carry);  
  328.             result.dataLength++;  
  329.         }  
  330.   
  331.         while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0)  
  332.             result.dataLength–;  
  333.   
  334.   
  335.         //溢出检查  
  336.         if ((this->data[lastPos] & 0x80000000) == (bi2.data[lastPos] & 0x80000000) &&  
  337.             (result.data[lastPos] & 0x80000000) != (this->data[lastPos] & 0x80000000))  
  338.         {  
  339.             assert(false);  
  340.         }  
  341.         return result;  
  342.     }  
  343.     //关键在于,负数全部要转化成为正数来做  
  344.     if(bi1Neg == false && bi2Neg == true)   //bi1正,bi2负  
  345.     {  
  346.         BigInteger bi3 = -bi2;  
  347.         if(bi1 > bi3)  
  348.         {  
  349.          result = bi1 - bi3;   
  350.          return result;  
  351.         }  
  352.         else  
  353.         {  
  354.          result = -(bi3 - bi1);  
  355.          return result;  
  356.         }  
  357.     }  
  358.   
  359.     if(bi1Neg == true && bi2Neg == false)  //bi1负,bi2正  
  360.     {  
  361.         BigInteger bi3 = -bi1;  
  362.         if(bi3 > bi2)  
  363.         {  
  364.          result = -(bi3 - bi2);  
  365.          return result;  
  366.         }  
  367.         else  
  368.         {  
  369.          result = bi2 - bi3;  
  370.          return result;  
  371.         }  
  372.     }  
  373.   
  374.     if(bi1Neg == true && bi2Neg == true)  //bi1负,bi2负  
  375.     {  
  376.         result = - ((-bi1) + (-bi2));  
  377.         return result;  
  378.     }  
  379. }  
  380.   
  381. BigInteger BigInteger::operator -()  
  382. {  
  383.     //逐位取反并+1  
  384.     if (this->dataLength == 1 && this->data[0] == 0)  
  385.         return *this;  
  386.   
  387.     BigInteger result(*this);  
  388.   
  389.     for (int i = 0; i < maxLength; i++)  
  390.         result.data[i] = (unsigned int)(~(this->data[i]));   //取反  
  391.   
  392.     __int64 val, carry = 1;  
  393.     int index = 0;  
  394.   
  395.     while (carry != 0 && index < maxLength)  //+1;  
  396.     {  
  397.         val = (__int64)(result.data[index]);  
  398.         val++;   //由于值加了1个1,往前面的进位最多也只是1个1,因此val++就完了  
  399.   
  400.         result.data[index] = (unsigned int)(val & 0xFFFFFFFF);   //取低位部分  
  401.         carry = val >> 32;   //进位  
  402.   
  403.         index++;  
  404.     }  
  405.   
  406.     if ((this->data[maxLength - 1] & 0x80000000) == (result.data[maxLength - 1] & 0x80000000))  
  407.         result.dataLength = maxLength;  
  408.   
  409.     while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0)  
  410.         result.dataLength–;  
  411.       
  412.     return result;  
  413. }  
  414.   
  415. BigInteger BigInteger::modPow(BigInteger exp, BigInteger n)   //求this^exp mod n  
  416. {  
  417.     if ((exp.data[maxLength - 1] & 0x80000000) != 0)   //指数是负数  
  418.     return BigInteger((__int64)0);  
  419.   
  420.     BigInteger resultNum((__int64)1);  
  421.     BigInteger tempNum;  
  422.     bool thisNegative = false;  
  423.   
  424.     if ((this->data[maxLength - 1] & 0x80000000) != 0)   //底数是负数  
  425.     {  
  426.         tempNum = -(*this) % n;  
  427.         thisNegative = true;  
  428.     }  
  429.     else  
  430.         tempNum = (*this) % n;  //保证(tempNum * tempNum) < b^(2k)  
  431.   
  432.     if ((n.data[maxLength - 1] & 0x80000000) != 0)   //n为负  
  433.         n = -n;  
  434.   
  435.     //计算 constant = b^(2k) / m  
  436.     //constant主要用于后面的Baeert Reduction算法  
  437.     BigInteger constant;  
  438.   
  439.     int i = n.dataLength << 1;  
  440.     constant.data[i] = 0x00000001;  
  441.     constant.dataLength = i + 1;  
  442.   
  443.     constant = constant / n;  
  444.     int totalBits = exp.bitCount();  
  445.     int count = 0;  
  446.   
  447.     //平方乘法算法  
  448.     for (int pos = 0; pos < exp.dataLength; pos++)  
  449.     {  
  450.         unsigned int mask = 0x01;  
  451.   
  452.         for (int index = 0; index < 32; index++)  
  453.         {  
  454.             if ((exp.data[pos] & mask) != 0)  //某一个bit不为0  
  455.             resultNum = BarrettReduction(resultNum * tempNum, n, constant);  
  456.             //resultNum = resultNum * tempNum mod n  
  457.   
  458.             mask <<= 1; //不断左移  
  459.   
  460.             tempNum = BarrettReduction(tempNum * tempNum, n, constant);  
  461.             //tempNum = tempNum * tempNum mod n  
  462.   
  463.             if (tempNum.dataLength == 1 && tempNum.data[0] == 1)  
  464.             {  
  465.                 if (thisNegative && (exp.data[0] & 0x1) != 0)    //指数为奇数  
  466.                     return -resultNum;  
  467.                 return resultNum;  
  468.             }  
  469.             count++;  
  470.             if (count == totalBits)  
  471.                 break;  
  472.         }  
  473.     }  
  474.   
  475.     if (thisNegative && (exp.data[0] & 0x1) != 0)    //底数为负数,指数为奇数  
  476.         return -resultNum;  
  477.   
  478.     return resultNum;  
  479. }  
  480.   
  481. int BigInteger::bitCount()   //计算字节数  
  482. {  
  483.     while (dataLength > 1 && data[dataLength - 1] == 0)  
  484.         dataLength–;  
  485.   
  486.     unsigned int value = data[dataLength - 1];  
  487.     unsigned int mask = 0x80000000;  
  488.     int bits = 32;  
  489.   
  490.     while (bits > 0 && (value & mask) == 0)   //计算最高位的bit  
  491.     {  
  492.         bits–;  
  493.         mask >>= 1;  
  494.     }  
  495.     bits += ((dataLength - 1) << 5);   //余下的位都有32bit  
  496.     //左移5位,相当于乘以32,即2^5  
  497.     return bits;  
  498. }  
  499.   
  500. BigInteger BigInteger::BarrettReduction(BigInteger x, BigInteger n, BigInteger constant)  
  501. {  
  502.   
  503. //算法,Baeert Reduction算法,在计算大规模的除法运算时很有优势  
  504. //原理如下  
  505. //Z mod N=Z-[Z/N]*N=Z-{[Z/b^(n-1)]*[b^2n/N]/b^(n+1)}*N=Z-q*N  
  506. //q=[Z/b^(n-1)]*[b^2n/N]/b^(n+1)  
  507. //其中,[]表示取整运算,A^B表示A的B次幂  
  508.   
  509.     int k = n.dataLength,  
  510.         kPlusOne = k + 1,  
  511.         kMinusOne = k - 1;  
  512.   
  513.     BigInteger q1;  
  514.   
  515.     // q1 = x / b^(k-1)  
  516.     for (int i = kMinusOne, j = 0; i < x.dataLength; i++, j++)  
  517.         q1.data[j] = x.data[i];  
  518.     q1.dataLength = x.dataLength - kMinusOne;  
  519.     if (q1.dataLength <= 0)  
  520.         q1.dataLength = 1;  
  521.   
  522.   
  523.     BigInteger q2 = q1 * constant;  
  524.     BigInteger q3;  
  525.   
  526.     // q3 = q2 / b^(k+1)  
  527.     for (int i = kPlusOne, j = 0; i < q2.dataLength; i++, j++)  
  528.         q3.data[j] = q2.data[i];  
  529.     q3.dataLength = q2.dataLength - kPlusOne;  
  530.     if (q3.dataLength <= 0)  
  531.         q3.dataLength = 1;  
  532.   
  533.   
  534.     // r1 = x mod b^(k+1)  
  535.     // i.e. keep the lowest (k+1) words  
  536.     BigInteger r1;  
  537.     int lengthToCopy = (x.dataLength > kPlusOne) ? kPlusOne : x.dataLength;  
  538.     for (int i = 0; i < lengthToCopy; i++)  
  539.         r1.data[i] = x.data[i];  
  540.     r1.dataLength = lengthToCopy;  
  541.   
  542.   
  543.     // r2 = (q3 * n) mod b^(k+1)  
  544.     // partial multiplication of q3 and n  
  545.   
  546.     BigInteger r2;  
  547.     for (int i = 0; i < q3.dataLength; i++)  
  548.     {  
  549.         if (q3.data[i] == 0) continue;  
  550.   
  551.         unsigned __int64 mcarry = 0;  
  552.         int t = i;  
  553.         for (int j = 0; j < n.dataLength && t < kPlusOne; j++, t++)  
  554.         {  
  555.             // t = i + j  
  556.             unsigned __int64 val = ((unsigned __int64)q3.data[i] * (unsigned __int64)n.data[j]) +  
  557.                 (unsigned __int64)r2.data[t] + mcarry;  
  558.   
  559.             r2.data[t] = (unsigned int)(val & 0xFFFFFFFF);  
  560.             mcarry = (val >> 32);  
  561.         }  
  562.   
  563.         if (t < kPlusOne)  
  564.             r2.data[t] = (unsigned int)mcarry;  
  565.     }  
  566.     r2.dataLength = kPlusOne;  
  567.     while (r2.dataLength > 1 && r2.data[r2.dataLength - 1] == 0)  
  568.         r2.dataLength–;  
  569.   
  570.     r1 -= r2;  
  571.     if ((r1.data[maxLength - 1] & 0x80000000) != 0)        // negative  
  572.     {  
  573.         BigInteger val;  
  574.         val.data[kPlusOne] = 0x00000001;  
  575.         val.dataLength = kPlusOne + 1;  
  576.         r1 += val;  
  577.     }  
  578.   
  579.     while (r1 >= n)  
  580.         r1 -= n;  
  581.   
  582.     return r1;  
  583. }  
  584.   
  585. bool BigInteger::operator >(BigInteger bi2)  
  586. {  
  587.     int pos = maxLength - 1;  
  588.     BigInteger bi1(*this);  
  589.   
  590.     // bi1 is negative, bi2 is positive  
  591.     if ((bi1.data[pos] & 0x80000000) != 0 && (bi2.data[pos] & 0x80000000) == 0)  
  592.         return false;  
  593.   
  594.     // bi1 is positive, bi2 is negative  
  595.     else if ((bi1.data[pos] & 0x80000000) == 0 && (bi2.data[pos] & 0x80000000) != 0)  
  596.         return true;  
  597.   
  598.     // same sign  
  599.     int len = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength;  
  600.     for (pos = len - 1; pos >= 0 && bi1.data[pos] == bi2.data[pos]; pos–) ;  
  601.   
  602.     if (pos >= 0)  
  603.     {  
  604.         if (bi1.data[pos] > bi2.data[pos])  
  605.             return true;  
  606.         return false;  
  607.     }  
  608.     return false;  
  609. }  
  610.   
  611. bool BigInteger::operator ==(BigInteger bi2)  
  612. {  
  613.     if (this->dataLength != bi2.dataLength)  
  614.         return false;  
  615.   
  616.     for (int i = 0; i < this->dataLength; i++)  
  617.     {  
  618.         if (this->data[i] != bi2.data[i])  
  619.             return false;  
  620.     }  
  621.     return true;  
  622. }  
  623.   
  624. bool BigInteger::operator !=(BigInteger bi2)  
  625. {  
  626.     if(this->dataLength != bi2.dataLength)  
  627.         return true;  
  628.     for(int i = 0; i < this->dataLength; i++)  
  629.     {  
  630.         if(this->data[i] != bi2.data[i])  
  631.             return true;  
  632.     }  
  633.     return false;  
  634. }  
  635.   
  636. BigInteger BigInteger::operator %(BigInteger bi2)  
  637. {  
  638.     BigInteger bi1(*this);  
  639.     BigInteger quotient;  
  640.     BigInteger remainder(bi1);  
  641.   
  642.     int lastPos = maxLength - 1;  
  643.     bool dividendNeg = false;  
  644.   
  645.     if ((bi1.data[lastPos] & 0x80000000) != 0)     // bi1 negative  
  646.     {  
  647.         bi1 = -bi1;  
  648.         dividendNeg = true;  
  649.     }  
  650.     if ((bi2.data[lastPos] & 0x80000000) != 0)     // bi2 negative  
  651.         bi2 = -bi2;  
  652.   
  653.     if (bi1 < bi2)  
  654.     {  
  655.         return remainder;  
  656.     }  
  657.   
  658.     else  
  659.     {  
  660.         if (bi2.dataLength == 1)  
  661.             singleByteDivide(bi1, bi2, quotient, remainder);   //bi2只占一个位置时,用singleByteDivide更快  
  662.         else  
  663.             multiByteDivide(bi1, bi2, quotient, remainder);   //bi2占多个位置时,用multiByteDivide更快  
  664.   
  665.         if (dividendNeg)  
  666.             return -remainder;  
  667.   
  668.         return remainder;  
  669.     }  
  670. }  
  671.   
  672. void BigInteger::singleByteDivide(BigInteger &bi1, BigInteger &bi2,  
  673.                       BigInteger &outQuotient, BigInteger &outRemainder)  
  674. {//outQuotient商,outRemainder余数  
  675.   
  676.     unsigned int result[maxLength];   //用来存储结果  
  677.     memset(result, 0, sizeof(unsigned int) * maxLength);  
  678.     int resultPos = 0;  
  679.   
  680.     for (int i = 0; i < maxLength; i++)   //将bi1复制至outRemainder  
  681.         outRemainder.data[i] = bi1.data[i];  
  682.     outRemainder.dataLength = bi1.dataLength;  
  683.   
  684.     while (outRemainder.dataLength > 1 && outRemainder.data[outRemainder.dataLength - 1] == 0)  
  685.         outRemainder.dataLength–;  
  686.   
  687.     unsigned __int64 divisor = (unsigned __int64)bi2.data[0];  
  688.     int pos = outRemainder.dataLength - 1;  
  689.     unsigned __int64 dividend = (unsigned __int64)outRemainder.data[pos];   //取最高位的数值  
  690.   
  691.   
  692.     if (dividend >= divisor)   //被除数>除数  
  693.     {  
  694.         unsigned __int64 quotient = dividend / divisor;  
  695.         result[resultPos++] = (unsigned __int64)quotient;   //结果  
  696.   
  697.         outRemainder.data[pos] = (unsigned __int64)(dividend % divisor);   //余数  
  698.     }  
  699.     pos–;  
  700.   
  701.     while (pos >= 0)  
  702.     {  
  703.         dividend = ((unsigned __int64)outRemainder.data[pos + 1] << 32) + (unsigned __int64)outRemainder.data[pos];   //前一位的余数和这一位的值相加  
  704.         unsigned __int64 quotient = dividend / divisor;   //得到结果  
  705.         result[resultPos++] = (unsigned int)quotient;   //结果取低位  
  706.   
  707.         outRemainder.data[pos + 1] = 0;   //前一位的余数清零  
  708.         outRemainder.data[pos–] = (unsigned int)(dividend % divisor);   //得到这一位的余数  
  709.     }  
  710.   
  711.     outQuotient.dataLength = resultPos;   //商的长度是resultPos的长度  
  712.     int j = 0;  
  713.     for (int i = outQuotient.dataLength - 1; i >= 0; i–, j++)  //将商反转过来   
  714.         outQuotient.data[j] = result[i];  
  715.     for (; j < maxLength; j++)   //商的其余位都要置0  
  716.         outQuotient.data[j] = 0;  
  717.   
  718.     while (outQuotient.dataLength > 1 && outQuotient.data[outQuotient.dataLength - 1] == 0)  
  719.         outQuotient.dataLength–;  
  720.   
  721.     if (outQuotient.dataLength == 0)  
  722.         outQuotient.dataLength = 1;  
  723.   
  724.     while (outRemainder.dataLength > 1 && outRemainder.data[outRemainder.dataLength - 1] == 0)  
  725.         outRemainder.dataLength–;  
  726. }  
  727.   
  728. void BigInteger::multiByteDivide(BigInteger &bi1, BigInteger &bi2,  
  729.                      BigInteger &outQuotient, BigInteger &outRemainder)  
  730. {  
  731.     unsigned int result[maxLength];  
  732.     memset(result, 0, sizeof(unsigned int) * maxLength);   //结果置零   
  733.   
  734.     int remainderLen = bi1.dataLength + 1;   //余数长度  
  735.     unsigned int *remainder = new unsigned int[remainderLen];  
  736.     memset(remainder, 0, sizeof(unsigned int) * remainderLen);   //余数置零  
  737.   
  738.     unsigned int mask = 0x80000000;  
  739.     unsigned int val = bi2.data[bi2.dataLength - 1];  
  740.     int shift = 0, resultPos = 0;  
  741.   
  742.     while (mask != 0 && (val & mask) == 0)  
  743.     {  
  744.         shift++; mask >>= 1;  
  745.     }     
  746.     //最高位从高到低找出shift个0位  
  747.     for (int i = 0; i < bi1.dataLength; i++)  
  748.         remainder[i] = bi1.data[i];   //将bi1复制到remainder之中  
  749.     this->shiftLeft(remainder, remainderLen, shift);   //remainder左移shift位  
  750.     bi2 = bi2 << shift;   //向左移shift位,将空位填满  
  751.     //由于两个数都扩大了相同的倍数,所以结果不变  
  752.   
  753.     int j = remainderLen - bi2.dataLength;   //j表示两个数长度的差值,也是要计算的次数  
  754.     int pos = remainderLen - 1;   //pos指示余数的最高位的位置,现在pos=bi1.dataLength  
  755.   
  756.     //以下的步骤并没有别的意思,主要是用来试商  
  757.     unsigned __int64 firstDivisorByte = bi2.data[bi2.dataLength - 1];   //第一个除数  
  758.     unsigned __int64 secondDivisorByte = bi2.data[bi2.dataLength - 2];  //第二个除数   
  759.   
  760.     int divisorLen = bi2.dataLength + 1;   //除数的长度  
  761.     unsigned int *dividendPart = new unsigned int[divisorLen];   //起名为除数的部分  
  762.     memset(dividendPart, 0, sizeof(unsigned int) * divisorLen);  
  763.   
  764.     while (j > 0)  
  765.     {  
  766.         unsigned __int64 dividend = ((unsigned __int64)remainder[pos] << 32) + (unsigned __int64)remainder[pos - 1];   //取余数的高两位  
  767.   
  768.         unsigned __int64 q_hat = dividend / firstDivisorByte;   //得到一个商  
  769.         unsigned __int64 r_hat = dividend % firstDivisorByte;   //以及一个余数  
  770.   
  771.         bool done = false;   //表示没有做完  
  772.         while (!done)  
  773.         {  
  774.             done = true;  
  775.   
  776.             if (q_hat == 0x100000000 || (q_hat * secondDivisorByte) > ((r_hat << 32) + remainder[pos - 2]))   //这里主要用来调整商的大小   
  777.             //(q_hat * secondDivisorByte) > ((r_hat << 32) + remainder[pos - 2]))是害怕上的商过大,减之后变为负数  
  778.             //商q_hat也不能超过32bit  
  779.             {  
  780.                 q_hat–;   //否则的话,就商小一点,余数大一点  
  781.                 r_hat += firstDivisorByte;  
  782.   
  783.                 if (r_hat < 0x100000000)   //如果余数小于32bit,就继续循环  
  784.                     done = false;  
  785.             }  
  786.         }  
  787.   
  788.         for (int h = 0; h < divisorLen; h++)   //取被除数的高位部分,高位部分长度与除数长度一致  
  789.             dividendPart[h] = remainder[pos - h];  
  790.   
  791.         BigInteger kk(dividendPart, divisorLen);  
  792.         BigInteger ss = bi2 * BigInteger((__int64)q_hat);  
  793.   
  794.         while (ss > kk)   //调节商的大小  
  795.         {  
  796.             q_hat–;  
  797.             ss -= bi2;  
  798.         }  
  799.         BigInteger yy = kk - ss;   //得到余数  
  800.   
  801.         for (int h = 0; h < divisorLen; h++)  //将yy高位和remainder低位拼接起来,得到余数  
  802.             remainder[pos - h] = yy.data[bi2.dataLength - h];   //取得真正的余数  
  803.   
  804.         result[resultPos++] = (unsigned int)q_hat;  
  805.   
  806.         pos–;  
  807.         j–;  
  808.     }  
  809.   
  810.     outQuotient.dataLength = resultPos;  
  811.     int y = 0;  
  812.     for (int x = outQuotient.dataLength - 1; x >= 0; x–, y++)   //将商反转过来  
  813.         outQuotient.data[y] = result[x];  
  814.     for (; y < maxLength; y++)   //商的其余位都要置0  
  815.         outQuotient.data[y] = 0;  
  816.   
  817.     while (outQuotient.dataLength > 1 && outQuotient.data[outQuotient.dataLength - 1] == 0)  
  818.         outQuotient.dataLength–;  
  819.   
  820.     if (outQuotient.dataLength == 0)  
  821.         outQuotient.dataLength = 1;  
  822.   
  823.     outRemainder.dataLength = this->shiftRight(remainder, remainderLen, shift);  
  824.   
  825.     for (y = 0; y < outRemainder.dataLength; y++)  
  826.         outRemainder.data[y] = remainder[y];  
  827.     for (; y < maxLength; y++)  
  828.         outRemainder.data[y] = 0;  
  829.   
  830.     delete []remainder;  
  831.     delete []dividendPart;  
  832. }  
  833.   
  834. int BigInteger::shiftRight(unsigned int buffer[], int bufferLen,int shiftVal)   //右移操作  
  835. {//自己用图画模拟一下移位操作,就能很快明白意义了  
  836.     int shiftAmount = 32;  
  837.     int invShift = 0;  
  838.     int bufLen = bufferLen;  
  839.   
  840.     while (bufLen > 1 && buffer[bufLen - 1] == 0)  
  841.         bufLen–;  
  842.   
  843.     for (int count = shiftVal; count > 0; )  
  844.     {  
  845.         if (count < shiftAmount)  
  846.         {  
  847.             shiftAmount = count;  
  848.             invShift = 32 - shiftAmount;  
  849.         }  
  850.   
  851.         unsigned __int64 carry = 0;  
  852.         for (int i = bufLen - 1; i >= 0; i–)  
  853.         {  
  854.             unsigned __int64 val = ((unsigned __int64)buffer[i]) >> shiftAmount;  
  855.             val |= carry;  
  856.   
  857.             carry = ((unsigned __int64)buffer[i]) << invShift;  
  858.             buffer[i] = (unsigned int)(val);  
  859.         }  
  860.   
  861.         count -= shiftAmount;  
  862.     }  
  863.   
  864.     while (bufLen > 1 && buffer[bufLen - 1] == 0)  
  865.         bufLen–;  
  866.   
  867.     return bufLen;  
  868. }  
  869.   
  870. BigInteger BigInteger::operator <<(int shiftVal)  
  871. {  
  872.     BigInteger result(*this);  
  873.     result.dataLength = shiftLeft(result.data, maxLength, shiftVal);  
  874.   
  875.     return result;  
  876. }  
  877.   
  878. int BigInteger::shiftLeft(unsigned int buffer[], int bufferLen, int shiftVal)  
  879. {  
  880.     int shiftAmount = 32;  
  881.     int bufLen = bufferLen;  
  882.   
  883.     while (bufLen > 1 && buffer[bufLen - 1] == 0)  
  884.         bufLen–;  
  885.   
  886.     for (int count = shiftVal; count > 0; )  
  887.     {  
  888.         if (count < shiftAmount)  
  889.             shiftAmount = count;  
  890.   
  891.         unsigned __int64 carry = 0;  
  892.         for (int i = 0; i < bufLen; i++)  
  893.         {  
  894.             unsigned __int64 val = ((unsigned __int64)buffer[i]) << shiftAmount;  
  895.             val |= carry;  
  896.   
  897.             buffer[i] = (unsigned int)(val & 0xFFFFFFFF);  
  898.             carry = val >> 32;  
  899.         }  
  900.   
  901.         if (carry != 0)  
  902.         {  
  903.             if (bufLen + 1 <= bufferLen)  
  904.             {  
  905.                 buffer[bufLen] = (unsigned int)carry;  
  906.                 bufLen++;  
  907.             }  
  908.         }  
  909.         count -= shiftAmount;  
  910.     }  
  911.     return bufLen;  
  912. }  
  913.   
  914. bool BigInteger::operator <(BigInteger bi2)  
  915. {  
  916.     BigInteger bi1(*this);  
  917.     int pos = maxLength - 1;  
  918.   
  919.     // bi1 is negative, bi2 is positive  
  920.     if ((bi1.data[pos] & 0x80000000) != 0 && (bi2.data[pos] & 0x80000000) == 0)  
  921.         return true;  
  922.   
  923.     // bi1 is positive, bi2 is negative  
  924.     else if ((bi1.data[pos] & 0x80000000) == 0 && (bi2.data[pos] & 0x80000000) != 0)  
  925.         return false;  
  926.   
  927.     // same sign  
  928.     int len = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength;  
  929.     for (pos = len - 1; pos >= 0 && bi1.data[pos] == bi2.data[pos]; pos–) ;  
  930.   
  931.     if (pos >= 0)  
  932.     {  
  933.         if (bi1.data[pos] < bi2.data[pos])  
  934.             return true;  
  935.         return false;  
  936.     }  
  937.     return false;  
  938. }  
  939.   
  940. BigInteger BigInteger::operator +=(BigInteger bi2)  
  941. {  
  942.     *this = *this + bi2;  
  943.     return *this;  
  944. }  
  945.   
  946. BigInteger BigInteger::operator /(BigInteger bi2)  
  947. {  
  948.     BigInteger bi1(*this);  
  949.     BigInteger quotient;  
  950.     BigInteger remainder;  
  951.   
  952.     int lastPos = maxLength - 1;  
  953.     bool divisorNeg = false, dividendNeg = false;  
  954.   
  955.     if ((bi1.data[lastPos] & 0x80000000) != 0)     // bi1 negative  
  956.     {  
  957.         bi1 = -bi1;  
  958.         dividendNeg = true;  
  959.     }  
  960.     if ((bi2.data[lastPos] & 0x80000000) != 0)     // bi2 negative  
  961.     {  
  962.         bi2 = -bi2;  
  963.         divisorNeg = true;  
  964.     }  
  965.   
  966.     if (bi1 < bi2)  
  967.     {  
  968.         return quotient;  
  969.     }  
  970.   
  971.     else  
  972.     {  
  973.         if (bi2.dataLength == 1)  
  974.             singleByteDivide(bi1, bi2, quotient, remainder);  
  975.         else  
  976.             multiByteDivide(bi1, bi2, quotient, remainder);  
  977.   
  978.         if (dividendNeg != divisorNeg)  
  979.             return -quotient;  
  980.   
  981.         return quotient;  
  982.     }  
  983. }  
  984.   
  985. BigInteger BigInteger::operator -=(BigInteger bi2)  
  986. {  
  987.     *this = *this - bi2;  
  988.     return *this;  
  989. }  
  990.   
  991. BigInteger BigInteger::operator -(BigInteger bi2)   //减法的重载  
  992. {  
  993.     BigInteger bi1(*this);  
  994.     BigInteger result;  
  995.     int lastPos = maxLength - 1;  
  996.     bool bi1Neg = false, bi2Neg = false;  
  997.   
  998.     if ((this->data[lastPos] & 0x80000000) != 0)     // bi1 negative  
  999.         bi1Neg = true;   
  1000.     if ((bi2.data[lastPos] & 0x80000000) != 0)     // bi1 negative  
  1001.         bi2Neg = true;  
  1002.   
  1003.     if(bi1Neg == false && bi2Neg == false)   //bi1,bi2都为正数  
  1004.     {  
  1005.         if(bi1 < bi2)  
  1006.         {  
  1007.          result = -(bi2 - bi1);  
  1008.          return result;  
  1009.         }  
  1010.         result.dataLength = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength;  
  1011.   
  1012.         __int64 carryIn = 0;  
  1013.         for (int i = 0; i < result.dataLength; i++)   //从低位开始减  
  1014.         {  
  1015.             __int64 diff;  
  1016.   
  1017.             diff = (__int64)bi1.data[i] - (__int64)bi2.data[i] - carryIn;  
  1018.             result.data[i] = (unsigned int)(diff & 0xFFFFFFFF);  
  1019.   
  1020.             if (diff < 0)  
  1021.                 carryIn = 1;  
  1022.             else  
  1023.                 carryIn = 0;  
  1024.         }  
  1025.   
  1026.         if (carryIn != 0)  
  1027.         {  
  1028.             for (int i = result.dataLength; i < maxLength; i++)  
  1029.                 result.data[i] = 0xFFFFFFFF;  
  1030.             result.dataLength = maxLength;  
  1031.         }  
  1032.   
  1033.         // fixed in v1.03 to give correct datalength for a - (-b)  
  1034.         while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0)  
  1035.             result.dataLength–;  
  1036.   
  1037.         // overflow check  
  1038.   
  1039.         if ((bi1.data[lastPos] & 0x80000000) != (bi2.data[lastPos] & 0x80000000) &&  
  1040.             (result.data[lastPos] & 0x80000000) != (bi1.data[lastPos] & 0x80000000))  
  1041.         {  
  1042.             assert(false);  
  1043.         }  
  1044.   
  1045.         return result;  
  1046.     }  
  1047.   
  1048.     if(bi1Neg == true && bi2Neg == false)    //bi1负,bi2正  
  1049.     {  
  1050.         result = -(-bi1 + bi2);  
  1051.         return result;  
  1052.     }  
  1053.   
  1054.     if(bi1Neg == false && bi2Neg == true)   //bi1正,bi2负  
  1055.     {  
  1056.         result = bi1 + (-bi2);  
  1057.         return result;  
  1058.     }  
  1059.   
  1060.     if(bi1Neg == true && bi2Neg == true)   //bi1,bi2皆为负  
  1061.     {  
  1062.         BigInteger bi3 = -bi1, bi4 = -bi2;  
  1063.         if(bi3 > bi4)  
  1064.         {  
  1065.          result = -(bi3 - bi4);  
  1066.          return result;  
  1067.         }  
  1068.         else  
  1069.         {  
  1070.             result = bi4 - bi3;  
  1071.             return result;  
  1072.         }  
  1073.     }  
  1074. }  
  1075.   
  1076. string BigInteger::DecToHex(unsigned int value, string format)   //10进制数转换成16进制数,并用string表示  
  1077. {  
  1078.     string HexStr;  
  1079.     int a[100];   
  1080.     int i = 0;   
  1081.     int m = 0;  
  1082.     int mod = 0;   
  1083.     char hex[16]={‘0’,‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’,‘A’,‘B’,‘C’,‘D’,‘E’,‘F’};  
  1084.     while(value > 0)   
  1085.     {   
  1086.         mod = value % 16;   
  1087.         a[i++] = mod;   
  1088.         value = value/16;   
  1089.   
  1090.     }   
  1091.   
  1092.     for(i = i - 1; i >= 0; i–)  
  1093.     {   
  1094.         m=a[i];  
  1095.         HexStr.push_back(hex[m]);  
  1096.     }   
  1097.   
  1098.     while (format == string(“X8”) && HexStr.size() < 8)  
  1099.     {  
  1100.         HexStr = ”0” + HexStr;  
  1101.     }  
  1102.   
  1103.     return HexStr;  
  1104. }  
  1105.   
  1106. string BigInteger::ToHexString()  //功能:将一个大数用16进制的string表示出来  
  1107. {  
  1108.     string result = DecToHex(data[dataLength - 1], string(”X”));  
  1109.   
  1110.     for (int i = dataLength - 2; i >= 0; i–)  
  1111.     {  
  1112.         result += DecToHex(data[i], string(”X8”));  
  1113.     }  
  1114.   
  1115.     return result;  
  1116. }  
  1117.   
  1118. ostream& operator<<(ostream& output, BigInteger &obj)//以16进制输出数值  
  1119. {  
  1120.      //if ((obj.data[obj.dataLength-1] & 0x80000000) != 0)     // bi1 negative  
  1121.     for(int i = obj.dataLength - 1; i >= 0; i–)  
  1122.         output << hex << obj.data[i];  
  1123.     return output;  
  1124. }  
  1125.   
  1126.   
  1127. bool Miller_Robin(BigInteger &bi1)   //Miller_Robin算法  
  1128. {  
  1129.     BigInteger one((__int64)1), two((__int64)2), sum, a, b, temp;  
  1130.     int k = 0, len = primeLength / 2;  
  1131.     temp = sum = bi1 - one;  
  1132.     while((sum.data[0] & 0x00000001) == 0)   //只要sum不为奇数,sum就一直往右移  
  1133.     {  
  1134.         sum.dataLength = sum.shiftRight(sum.data, maxLength, 1);   //右移一位  
  1135.         k++;  
  1136.     }  
  1137.     //sum即为要求的奇数,k即是要求的2的次数  
  1138.     srand((unsigned)time(0));  
  1139.     for(int i = 0; i < len; i++)  
  1140.     {  
  1141.         a.data[i] =(unsigned int)rand ();  
  1142.         if(a.data[i] != 0) a.dataLength = i + 1;  
  1143.     }  
  1144.   
  1145.     b = a.modPow(sum, bi1);  //b = a^m mod bi1  
  1146.     if (b == one) return true;     
  1147.   
  1148.     for(int i = 0; i < k; i++)  
  1149.     {  
  1150.         if(b == temp) return true;  
  1151.         else b = b.modPow(two, bi1);  //b = b^2 mod bi1  
  1152.     }  
  1153.     return false;  
  1154. }  
  1155.   
  1156. bool IsPrime (BigInteger &obj)  
  1157. {  
  1158.     BigInteger zero;  
  1159.     for(int i = 0; i < 303; i++)   //先用一些素数对这个整数进行筛选  
  1160.     {  
  1161.         BigInteger prime((__int64)primesBelow2000[i]);  
  1162.         if(obj % prime == zero)  
  1163.             return false;  
  1164.     }  
  1165.     cout << ”第一轮素性检验通过… … … …” << endl;  
  1166.     cout << ”正在进行Miller_Robin素性检验… … … …” << endl;  
  1167.     if(Miller_Robin(obj))   //进行1次Miller_Robin检验  
  1168.         return true;  //通过了就返回result        
  1169.     return false;//表明result是合数,没有通过检验  
  1170. }  
  1171.   
  1172. BigInteger GetPrime()  
  1173. {  
  1174.     BigInteger one((__int64)1), two((__int64)2), result;  
  1175.     srand((unsigned)time(0));  
  1176.   
  1177.     //随机产生一个大整数  
  1178.     for(int i = 0; i < primeLength; i++)  
  1179.     {  
  1180.         result.data[i] =(unsigned int)rand();  
  1181.         if(result.data[i] != 0)  
  1182.         result.dataLength = i + 1;  
  1183.     }  
  1184.   
  1185.     result.data[0] |= 0x00000001;   //保证这个整数为奇数  
  1186.     while(!IsPrime(result))   //如果没有通过检验,就+2,继续检验  
  1187.     {  
  1188.      result = result + two;  
  1189.   
  1190.      cout << ”检验没有通过,进行下一个数的检验,运行之中… … … …” << endl;  
  1191.      cout << endl;  
  1192.     }  
  1193.     return result;  
  1194.       
  1195. }  
  1196.   
  1197.   
  1198.   
  1199.   
  1200. BigInteger extended_euclidean(BigInteger n, BigInteger m, BigInteger &x, BigInteger &y)   //扩展的欧几里德算法    
  1201. {    
  1202.     BigInteger x1((__int64)1), x2, x3(n);    
  1203.     BigInteger y1, y2((__int64)1), y3(m);   
  1204.     BigInteger zero;  
  1205.     while(x3 % y3 != zero)    
  1206.     {    
  1207.         BigInteger d = x3 / y3;    
  1208.         BigInteger t1, t2, t3;    
  1209.         t1 = x1 - d * y1;    
  1210.         t2 = x2 - d * y2;    
  1211.         t3 = x3 - d * y3;    
  1212.         x1 = y1; x2 = y2; x3 = y3;    
  1213.         y1 = t1; y2 = t2; y3 = t3;    
  1214.     }    
  1215.     x = y1; y = y2;    
  1216.     return y3;    
  1217. }   
  1218.   
  1219. /* 
  1220. BigInteger extended_euclidean(BigInteger n,BigInteger m,BigInteger &x,BigInteger &y)   
  1221. {   
  1222.     BigInteger zero, one((__int64)1); 
  1223.     if(m == zero) { x = one; y = zero; return n; }   
  1224.     BigInteger g = extended_euclidean(m, n%m, x, y);   
  1225.     BigInteger t = x - n / m * y;   
  1226.     x = y;   
  1227.     y = t;   
  1228.     return g;   
  1229. }   
  1230. */  
  1231.   
  1232. BigInteger Gcd(BigInteger &bi1, BigInteger &bi2)  
  1233. {  
  1234.     BigInteger x, y;  
  1235.     BigInteger g = extended_euclidean(bi1, bi2, x, y);  
  1236.     return g;  
  1237. }  
  1238.   
  1239. BigInteger MultipInverse(BigInteger &bi1, BigInteger &n)   //求乘法逆元  
  1240. {  
  1241.    BigInteger x, y;  
  1242.    extended_euclidean(bi1, n, x, y);  
  1243.    if ((x.data[maxLength-1] & 0x80000000) != 0)     // x negative  
  1244.        x = x + n;  
  1245.   // unsigned int i =  x.data[maxLength-1] & 0x80000000;  
  1246.   // cout << i << endl;  
  1247.    return x;  
  1248. }  
#include "BigInteger.h"BigInteger::BigInteger(void)   //默认的构造函数: dataLength(0), data(0){    data = new unsigned int[maxLength];    memset(data, 0, maxLength * sizeof(unsigned int));    dataLength = 1;}BigInteger::BigInteger(__int64 value)   //用一个64位的值来初始化大数{    data = new unsigned int[maxLength];    memset(data, 0, maxLength * sizeof(unsigned int));   //先清零    __int64 tempVal = value;    dataLength = 0;    while (value != 0 && dataLength < maxLength)    {        data[dataLength] = (unsigned int)(value & 0xFFFFFFFF);   //取低位        value = value >> 32;   //进位        dataLength++;    }    if (tempVal > 0)         // overflow check for +ve value    {        if (value != 0 || (data[maxLength - 1] & 0x80000000) != 0)            assert(false);    }    else if (tempVal < 0)    // underflow check for -ve value    {        if (value != -1 || (data[dataLength - 1] & 0x80000000) == 0)            assert(false);    }    if (dataLength == 0)        dataLength = 1;}BigInteger::BigInteger(unsigned __int64 value)   //用一个无符号的64位整数来初始化大数{    data = new unsigned int[maxLength];    memset(data, 0, maxLength * sizeof(unsigned int));    dataLength = 0;    while (value != 0 && dataLength < maxLength)    {        data[dataLength] = (unsigned int)(value & 0xFFFFFFFF);        value >>= 32;        dataLength++;    }    if (value != 0 || (data[maxLength - 1] & 0x80000000) != 0)        assert(false);    if (dataLength == 0)   //防止输入的value=0        dataLength = 1;}BigInteger::BigInteger(const BigInteger &bi)   //用大数初始化大数{    data = new unsigned int[maxLength];    dataLength = bi.dataLength;    for (int i = 0; i < maxLength; i++)   //考虑到有负数的情况,所以每一位都要复制        data[i] = bi.data[i];}BigInteger::~BigInteger(void){    if (data != NULL)    {        delete []data;    }}BigInteger::BigInteger(string value, int radix)   //输入转换函数,将字符串转换成对应进制的大数{   //一般不处理负数    BigInteger multiplier((__int64)1);    BigInteger result;    transform(value.begin(), value.end(), value.begin(), toupper);   //将小写字母转换成为大写    int limit = 0;    if (value[0] == '-')           limit = 1;    for (int i = value.size() - 1; i >= limit; i--)    {        int posVal = (int)value[i];        if (posVal >= '0' && posVal <= '9')  //将字符转换成数字            posVal -= '0';        else if (posVal >= 'A' && posVal <= 'Z')            posVal = (posVal - 'A') + 10;        else            posVal = 9999999;       // arbitrary large 输入别的字符        if (posVal >= radix)   //不能大于特定的进制,否则终止        {            assert(false);        }        else        {            result = result + (multiplier * BigInteger((__int64)posVal));            if ((i - 1) >= limit)   //没有到达尾部                multiplier = multiplier * BigInteger((__int64)radix);        }    }    if (value[0] == '-')   //符号最后再处理       result = -result;    if (value[0] == '-')     //输入为负数,但得到的结果为正数,可能溢出了    {        if ((result.data[maxLength - 1] & 0x80000000) == 0)               assert(false);    }    else    //或者说,输入为正数,得到的结果为负数,也可能溢出了    {        if ((result.data[maxLength - 1] & 0x80000000) != 0)              assert(false);    }    data = new unsigned int[maxLength];    //memset(data, 0, maxLength * sizeof(unsigned int));    for (int i = 0; i < maxLength; i++)        data[i] = result.data[i];    dataLength = result.dataLength;}BigInteger::BigInteger(byte inData[], int inLen)   //用一个char类型的数组来初始化大数{    dataLength = inLen >> 2;   //一个unsigned int占32位,而一个unsigned char只占8位    //因此dataLength应该是至少是inLen/4,不一定整除    int leftOver = inLen & 0x3;      //取最低两位的数值,为什么要这样干呢?实际上是为了探测len是不是4的倍数,好确定dataLength的长度    if (leftOver != 0)    //不能整除的话,dataLength要加1        dataLength++;    if (dataLength > maxLength)        assert(false);    data = new unsigned int[maxLength];    memset(data, 0, maxLength * sizeof(unsigned int));    for (int i = inLen - 1, j = 0; i >= 3; i -= 4, j++)       {        data[j] = (unsigned int)((inData[i - 3] << 24) + (inData[i - 2] << 16) + (inData[i - 1] << 8) + inData[i]);//我们知道:一个unsigned int占32位,而一个unsigned char只占8位,因此四个unsigned char才能组成一个unsigned int//因此取inData[i - 3]为前32-25位,inData[i - 2]为前24-17~~~//i % 4 = 0 or 1 or 2 or 3 余0表示恰好表示完    }    if (leftOver == 1)        data[dataLength - 1] = (unsigned int)inData[0];    else if (leftOver == 2)        data[dataLength - 1] = (unsigned int)((inData[0] << 8) + inData[1]);    else if (leftOver == 3)        data[dataLength - 1] = (unsigned int)((inData[0] << 16) + (inData[1] << 8) + inData[2]);    while (dataLength > 1 && data[dataLength - 1] == 0)        dataLength--;}BigInteger::BigInteger(unsigned int inData[], int inLen)   //用一个unsigned int型数组初始化大数{    dataLength = inLen;    if (dataLength > maxLength)        assert(false);    data = new unsigned int[maxLength];    memset(data, 0, maxLength * sizeof(maxLength));    for (int i = dataLength - 1, j = 0; i >= 0; i--, j++)        data[j] = inData[i];    while (dataLength > 1 && data[dataLength - 1] == 0)        dataLength--;}BigInteger BigInteger::operator *(BigInteger bi2)   //乘法的重载{    BigInteger bi1(*this);    int lastPos = maxLength - 1;    bool bi1Neg = false, bi2Neg = false;    //首先对两个乘数取绝对值    try    {        if ((this->data[lastPos] & 0x80000000) != 0)     //bi1为负数        {            bi1Neg = true;             bi1 = -bi1;        }        if ((bi2.data[lastPos] & 0x80000000) != 0)     //bi2为负数        {            bi2Neg = true; bi2 = -bi2;        }    }    catch (...) { }    BigInteger result;    //绝对值相乘    try    {        for (int i = 0; i < bi1.dataLength; i++)        {            if (bi1.data[i] == 0) continue;            unsigned __int64 mcarry = 0;            for (int j = 0, k = i; j < bi2.dataLength; j++, k++)            {                // k = i + j                unsigned __int64 val = ((unsigned __int64)bi1.data[i] * (unsigned __int64)bi2.data[j]) + (unsigned __int64)result.data[k] + mcarry;                result.data[k] = (unsigned __int64)(val & 0xFFFFFFFF);   //取低位                mcarry = (val >> 32);   //进位            }            if (mcarry != 0)            result.data[i + bi2.dataLength] = (unsigned int)mcarry;        }    }    catch (...)    {        assert(false);    }    result.dataLength = bi1.dataLength + bi2.dataLength;    if (result.dataLength > maxLength)        result.dataLength = maxLength;    while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0)        result.dataLength--;    // overflow check (result is -ve)溢出检查    if ((result.data[lastPos] & 0x80000000) != 0)  //结果为负数    {        if (bi1Neg != bi2Neg && result.data[lastPos] == 0x80000000)    //两乘数符号不同        {            // handle the special case where multiplication produces            // a max negative number in 2's complement.            if (result.dataLength == 1)                return result;            else            {                bool isMaxNeg = true;                for (int i = 0; i < result.dataLength - 1 && isMaxNeg; i++)                {                    if (result.data[i] != 0)                        isMaxNeg = false;                }                if (isMaxNeg)                    return result;            }        }        assert(false);    }    //两乘数符号不同,结果为负数    if (bi1Neg != bi2Neg)        return -result;    return result;}BigInteger BigInteger::operator =(const BigInteger &bi2){    if (&bi2 == this)    {        return *this;    }    if (data != NULL)    {        delete []data;        data = NULL;    }    data = new unsigned int[maxLength];    memset(data, 0, maxLength * sizeof(unsigned int));    dataLength = bi2.dataLength;    for (int i = 0; i < maxLength; i++)        data[i] = bi2.data[i];    return *this;}BigInteger BigInteger::operator +(BigInteger &bi2){    int lastPos = maxLength - 1;    bool bi1Neg = false, bi2Neg = false;    BigInteger bi1(*this);    BigInteger result;    if ((this->data[lastPos] & 0x80000000) != 0)     //bi1为负数          bi1Neg = true;     if ((bi2.data[lastPos] & 0x80000000) != 0)     //bi2为负数            bi2Neg = true;     if(bi1Neg == false && bi2Neg == false)   //bi1与bi2都是正数    {        result.dataLength = (this->dataLength > bi2.dataLength) ? this->dataLength : bi2.dataLength;        __int64 carry = 0;        for (int i = 0; i < result.dataLength; i++)   //从低位开始,逐位相加        {            __int64 sum = (__int64)this->data[i] + (__int64)bi2.data[i] + carry;            carry = sum >> 32;   //进位            result.data[i] = (unsigned int)(sum & 0xFFFFFFFF);  //取低位结果        }        if (carry != 0 && result.dataLength < maxLength)        {            result.data[result.dataLength] = (unsigned int)(carry);            result.dataLength++;        }        while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0)            result.dataLength--;        //溢出检查        if ((this->data[lastPos] & 0x80000000) == (bi2.data[lastPos] & 0x80000000) &&            (result.data[lastPos] & 0x80000000) != (this->data[lastPos] & 0x80000000))        {            assert(false);        }        return result;    }    //关键在于,负数全部要转化成为正数来做    if(bi1Neg == false && bi2Neg == true)   //bi1正,bi2负    {        BigInteger bi3 = -bi2;        if(bi1 > bi3)        {         result = bi1 - bi3;          return result;        }        else        {         result = -(bi3 - bi1);         return result;        }    }    if(bi1Neg == true && bi2Neg == false)  //bi1负,bi2正    {        BigInteger bi3 = -bi1;        if(bi3 > bi2)        {         result = -(bi3 - bi2);         return result;        }        else        {         result = bi2 - bi3;         return result;        }    }    if(bi1Neg == true && bi2Neg == true)  //bi1负,bi2负    {        result = - ((-bi1) + (-bi2));        return result;    }}BigInteger BigInteger::operator -(){    //逐位取反并+1    if (this->dataLength == 1 && this->data[0] == 0)        return *this;    BigInteger result(*this);    for (int i = 0; i < maxLength; i++)        result.data[i] = (unsigned int)(~(this->data[i]));   //取反    __int64 val, carry = 1;    int index = 0;    while (carry != 0 && index < maxLength)  //+1;    {        val = (__int64)(result.data[index]);        val++;   //由于值加了1个1,往前面的进位最多也只是1个1,因此val++就完了        result.data[index] = (unsigned int)(val & 0xFFFFFFFF);   //取低位部分        carry = val >> 32;   //进位        index++;    }    if ((this->data[maxLength - 1] & 0x80000000) == (result.data[maxLength - 1] & 0x80000000))        result.dataLength = maxLength;    while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0)        result.dataLength--;    return result;}BigInteger BigInteger::modPow(BigInteger exp, BigInteger n)   //求this^exp mod n{    if ((exp.data[maxLength - 1] & 0x80000000) != 0)   //指数是负数    return BigInteger((__int64)0);    BigInteger resultNum((__int64)1);    BigInteger tempNum;    bool thisNegative = false;    if ((this->data[maxLength - 1] & 0x80000000) != 0)   //底数是负数    {        tempNum = -(*this) % n;        thisNegative = true;    }    else        tempNum = (*this) % n;  //保证(tempNum * tempNum) < b^(2k)    if ((n.data[maxLength - 1] & 0x80000000) != 0)   //n为负        n = -n;    //计算 constant = b^(2k) / m    //constant主要用于后面的Baeert Reduction算法    BigInteger constant;    int i = n.dataLength << 1;    constant.data[i] = 0x00000001;    constant.dataLength = i + 1;    constant = constant / n;    int totalBits = exp.bitCount();    int count = 0;    //平方乘法算法    for (int pos = 0; pos < exp.dataLength; pos++)    {        unsigned int mask = 0x01;        for (int index = 0; index < 32; index++)        {            if ((exp.data[pos] & mask) != 0)  //某一个bit不为0            resultNum = BarrettReduction(resultNum * tempNum, n, constant);            //resultNum = resultNum * tempNum mod n            mask <<= 1; //不断左移            tempNum = BarrettReduction(tempNum * tempNum, n, constant);            //tempNum = tempNum * tempNum mod n            if (tempNum.dataLength == 1 && tempNum.data[0] == 1)            {                if (thisNegative && (exp.data[0] & 0x1) != 0)    //指数为奇数                    return -resultNum;                return resultNum;            }            count++;            if (count == totalBits)                break;        }    }    if (thisNegative && (exp.data[0] & 0x1) != 0)    //底数为负数,指数为奇数        return -resultNum;    return resultNum;}int BigInteger::bitCount()   //计算字节数{    while (dataLength > 1 && data[dataLength - 1] == 0)        dataLength--;    unsigned int value = data[dataLength - 1];    unsigned int mask = 0x80000000;    int bits = 32;    while (bits > 0 && (value & mask) == 0)   //计算最高位的bit    {        bits--;        mask >>= 1;    }    bits += ((dataLength - 1) << 5);   //余下的位都有32bit    //左移5位,相当于乘以32,即2^5    return bits;}BigInteger BigInteger::BarrettReduction(BigInteger x, BigInteger n, BigInteger constant){//算法,Baeert Reduction算法,在计算大规模的除法运算时很有优势//原理如下//Z mod N=Z-[Z/N]*N=Z-{[Z/b^(n-1)]*[b^2n/N]/b^(n+1)}*N=Z-q*N//q=[Z/b^(n-1)]*[b^2n/N]/b^(n+1)//其中,[]表示取整运算,A^B表示A的B次幂    int k = n.dataLength,        kPlusOne = k + 1,        kMinusOne = k - 1;    BigInteger q1;    // q1 = x / b^(k-1)    for (int i = kMinusOne, j = 0; i < x.dataLength; i++, j++)        q1.data[j] = x.data[i];    q1.dataLength = x.dataLength - kMinusOne;    if (q1.dataLength <= 0)        q1.dataLength = 1;    BigInteger q2 = q1 * constant;    BigInteger q3;    // q3 = q2 / b^(k+1)    for (int i = kPlusOne, j = 0; i < q2.dataLength; i++, j++)        q3.data[j] = q2.data[i];    q3.dataLength = q2.dataLength - kPlusOne;    if (q3.dataLength <= 0)        q3.dataLength = 1;    // r1 = x mod b^(k+1)    // i.e. keep the lowest (k+1) words    BigInteger r1;    int lengthToCopy = (x.dataLength > kPlusOne) ? kPlusOne : x.dataLength;    for (int i = 0; i < lengthToCopy; i++)        r1.data[i] = x.data[i];    r1.dataLength = lengthToCopy;    // r2 = (q3 * n) mod b^(k+1)    // partial multiplication of q3 and n    BigInteger r2;    for (int i = 0; i < q3.dataLength; i++)    {        if (q3.data[i] == 0) continue;        unsigned __int64 mcarry = 0;        int t = i;        for (int j = 0; j < n.dataLength && t < kPlusOne; j++, t++)        {            // t = i + j            unsigned __int64 val = ((unsigned __int64)q3.data[i] * (unsigned __int64)n.data[j]) +                (unsigned __int64)r2.data[t] + mcarry;            r2.data[t] = (unsigned int)(val & 0xFFFFFFFF);            mcarry = (val >> 32);        }        if (t < kPlusOne)            r2.data[t] = (unsigned int)mcarry;    }    r2.dataLength = kPlusOne;    while (r2.dataLength > 1 && r2.data[r2.dataLength - 1] == 0)        r2.dataLength--;    r1 -= r2;    if ((r1.data[maxLength - 1] & 0x80000000) != 0)        // negative    {        BigInteger val;        val.data[kPlusOne] = 0x00000001;        val.dataLength = kPlusOne + 1;        r1 += val;    }    while (r1 >= n)        r1 -= n;    return r1;}bool BigInteger::operator >(BigInteger bi2){    int pos = maxLength - 1;    BigInteger bi1(*this);    // bi1 is negative, bi2 is positive    if ((bi1.data[pos] & 0x80000000) != 0 && (bi2.data[pos] & 0x80000000) == 0)        return false;    // bi1 is positive, bi2 is negative    else if ((bi1.data[pos] & 0x80000000) == 0 && (bi2.data[pos] & 0x80000000) != 0)        return true;    // same sign    int len = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength;    for (pos = len - 1; pos >= 0 && bi1.data[pos] == bi2.data[pos]; pos--) ;    if (pos >= 0)    {        if (bi1.data[pos] > bi2.data[pos])            return true;        return false;    }    return false;}bool BigInteger::operator ==(BigInteger bi2){    if (this->dataLength != bi2.dataLength)        return false;    for (int i = 0; i < this->dataLength; i++)    {        if (this->data[i] != bi2.data[i])            return false;    }    return true;}bool BigInteger::operator !=(BigInteger bi2){    if(this->dataLength != bi2.dataLength)        return true;    for(int i = 0; i < this->dataLength; i++)    {        if(this->data[i] != bi2.data[i])            return true;    }    return false;}BigInteger BigInteger::operator %(BigInteger bi2){    BigInteger bi1(*this);    BigInteger quotient;    BigInteger remainder(bi1);    int lastPos = maxLength - 1;    bool dividendNeg = false;    if ((bi1.data[lastPos] & 0x80000000) != 0)     // bi1 negative    {        bi1 = -bi1;        dividendNeg = true;    }    if ((bi2.data[lastPos] & 0x80000000) != 0)     // bi2 negative        bi2 = -bi2;    if (bi1 < bi2)    {        return remainder;    }    else    {        if (bi2.dataLength == 1)            singleByteDivide(bi1, bi2, quotient, remainder);   //bi2只占一个位置时,用singleByteDivide更快        else            multiByteDivide(bi1, bi2, quotient, remainder);   //bi2占多个位置时,用multiByteDivide更快        if (dividendNeg)            return -remainder;        return remainder;    }}void BigInteger::singleByteDivide(BigInteger &bi1, BigInteger &bi2,                      BigInteger &outQuotient, BigInteger &outRemainder){//outQuotient商,outRemainder余数    unsigned int result[maxLength];   //用来存储结果    memset(result, 0, sizeof(unsigned int) * maxLength);    int resultPos = 0;    for (int i = 0; i < maxLength; i++)   //将bi1复制至outRemainder        outRemainder.data[i] = bi1.data[i];    outRemainder.dataLength = bi1.dataLength;    while (outRemainder.dataLength > 1 && outRemainder.data[outRemainder.dataLength - 1] == 0)        outRemainder.dataLength--;    unsigned __int64 divisor = (unsigned __int64)bi2.data[0];    int pos = outRemainder.dataLength - 1;    unsigned __int64 dividend = (unsigned __int64)outRemainder.data[pos];   //取最高位的数值    if (dividend >= divisor)   //被除数>除数    {        unsigned __int64 quotient = dividend / divisor;        result[resultPos++] = (unsigned __int64)quotient;   //结果        outRemainder.data[pos] = (unsigned __int64)(dividend % divisor);   //余数    }    pos--;    while (pos >= 0)    {        dividend = ((unsigned __int64)outRemainder.data[pos + 1] << 32) + (unsigned __int64)outRemainder.data[pos];   //前一位的余数和这一位的值相加        unsigned __int64 quotient = dividend / divisor;   //得到结果        result[resultPos++] = (unsigned int)quotient;   //结果取低位        outRemainder.data[pos + 1] = 0;   //前一位的余数清零        outRemainder.data[pos--] = (unsigned int)(dividend % divisor);   //得到这一位的余数    }    outQuotient.dataLength = resultPos;   //商的长度是resultPos的长度    int j = 0;    for (int i = outQuotient.dataLength - 1; i >= 0; i--, j++)  //将商反转过来         outQuotient.data[j] = result[i];    for (; j < maxLength; j++)   //商的其余位都要置0        outQuotient.data[j] = 0;    while (outQuotient.dataLength > 1 && outQuotient.data[outQuotient.dataLength - 1] == 0)        outQuotient.dataLength--;    if (outQuotient.dataLength == 0)        outQuotient.dataLength = 1;    while (outRemainder.dataLength > 1 && outRemainder.data[outRemainder.dataLength - 1] == 0)        outRemainder.dataLength--;}void BigInteger::multiByteDivide(BigInteger &bi1, BigInteger &bi2,                     BigInteger &outQuotient, BigInteger &outRemainder){    unsigned int result[maxLength];    memset(result, 0, sizeof(unsigned int) * maxLength);   //结果置零     int remainderLen = bi1.dataLength + 1;   //余数长度    unsigned int *remainder = new unsigned int[remainderLen];    memset(remainder, 0, sizeof(unsigned int) * remainderLen);   //余数置零    unsigned int mask = 0x80000000;    unsigned int val = bi2.data[bi2.dataLength - 1];    int shift = 0, resultPos = 0;    while (mask != 0 && (val & mask) == 0)    {        shift++; mask >>= 1;    }       //最高位从高到低找出shift个0位    for (int i = 0; i < bi1.dataLength; i++)        remainder[i] = bi1.data[i];   //将bi1复制到remainder之中    this->shiftLeft(remainder, remainderLen, shift);   //remainder左移shift位    bi2 = bi2 << shift;   //向左移shift位,将空位填满    //由于两个数都扩大了相同的倍数,所以结果不变    int j = remainderLen - bi2.dataLength;   //j表示两个数长度的差值,也是要计算的次数    int pos = remainderLen - 1;   //pos指示余数的最高位的位置,现在pos=bi1.dataLength    //以下的步骤并没有别的意思,主要是用来试商    unsigned __int64 firstDivisorByte = bi2.data[bi2.dataLength - 1];   //第一个除数    unsigned __int64 secondDivisorByte = bi2.data[bi2.dataLength - 2];  //第二个除数     int divisorLen = bi2.dataLength + 1;   //除数的长度    unsigned int *dividendPart = new unsigned int[divisorLen];   //起名为除数的部分    memset(dividendPart, 0, sizeof(unsigned int) * divisorLen);    while (j > 0)    {        unsigned __int64 dividend = ((unsigned __int64)remainder[pos] << 32) + (unsigned __int64)remainder[pos - 1];   //取余数的高两位        unsigned __int64 q_hat = dividend / firstDivisorByte;   //得到一个商        unsigned __int64 r_hat = dividend % firstDivisorByte;   //以及一个余数        bool done = false;   //表示没有做完        while (!done)        {            done = true;            if (q_hat == 0x100000000 || (q_hat * secondDivisorByte) > ((r_hat << 32) + remainder[pos - 2]))   //这里主要用来调整商的大小             //(q_hat * secondDivisorByte) > ((r_hat << 32) + remainder[pos - 2]))是害怕上的商过大,减之后变为负数            //商q_hat也不能超过32bit            {                q_hat--;   //否则的话,就商小一点,余数大一点                r_hat += firstDivisorByte;                if (r_hat < 0x100000000)   //如果余数小于32bit,就继续循环                    done = false;            }        }        for (int h = 0; h < divisorLen; h++)   //取被除数的高位部分,高位部分长度与除数长度一致            dividendPart[h] = remainder[pos - h];        BigInteger kk(dividendPart, divisorLen);        BigInteger ss = bi2 * BigInteger((__int64)q_hat);        while (ss > kk)   //调节商的大小        {            q_hat--;            ss -= bi2;        }        BigInteger yy = kk - ss;   //得到余数        for (int h = 0; h < divisorLen; h++)  //将yy高位和remainder低位拼接起来,得到余数            remainder[pos - h] = yy.data[bi2.dataLength - h];   //取得真正的余数        result[resultPos++] = (unsigned int)q_hat;        pos--;        j--;    }    outQuotient.dataLength = resultPos;    int y = 0;    for (int x = outQuotient.dataLength - 1; x >= 0; x--, y++)   //将商反转过来        outQuotient.data[y] = result[x];    for (; y < maxLength; y++)   //商的其余位都要置0        outQuotient.data[y] = 0;    while (outQuotient.dataLength > 1 && outQuotient.data[outQuotient.dataLength - 1] == 0)        outQuotient.dataLength--;    if (outQuotient.dataLength == 0)        outQuotient.dataLength = 1;    outRemainder.dataLength = this->shiftRight(remainder, remainderLen, shift);    for (y = 0; y < outRemainder.dataLength; y++)        outRemainder.data[y] = remainder[y];    for (; y < maxLength; y++)        outRemainder.data[y] = 0;    delete []remainder;    delete []dividendPart;}int BigInteger::shiftRight(unsigned int buffer[], int bufferLen,int shiftVal)   //右移操作{//自己用图画模拟一下移位操作,就能很快明白意义了    int shiftAmount = 32;    int invShift = 0;    int bufLen = bufferLen;    while (bufLen > 1 && buffer[bufLen - 1] == 0)        bufLen--;    for (int count = shiftVal; count > 0; )    {        if (count < shiftAmount)        {            shiftAmount = count;            invShift = 32 - shiftAmount;        }        unsigned __int64 carry = 0;        for (int i = bufLen - 1; i >= 0; i--)        {            unsigned __int64 val = ((unsigned __int64)buffer[i]) >> shiftAmount;            val |= carry;            carry = ((unsigned __int64)buffer[i]) << invShift;            buffer[i] = (unsigned int)(val);        }        count -= shiftAmount;    }    while (bufLen > 1 && buffer[bufLen - 1] == 0)        bufLen--;    return bufLen;}BigInteger BigInteger::operator <<(int shiftVal){    BigInteger result(*this);    result.dataLength = shiftLeft(result.data, maxLength, shiftVal);    return result;}int BigInteger::shiftLeft(unsigned int buffer[], int bufferLen, int shiftVal){    int shiftAmount = 32;    int bufLen = bufferLen;    while (bufLen > 1 && buffer[bufLen - 1] == 0)        bufLen--;    for (int count = shiftVal; count > 0; )    {        if (count < shiftAmount)            shiftAmount = count;        unsigned __int64 carry = 0;        for (int i = 0; i < bufLen; i++)        {            unsigned __int64 val = ((unsigned __int64)buffer[i]) << shiftAmount;            val |= carry;            buffer[i] = (unsigned int)(val & 0xFFFFFFFF);            carry = val >> 32;        }        if (carry != 0)        {            if (bufLen + 1 <= bufferLen)            {                buffer[bufLen] = (unsigned int)carry;                bufLen++;            }        }        count -= shiftAmount;    }    return bufLen;}bool BigInteger::operator <(BigInteger bi2){    BigInteger bi1(*this);    int pos = maxLength - 1;    // bi1 is negative, bi2 is positive    if ((bi1.data[pos] & 0x80000000) != 0 && (bi2.data[pos] & 0x80000000) == 0)        return true;    // bi1 is positive, bi2 is negative    else if ((bi1.data[pos] & 0x80000000) == 0 && (bi2.data[pos] & 0x80000000) != 0)        return false;    // same sign    int len = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength;    for (pos = len - 1; pos >= 0 && bi1.data[pos] == bi2.data[pos]; pos--) ;    if (pos >= 0)    {        if (bi1.data[pos] < bi2.data[pos])            return true;        return false;    }    return false;}BigInteger BigInteger::operator +=(BigInteger bi2){    *this = *this + bi2;    return *this;}BigInteger BigInteger::operator /(BigInteger bi2){    BigInteger bi1(*this);    BigInteger quotient;    BigInteger remainder;    int lastPos = maxLength - 1;    bool divisorNeg = false, dividendNeg = false;    if ((bi1.data[lastPos] & 0x80000000) != 0)     // bi1 negative    {        bi1 = -bi1;        dividendNeg = true;    }    if ((bi2.data[lastPos] & 0x80000000) != 0)     // bi2 negative    {        bi2 = -bi2;        divisorNeg = true;    }    if (bi1 < bi2)    {        return quotient;    }    else    {        if (bi2.dataLength == 1)            singleByteDivide(bi1, bi2, quotient, remainder);        else            multiByteDivide(bi1, bi2, quotient, remainder);        if (dividendNeg != divisorNeg)            return -quotient;        return quotient;    }}BigInteger BigInteger::operator -=(BigInteger bi2){    *this = *this - bi2;    return *this;}BigInteger BigInteger::operator -(BigInteger bi2)   //减法的重载{    BigInteger bi1(*this);    BigInteger result;    int lastPos = maxLength - 1;    bool bi1Neg = false, bi2Neg = false;    if ((this->data[lastPos] & 0x80000000) != 0)     // bi1 negative        bi1Neg = true;     if ((bi2.data[lastPos] & 0x80000000) != 0)     // bi1 negative        bi2Neg = true;    if(bi1Neg == false && bi2Neg == false)   //bi1,bi2都为正数    {        if(bi1 < bi2)        {         result = -(bi2 - bi1);         return result;        }        result.dataLength = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength;        __int64 carryIn = 0;        for (int i = 0; i < result.dataLength; i++)   //从低位开始减        {            __int64 diff;            diff = (__int64)bi1.data[i] - (__int64)bi2.data[i] - carryIn;            result.data[i] = (unsigned int)(diff & 0xFFFFFFFF);            if (diff < 0)                carryIn = 1;            else                carryIn = 0;        }        if (carryIn != 0)        {            for (int i = result.dataLength; i < maxLength; i++)                result.data[i] = 0xFFFFFFFF;            result.dataLength = maxLength;        }        // fixed in v1.03 to give correct datalength for a - (-b)        while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0)            result.dataLength--;        // overflow check        if ((bi1.data[lastPos] & 0x80000000) != (bi2.data[lastPos] & 0x80000000) &&            (result.data[lastPos] & 0x80000000) != (bi1.data[lastPos] & 0x80000000))        {            assert(false);        }        return result;    }    if(bi1Neg == true && bi2Neg == false)    //bi1负,bi2正    {        result = -(-bi1 + bi2);        return result;    }    if(bi1Neg == false && bi2Neg == true)   //bi1正,bi2负    {        result = bi1 + (-bi2);        return result;    }    if(bi1Neg == true && bi2Neg == true)   //bi1,bi2皆为负    {        BigInteger bi3 = -bi1, bi4 = -bi2;        if(bi3 > bi4)        {         result = -(bi3 - bi4);         return result;        }        else        {            result = bi4 - bi3;            return result;        }    }}string BigInteger::DecToHex(unsigned int value, string format)   //10进制数转换成16进制数,并用string表示{    string HexStr;    int a[100];     int i = 0;     int m = 0;    int mod = 0;     char hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};    while(value > 0)     {         mod = value % 16;         a[i++] = mod;         value = value/16;     }     for(i = i - 1; i >= 0; i--)    {         m=a[i];        HexStr.push_back(hex[m]);    }     while (format == string("X8") && HexStr.size() < 8)    {        HexStr = "0" + HexStr;    }    return HexStr;}string BigInteger::ToHexString()  //功能:将一个大数用16进制的string表示出来{    string result = DecToHex(data[dataLength - 1], string("X"));    for (int i = dataLength - 2; i >= 0; i--)    {        result += DecToHex(data[i], string("X8"));    }    return result;}ostream& operator<<(ostream& output, BigInteger &obj)//以16进制输出数值{     //if ((obj.data[obj.dataLength-1] & 0x80000000) != 0)     // bi1 negative    for(int i = obj.dataLength - 1; i >= 0; i--)        output << hex << obj.data[i];    return output;}bool Miller_Robin(BigInteger &bi1)   //Miller_Robin算法{    BigInteger one((__int64)1), two((__int64)2), sum, a, b, temp;    int k = 0, len = primeLength / 2;    temp = sum = bi1 - one;    while((sum.data[0] & 0x00000001) == 0)   //只要sum不为奇数,sum就一直往右移    {        sum.dataLength = sum.shiftRight(sum.data, maxLength, 1);   //右移一位        k++;    }    //sum即为要求的奇数,k即是要求的2的次数    srand((unsigned)time(0));    for(int i = 0; i < len; i++)    {        a.data[i] =(unsigned int)rand ();        if(a.data[i] != 0) a.dataLength = i + 1;    }    b = a.modPow(sum, bi1);  //b = a^m mod bi1    if (b == one) return true;       for(int i = 0; i < k; i++)    {        if(b == temp) return true;        else b = b.modPow(two, bi1);  //b = b^2 mod bi1    }    return false;}bool IsPrime (BigInteger &obj){    BigInteger zero;    for(int i = 0; i < 303; i++)   //先用一些素数对这个整数进行筛选    {        BigInteger prime((__int64)primesBelow2000[i]);        if(obj % prime == zero)            return false;    }    cout << "第一轮素性检验通过… … … …" << endl;    cout << "正在进行Miller_Robin素性检验… … … …" << endl;    if(Miller_Robin(obj))   //进行1次Miller_Robin检验        return true;  //通过了就返回result          return false;//表明result是合数,没有通过检验}BigInteger GetPrime(){    BigInteger one((__int64)1), two((__int64)2), result;    srand((unsigned)time(0));    //随机产生一个大整数    for(int i = 0; i < primeLength; i++)    {        result.data[i] =(unsigned int)rand();        if(result.data[i] != 0)        result.dataLength = i + 1;    }    result.data[0] |= 0x00000001;   //保证这个整数为奇数    while(!IsPrime(result))   //如果没有通过检验,就+2,继续检验    {     result = result + two;     cout << "检验没有通过,进行下一个数的检验,运行之中… … … …" << endl;     cout << endl;    }    return result;}BigInteger extended_euclidean(BigInteger n, BigInteger m, BigInteger &x, BigInteger &y)   //扩展的欧几里德算法  {      BigInteger x1((__int64)1), x2, x3(n);      BigInteger y1, y2((__int64)1), y3(m);     BigInteger zero;    while(x3 % y3 != zero)      {          BigInteger d = x3 / y3;          BigInteger t1, t2, t3;          t1 = x1 - d * y1;          t2 = x2 - d * y2;          t3 = x3 - d * y3;          x1 = y1; x2 = y2; x3 = y3;          y1 = t1; y2 = t2; y3 = t3;      }      x = y1; y = y2;      return y3;  } /*BigInteger extended_euclidean(BigInteger n,BigInteger m,BigInteger &x,BigInteger &y)  {      BigInteger zero, one((__int64)1);    if(m == zero) { x = one; y = zero; return n; }      BigInteger g = extended_euclidean(m, n%m, x, y);      BigInteger t = x - n / m * y;      x = y;      y = t;      return g;  }  */BigInteger Gcd(BigInteger &bi1, BigInteger &bi2){    BigInteger x, y;    BigInteger g = extended_euclidean(bi1, bi2, x, y);    return g;}BigInteger MultipInverse(BigInteger &bi1, BigInteger &n)   //求乘法逆元{   BigInteger x, y;   extended_euclidean(bi1, n, x, y);   if ((x.data[maxLength-1] & 0x80000000) != 0)     // x negative       x = x + n;  // unsigned int i =  x.data[maxLength-1] & 0x80000000;  // cout << i << endl;   return x;}

还需要一个用于计算消息hash值的MD5~

md5.h

[cpp] view plain copy
print?
  1. #include <stdio.h>  
  2. / #include <stdint.h>  
  3. #include <string.h>  
  4. #include <assert.h>  
  5.   
  6. #define ROTL32(dword, n) ((dword) << (n) ^ ((dword) >> (32 - (n))))  
  7. /*MD5的结果数据长度*/  
  8. static const unsigned int MD5_HASH_SIZE   = 16;  
  9.   
  10. /*每次处理的BLOCK的大小*/  
  11. static const unsigned int MD5_BLOCK_SIZE = 64;  
  12. //================================================================================================  
  13. /*MD5的算法*/  
  14.   
  15.   
  16. /*md5算法的上下文,保存一些状态,中间数据,结果*/  
  17. typedef struct md5_ctx  
  18. {  
  19.     /*处理的数据的长度*/  
  20.     unsigned __int64 length;  
  21.     /*还没有处理的数据长度*/  
  22.     unsigned __int64 unprocessed;  
  23.     /*取得的HASH结果(中间数据)*/  
  24.     unsigned int  hash[4];  
  25. } md5_ctx;  
  26.   
  27.   
  28.   
  29.   
  30. static void md5_init(md5_ctx *ctx)  
  31. {  
  32.     ctx->length = 0;  
  33.     ctx->unprocessed = 0;  
  34.   
  35.     /* initialize state */  
  36.  /*不要奇怪为什么初始数值与参考数值不同,这是因为我们使用的数据结构的关系,大的在低位,小的在高位,8位8位一读*/  
  37.     ctx->hash[0] = 0x67452301; /*应该这样读0x01234567*/  
  38.     ctx->hash[1] = 0xefcdab89; /*0x89abcdef*/  
  39.     ctx->hash[2] = 0x98badcfe; /*0xfedcba98*/  
  40.     ctx->hash[3] = 0x10325476; /*0x76543210*/  
  41. }  
  42.   
  43. #define MD5_F(x, y, z) ((((y) ^ (z)) & (x)) ^ (z))  
  44. #define MD5_G(x, y, z) (((x) & (z)) | ((y) & (~z)))  
  45. #define MD5_H(x, y, z) ((x) ^ (y) ^ (z))  
  46. #define MD5_I(x, y, z) ((y) ^ ((x) | (~z)))  
  47.   
  48. /* 一共4轮,每一轮使用不同函数*/  
  49. #define MD5_ROUND1(a, b, c, d, x, s, ac) {        \  
  50.         (a) += MD5_F((b), (c), (d)) + (x) + (ac); \  
  51.         (a) = ROTL32((a), (s));                   \  
  52.         (a) += (b);                               \  
  53.     }  
  54. #define MD5_ROUND2(a, b, c, d, x, s, ac) {        \  
  55.         (a) += MD5_G((b), (c), (d)) + (x) + (ac); \  
  56.         (a) = ROTL32((a), (s));                   \  
  57.         (a) += (b);                               \  
  58.     }  
  59. #define MD5_ROUND3(a, b, c, d, x, s, ac) {        \  
  60.         (a) += MD5_H((b), (c), (d)) + (x) + (ac); \  
  61.         (a) = ROTL32((a), (s));                   \  
  62.         (a) += (b);                               \  
  63.     }  
  64. #define MD5_ROUND4(a, b, c, d, x, s, ac) {        \  
  65.         (a) += MD5_I((b), (c), (d)) + (x) + (ac); \  
  66.         (a) = ROTL32((a), (s));                   \  
  67.         (a) += (b);                               \  
  68.     }  
  69.   
  70.   
  71. static void md5_process_block(unsigned int state[4], const unsigned int block[MD5_BLOCK_SIZE / 4])  
  72. {  
  73.     register unsigned a, b, c, d;  
  74.     a = state[0];  
  75.     b = state[1];  
  76.     c = state[2];  
  77.     d = state[3];  
  78.   
  79.     const unsigned int *x = block;  
  80.   
  81.   
  82.     MD5_ROUND1(a, b, c, d, x[ 0],  7, 0xd76aa478);  
  83.     MD5_ROUND1(d, a, b, c, x[ 1], 12, 0xe8c7b756);  
  84.     MD5_ROUND1(c, d, a, b, x[ 2], 17, 0x242070db);  
  85.     MD5_ROUND1(b, c, d, a, x[ 3], 22, 0xc1bdceee);  
  86.     MD5_ROUND1(a, b, c, d, x[ 4],  7, 0xf57c0faf);  
  87.     MD5_ROUND1(d, a, b, c, x[ 5], 12, 0x4787c62a);  
  88.     MD5_ROUND1(c, d, a, b, x[ 6], 17, 0xa8304613);  
  89.     MD5_ROUND1(b, c, d, a, x[ 7], 22, 0xfd469501);  
  90.     MD5_ROUND1(a, b, c, d, x[ 8],  7, 0x698098d8);  
  91.     MD5_ROUND1(d, a, b, c, x[ 9], 12, 0x8b44f7af);  
  92.     MD5_ROUND1(c, d, a, b, x[10], 17, 0xffff5bb1);  
  93.     MD5_ROUND1(b, c, d, a, x[11], 22, 0x895cd7be);  
  94.     MD5_ROUND1(a, b, c, d, x[12],  7, 0x6b901122);  
  95.     MD5_ROUND1(d, a, b, c, x[13], 12, 0xfd987193);  
  96.     MD5_ROUND1(c, d, a, b, x[14], 17, 0xa679438e);  
  97.     MD5_ROUND1(b, c, d, a, x[15], 22, 0x49b40821);  
  98.   
  99.     MD5_ROUND2(a, b, c, d, x[ 1],  5, 0xf61e2562);  
  100.     MD5_ROUND2(d, a, b, c, x[ 6],  9, 0xc040b340);  
  101.     MD5_ROUND2(c, d, a, b, x[11], 14, 0x265e5a51);  
  102.     MD5_ROUND2(b, c, d, a, x[ 0], 20, 0xe9b6c7aa);  
  103.     MD5_ROUND2(a, b, c, d, x[ 5],  5, 0xd62f105d);  
  104.     MD5_ROUND2(d, a, b, c, x[10],  9,  0x2441453);  
  105.     MD5_ROUND2(c, d, a, b, x[15], 14, 0xd8a1e681);  
  106.     MD5_ROUND2(b, c, d, a, x[ 4], 20, 0xe7d3fbc8);  
  107.     MD5_ROUND2(a, b, c, d, x[ 9],  5, 0x21e1cde6);  
  108.     MD5_ROUND2(d, a, b, c, x[14],  9, 0xc33707d6);  
  109.     MD5_ROUND2(c, d, a, b, x[ 3], 14, 0xf4d50d87);  
  110.     MD5_ROUND2(b, c, d, a, x[ 8], 20, 0x455a14ed);  
  111.     MD5_ROUND2(a, b, c, d, x[13],  5, 0xa9e3e905);  
  112.     MD5_ROUND2(d, a, b, c, x[ 2],  9, 0xfcefa3f8);  
  113.     MD5_ROUND2(c, d, a, b, x[ 7], 14, 0x676f02d9);  
  114.     MD5_ROUND2(b, c, d, a, x[12], 20, 0x8d2a4c8a);  
  115.   
  116.     MD5_ROUND3(a, b, c, d, x[ 5],  4, 0xfffa3942);  
  117.     MD5_ROUND3(d, a, b, c, x[ 8], 11, 0x8771f681);  
  118.     MD5_ROUND3(c, d, a, b, x[11], 16, 0x6d9d6122);  
  119.     MD5_ROUND3(b, c, d, a, x[14], 23, 0xfde5380c);  
  120.     MD5_ROUND3(a, b, c, d, x[ 1],  4, 0xa4beea44);  
  121.     MD5_ROUND3(d, a, b, c, x[ 4], 11, 0x4bdecfa9);  
  122.     MD5_ROUND3(c, d, a, b, x[ 7], 16, 0xf6bb4b60);  
  123.     MD5_ROUND3(b, c, d, a, x[10], 23, 0xbebfbc70);  
  124.     MD5_ROUND3(a, b, c, d, x[13],  4, 0x289b7ec6);  
  125.     MD5_ROUND3(d, a, b, c, x[ 0], 11, 0xeaa127fa);  
  126.     MD5_ROUND3(c, d, a, b, x[ 3], 16, 0xd4ef3085);  
  127.     MD5_ROUND3(b, c, d, a, x[ 6], 23,  0x4881d05);  
  128.     MD5_ROUND3(a, b, c, d, x[ 9],  4, 0xd9d4d039);  
  129.     MD5_ROUND3(d, a, b, c, x[12], 11, 0xe6db99e5);  
  130.     MD5_ROUND3(c, d, a, b, x[15], 16, 0x1fa27cf8);  
  131.     MD5_ROUND3(b, c, d, a, x[ 2], 23, 0xc4ac5665);  
  132.   
  133.     MD5_ROUND4(a, b, c, d, x[ 0],  6, 0xf4292244);  
  134.     MD5_ROUND4(d, a, b, c, x[ 7], 10, 0x432aff97);  
  135.     MD5_ROUND4(c, d, a, b, x[14], 15, 0xab9423a7);  
  136.     MD5_ROUND4(b, c, d, a, x[ 5], 21, 0xfc93a039);  
  137.     MD5_ROUND4(a, b, c, d, x[12],  6, 0x655b59c3);  
  138.     MD5_ROUND4(d, a, b, c, x[ 3], 10, 0x8f0ccc92);  
  139.     MD5_ROUND4(c, d, a, b, x[10], 15, 0xffeff47d);  
  140.     MD5_ROUND4(b, c, d, a, x[ 1], 21, 0x85845dd1);  
  141.     MD5_ROUND4(a, b, c, d, x[ 8],  6, 0x6fa87e4f);  
  142.     MD5_ROUND4(d, a, b, c, x[15], 10, 0xfe2ce6e0);  
  143.     MD5_ROUND4(c, d, a, b, x[ 6], 15, 0xa3014314);  
  144.     MD5_ROUND4(b, c, d, a, x[13], 21, 0x4e0811a1);  
  145.     MD5_ROUND4(a, b, c, d, x[ 4],  6, 0xf7537e82);  
  146.     MD5_ROUND4(d, a, b, c, x[11], 10, 0xbd3af235);  
  147.     MD5_ROUND4(c, d, a, b, x[ 2], 15, 0x2ad7d2bb);  
  148.     MD5_ROUND4(b, c, d, a, x[ 9], 21, 0xeb86d391);  
  149.   
  150.     state[0] += a;  
  151.     state[1] += b;  
  152.     state[2] += c;  
  153.     state[3] += d;  
  154. }  
  155.   
  156.   
  157. static void md5_update(md5_ctx *ctx, const unsigned char *buf, unsigned int size)  
  158. {  
  159.     /*为什么不是=,因为在某些环境下,可以多次调用zen_md5_update,但这种情况,必须保证前面的调用,每次都没有unprocessed*/  
  160.     ctx->length += size;  
  161.   
  162.     /*每个处理的块都是64字节*/  
  163.     while (size >= MD5_BLOCK_SIZE)  
  164.     {  
  165.         md5_process_block(ctx->hash, reinterpret_cast<const unsigned int *>(buf));  
  166.         buf  += MD5_BLOCK_SIZE;    /*buf指针每一次向后挪动64*/  
  167.         size -= MD5_BLOCK_SIZE;   /*每一次处理64个字符*/  
  168.     }  
  169.   
  170.     ctx->unprocessed = size;   /*未处理的字符数数目记录下来*/  
  171. }  
  172.   
  173.   
  174.   
  175. static void md5_final(md5_ctx *ctx, const unsigned char *buf, unsigned int size, unsigned char *result)  
  176. {  
  177.     unsigned int message[MD5_BLOCK_SIZE / 4];  
  178.  memset(message, 0 ,(MD5_BLOCK_SIZE / 4) * sizeof(unsigned int));  
  179.     /*保存剩余的数据,我们要拼出最后1个(或者两个)要处理的块,前面的算法保证了,最后一个块肯定小于64个字节*/  
  180.     if (ctx->unprocessed)  
  181.     {  
  182.         memcpy(message, buf + size - ctx->unprocessed, static_cast<unsigned int>( ctx->unprocessed));  
  183.     /*================================================================================ 
  184.      这里的memcpy复制很有趣,是按照字节复制比如说buf — 0x11 0x14 0xab 0x23 0xcd  | 
  185.      ctx>unprocessed_=5 现在copy至 message — 0x23ab1411 0x000000cd 
  186.      这样的话,下面的也很好解释了! 
  187.     =================================================================================*/  
  188.     }  
  189.    /*================================================================================= 
  190.        用法:static_cast < type-id > ( expression ) 
  191.        该运算符把expression转换为type-id类型 
  192.        ==================================================================================*/  
  193.   
  194.     /*得到0x80要添加在的位置(在unsigned int 数组中)*/  
  195.     unsigned int index = ((unsigned int)ctx->length & 63) >> 2;  
  196.  /*一次性处理64个unsigned int型数据,(unsigned int)ctx->length_ & 63求出余下多少未处理的字符*/  
  197.   
  198.     unsigned int shift = ((unsigned int)ctx->length & 3) * 8;  
  199.  /*一个message里面可以放置4个字符数据,找到应该移动的位数*/  
  200.   
  201.     /*添加0x80进去,并且把余下的空间补充0*/  
  202.     message[index++] ^= 0x80 << shift;   /*^ 位异或*/  
  203.   
  204.     /*如果这个block还无法处理,其后面的长度无法容纳长度64bit,那么先处理这个block*/  
  205.     if (index > 14)  
  206.     {  
  207.         while (index < 16)  
  208.         {  
  209.             message[index++] = 0;  
  210.         }  
  211.   
  212.         md5_process_block(ctx->hash, message);  
  213.         index = 0;  
  214.     }  
  215.   
  216.     /*补0*/  
  217.     while (index < 14)  
  218.     {  
  219.         message[index++] = 0;  
  220.     }  
  221.   
  222.     /*保存长度,注意是bit位的长度*/  
  223.     unsigned __int64 data_len = (ctx->length) << 3;  
  224.   
  225.     message[14] = (unsigned int) (data_len & 0x00000000FFFFFFFF);  
  226.     message[15] = (unsigned int) ((data_len & 0xFFFFFFFF00000000ULL) >> 32);  
  227.   
  228.     md5_process_block(ctx->hash, message);  
  229.     memcpy(result, &ctx->hash, MD5_HASH_SIZE);    
  230. }  
  231.   
  232.   
  233.  unsigned char* md5(const unsigned char *buf,  unsigned int  size,   unsigned char result[MD5_HASH_SIZE])    
  234. {    
  235.     md5_ctx ctx;    
  236.     md5_init(&ctx);   /*初始化*/  
  237.     md5_update(&ctx, buf, size);       
  238.     md5_final(&ctx, buf, size, result);    
  239.     return result;    
  240. }    
 #include <stdio.h>// #include <stdint.h> #include <string.h> #include <assert.h> #define ROTL32(dword, n) ((dword) << (n) ^ ((dword) >> (32 - (n)))) /*MD5的结果数据长度*/ static const unsigned int MD5_HASH_SIZE   = 16; /*每次处理的BLOCK的大小*/ static const unsigned int MD5_BLOCK_SIZE = 64; //================================================================================================ /*MD5的算法*/ /*md5算法的上下文,保存一些状态,中间数据,结果*/ typedef struct md5_ctx {     /*处理的数据的长度*/     unsigned __int64 length;     /*还没有处理的数据长度*/     unsigned __int64 unprocessed;     /*取得的HASH结果(中间数据)*/     unsigned int  hash[4]; } md5_ctx; static void md5_init(md5_ctx *ctx) {     ctx->length = 0;     ctx->unprocessed = 0;     /* initialize state */     /*不要奇怪为什么初始数值与参考数值不同,这是因为我们使用的数据结构的关系,大的在低位,小的在高位,8位8位一读*/     ctx->hash[0] = 0x67452301; /*应该这样读0x01234567*/     ctx->hash[1] = 0xefcdab89; /*0x89abcdef*/     ctx->hash[2] = 0x98badcfe; /*0xfedcba98*/     ctx->hash[3] = 0x10325476; /*0x76543210*/ } #define MD5_F(x, y, z) ((((y) ^ (z)) & (x)) ^ (z)) #define MD5_G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define MD5_H(x, y, z) ((x) ^ (y) ^ (z)) #define MD5_I(x, y, z) ((y) ^ ((x) | (~z))) /* 一共4轮,每一轮使用不同函数*/ #define MD5_ROUND1(a, b, c, d, x, s, ac) {        \         (a) += MD5_F((b), (c), (d)) + (x) + (ac); \         (a) = ROTL32((a), (s));                   \         (a) += (b);                               \     } #define MD5_ROUND2(a, b, c, d, x, s, ac) {        \         (a) += MD5_G((b), (c), (d)) + (x) + (ac); \         (a) = ROTL32((a), (s));                   \         (a) += (b);                               \     } #define MD5_ROUND3(a, b, c, d, x, s, ac) {        \         (a) += MD5_H((b), (c), (d)) + (x) + (ac); \         (a) = ROTL32((a), (s));                   \         (a) += (b);                               \     } #define MD5_ROUND4(a, b, c, d, x, s, ac) {        \         (a) += MD5_I((b), (c), (d)) + (x) + (ac); \         (a) = ROTL32((a), (s));                   \         (a) += (b);                               \     } static void md5_process_block(unsigned int state[4], const unsigned int block[MD5_BLOCK_SIZE / 4]) {     register unsigned a, b, c, d;     a = state[0];     b = state[1];     c = state[2];     d = state[3];     const unsigned int *x = block;     MD5_ROUND1(a, b, c, d, x[ 0],  7, 0xd76aa478);     MD5_ROUND1(d, a, b, c, x[ 1], 12, 0xe8c7b756);     MD5_ROUND1(c, d, a, b, x[ 2], 17, 0x242070db);     MD5_ROUND1(b, c, d, a, x[ 3], 22, 0xc1bdceee);     MD5_ROUND1(a, b, c, d, x[ 4],  7, 0xf57c0faf);     MD5_ROUND1(d, a, b, c, x[ 5], 12, 0x4787c62a);     MD5_ROUND1(c, d, a, b, x[ 6], 17, 0xa8304613);     MD5_ROUND1(b, c, d, a, x[ 7], 22, 0xfd469501);     MD5_ROUND1(a, b, c, d, x[ 8],  7, 0x698098d8);     MD5_ROUND1(d, a, b, c, x[ 9], 12, 0x8b44f7af);     MD5_ROUND1(c, d, a, b, x[10], 17, 0xffff5bb1);     MD5_ROUND1(b, c, d, a, x[11], 22, 0x895cd7be);     MD5_ROUND1(a, b, c, d, x[12],  7, 0x6b901122);     MD5_ROUND1(d, a, b, c, x[13], 12, 0xfd987193);     MD5_ROUND1(c, d, a, b, x[14], 17, 0xa679438e);     MD5_ROUND1(b, c, d, a, x[15], 22, 0x49b40821);     MD5_ROUND2(a, b, c, d, x[ 1],  5, 0xf61e2562);     MD5_ROUND2(d, a, b, c, x[ 6],  9, 0xc040b340);     MD5_ROUND2(c, d, a, b, x[11], 14, 0x265e5a51);     MD5_ROUND2(b, c, d, a, x[ 0], 20, 0xe9b6c7aa);     MD5_ROUND2(a, b, c, d, x[ 5],  5, 0xd62f105d);     MD5_ROUND2(d, a, b, c, x[10],  9,  0x2441453);     MD5_ROUND2(c, d, a, b, x[15], 14, 0xd8a1e681);     MD5_ROUND2(b, c, d, a, x[ 4], 20, 0xe7d3fbc8);     MD5_ROUND2(a, b, c, d, x[ 9],  5, 0x21e1cde6);     MD5_ROUND2(d, a, b, c, x[14],  9, 0xc33707d6);     MD5_ROUND2(c, d, a, b, x[ 3], 14, 0xf4d50d87);     MD5_ROUND2(b, c, d, a, x[ 8], 20, 0x455a14ed);     MD5_ROUND2(a, b, c, d, x[13],  5, 0xa9e3e905);     MD5_ROUND2(d, a, b, c, x[ 2],  9, 0xfcefa3f8);     MD5_ROUND2(c, d, a, b, x[ 7], 14, 0x676f02d9);     MD5_ROUND2(b, c, d, a, x[12], 20, 0x8d2a4c8a);     MD5_ROUND3(a, b, c, d, x[ 5],  4, 0xfffa3942);     MD5_ROUND3(d, a, b, c, x[ 8], 11, 0x8771f681);     MD5_ROUND3(c, d, a, b, x[11], 16, 0x6d9d6122);     MD5_ROUND3(b, c, d, a, x[14], 23, 0xfde5380c);     MD5_ROUND3(a, b, c, d, x[ 1],  4, 0xa4beea44);     MD5_ROUND3(d, a, b, c, x[ 4], 11, 0x4bdecfa9);     MD5_ROUND3(c, d, a, b, x[ 7], 16, 0xf6bb4b60);     MD5_ROUND3(b, c, d, a, x[10], 23, 0xbebfbc70);     MD5_ROUND3(a, b, c, d, x[13],  4, 0x289b7ec6);     MD5_ROUND3(d, a, b, c, x[ 0], 11, 0xeaa127fa);     MD5_ROUND3(c, d, a, b, x[ 3], 16, 0xd4ef3085);     MD5_ROUND3(b, c, d, a, x[ 6], 23,  0x4881d05);     MD5_ROUND3(a, b, c, d, x[ 9],  4, 0xd9d4d039);     MD5_ROUND3(d, a, b, c, x[12], 11, 0xe6db99e5);     MD5_ROUND3(c, d, a, b, x[15], 16, 0x1fa27cf8);     MD5_ROUND3(b, c, d, a, x[ 2], 23, 0xc4ac5665);     MD5_ROUND4(a, b, c, d, x[ 0],  6, 0xf4292244);     MD5_ROUND4(d, a, b, c, x[ 7], 10, 0x432aff97);     MD5_ROUND4(c, d, a, b, x[14], 15, 0xab9423a7);     MD5_ROUND4(b, c, d, a, x[ 5], 21, 0xfc93a039);     MD5_ROUND4(a, b, c, d, x[12],  6, 0x655b59c3);     MD5_ROUND4(d, a, b, c, x[ 3], 10, 0x8f0ccc92);     MD5_ROUND4(c, d, a, b, x[10], 15, 0xffeff47d);     MD5_ROUND4(b, c, d, a, x[ 1], 21, 0x85845dd1);     MD5_ROUND4(a, b, c, d, x[ 8],  6, 0x6fa87e4f);     MD5_ROUND4(d, a, b, c, x[15], 10, 0xfe2ce6e0);     MD5_ROUND4(c, d, a, b, x[ 6], 15, 0xa3014314);     MD5_ROUND4(b, c, d, a, x[13], 21, 0x4e0811a1);     MD5_ROUND4(a, b, c, d, x[ 4],  6, 0xf7537e82);     MD5_ROUND4(d, a, b, c, x[11], 10, 0xbd3af235);     MD5_ROUND4(c, d, a, b, x[ 2], 15, 0x2ad7d2bb);     MD5_ROUND4(b, c, d, a, x[ 9], 21, 0xeb86d391);     state[0] += a;     state[1] += b;     state[2] += c;     state[3] += d; } static void md5_update(md5_ctx *ctx, const unsigned char *buf, unsigned int size) {     /*为什么不是=,因为在某些环境下,可以多次调用zen_md5_update,但这种情况,必须保证前面的调用,每次都没有unprocessed*/     ctx->length += size;     /*每个处理的块都是64字节*/     while (size >= MD5_BLOCK_SIZE)     {         md5_process_block(ctx->hash, reinterpret_cast<const unsigned int *>(buf));         buf  += MD5_BLOCK_SIZE;    /*buf指针每一次向后挪动64*/         size -= MD5_BLOCK_SIZE;   /*每一次处理64个字符*/     }     ctx->unprocessed = size;   /*未处理的字符数数目记录下来*/ } static void md5_final(md5_ctx *ctx, const unsigned char *buf, unsigned int size, unsigned char *result) {     unsigned int message[MD5_BLOCK_SIZE / 4];     memset(message, 0 ,(MD5_BLOCK_SIZE / 4) * sizeof(unsigned int));     /*保存剩余的数据,我们要拼出最后1个(或者两个)要处理的块,前面的算法保证了,最后一个块肯定小于64个字节*/     if (ctx->unprocessed)     {         memcpy(message, buf + size - ctx->unprocessed, static_cast<unsigned int>( ctx->unprocessed));        /*================================================================================         这里的memcpy复制很有趣,是按照字节复制比如说buf --- 0x11 0x14 0xab 0x23 0xcd  |         ctx>unprocessed_=5 现在copy至 message --- 0x23ab1411 0x000000cd         这样的话,下面的也很好解释了!        =================================================================================*/     }       /*=================================================================================        用法:static_cast < type-id > ( expression )        该运算符把expression转换为type-id类型        ==================================================================================*/     /*得到0x80要添加在的位置(在unsigned int 数组中)*/     unsigned int index = ((unsigned int)ctx->length & 63) >> 2;     /*一次性处理64个unsigned int型数据,(unsigned int)ctx->length_ & 63求出余下多少未处理的字符*/     unsigned int shift = ((unsigned int)ctx->length & 3) * 8;     /*一个message里面可以放置4个字符数据,找到应该移动的位数*/     /*添加0x80进去,并且把余下的空间补充0*/     message[index++] ^= 0x80 << shift;   /*^ 位异或*/     /*如果这个block还无法处理,其后面的长度无法容纳长度64bit,那么先处理这个block*/     if (index > 14)     {         while (index < 16)         {             message[index++] = 0;         }         md5_process_block(ctx->hash, message);         index = 0;     }     /*补0*/     while (index < 14)     {         message[index++] = 0;     }     /*保存长度,注意是bit位的长度*/     unsigned __int64 data_len = (ctx->length) << 3;     message[14] = (unsigned int) (data_len & 0x00000000FFFFFFFF);     message[15] = (unsigned int) ((data_len & 0xFFFFFFFF00000000ULL) >> 32);     md5_process_block(ctx->hash, message);     memcpy(result, &ctx->hash, MD5_HASH_SIZE);   }  unsigned char* md5(const unsigned char *buf,  unsigned int  size,   unsigned char result[MD5_HASH_SIZE])   {       md5_ctx ctx;       md5_init(&ctx);   /*初始化*/     md5_update(&ctx, buf, size);          md5_final(&ctx, buf, size, result);       return result;   }   
然后才是ELGamal的实现~

ELGamal.h

[cpp] view plain copy
print?
  1. #include <string>  
  2. #include “BigInteger.h”  
  3. #include “md5.h”  
  4.   
  5.   
  6. /* 
  7. *事先说明一句:由于大素数的本原元很难求得,所以这里的数字签名所需要的数字我都提前给出 
  8. *避免了没必要的十分耗时的生成过程,大家也可以直接修改这些数字,即使是很大的数也支持! 
  9. */  
  10.   
  11. /*测试数据: 
  12. * 素数 p = 19, 本原元 g = 2, 私钥 x = 9, 公钥 y = 18, 随机取值 k = 5 
  13. */  
  14.   
  15. string prime(”19”), prielem(“2”), key(“9”), pubKey(“18”), randomK(“5”);  
  16.   
  17. /*数的初始化*/  
  18. /*p 素数 g 本原元 x 私钥 y 公钥 k 随机取值*/  
  19. BigInteger p(prime, 10),g(prielem, 10), x(key, 10), y(pubKey, 10), k(randomK, 10),  
  20.         one((__int64)1), two((__int64)2);  
  21.   
  22. /*签名*/  
  23. void elgamalSign(unsigned char *message, int len, BigInteger &r, BigInteger &s)  
  24. {  
  25.       
  26.     /*m 为消息所对应的明文数值*/  
  27.     unsigned char result[16] ={0};  
  28.     md5(message, len, result);  
  29.   
  30.     /*输出MD5值*/  
  31.     cout << ”消息的MD5散列值为:” ;  
  32.     for (int i = 0; i < 16; i++)  
  33.      printf (”%02x”, result[i]);  
  34.     cout << endl;  
  35.   
  36.     /*用md5作为消息的hash值*/  
  37.     /*用hash值初始化m*/  
  38.     BigInteger m(result, 16), pMinusOne(p - one);  
  39.     BigInteger  k1;  
  40.   
  41.     r = g.modPow(k, p);  
  42.   
  43.     /*k1 为 k 在 p - 1 下的逆元*/  
  44.     k1 = MultipInverse(k, pMinusOne);  
  45.   
  46.     s = ((m - x * r) * k1 ) % pMinusOne;  
  47.       
  48. }  
  49. /*签名验证*/  
  50. bool elgamalVerifiSign(unsigned char *message, int len, BigInteger &r, BigInteger &s)  
  51. {  
  52.     cout << ”接收到消息的MD5散列值为:”;  
  53.     unsigned char result[16] ={0};  
  54.   
  55.     md5(message, len, result);  
  56.     for (int i = 0; i < 16; i++)  
  57.      printf (”%02x”, result[i]);  
  58.     cout << endl;  
  59.   
  60.     BigInteger leftValue, rightValue;  
  61.     BigInteger m(result, 16);  
  62.   
  63.     leftValue = (y.modPow(r, p) * r.modPow(s, p)) % p;  
  64.     rightValue = g.modPow(m, p);  
  65.     if (leftValue == rightValue)  
  66.     {  
  67.         return true;  
  68.     }  
  69.     else  
  70.     {  
  71.         return false;  
  72.     }  
  73.   
  74. }  
#include <string>
#include "BigInteger.h"#include "md5.h"/**事先说明一句:由于大素数的本原元很难求得,所以这里的数字签名所需要的数字我都提前给出*避免了没必要的十分耗时的生成过程,大家也可以直接修改这些数字,即使是很大的数也支持!*//*测试数据:* 素数 p = 19, 本原元 g = 2, 私钥 x = 9, 公钥 y = 18, 随机取值 k = 5*/string prime("19"), prielem("2"), key("9"), pubKey("18"), randomK("5");/*数的初始化*//*p 素数 g 本原元 x 私钥 y 公钥 k 随机取值*/BigInteger p(prime, 10),g(prielem, 10), x(key, 10), y(pubKey, 10), k(randomK, 10), one((__int64)1), two((__int64)2);/*签名*/void elgamalSign(unsigned char *message, int len, BigInteger &r, BigInteger &s){ /*m 为消息所对应的明文数值*/ unsigned char result[16] ={0}; md5(message, len, result); /*输出MD5值*/ cout << "消息的MD5散列值为:" ; for (int i = 0; i < 16; i++) printf ("%02x", result[i]); cout << endl; /*用md5作为消息的hash值*/ /*用hash值初始化m*/ BigInteger m(result, 16), pMinusOne(p - one); BigInteger k1; r = g.modPow(k, p); /*k1 为 k 在 p - 1 下的逆元*/ k1 = MultipInverse(k, pMinusOne); s = ((m - x * r) * k1 ) % pMinusOne;}/*签名验证*/bool elgamalVerifiSign(unsigned char *message, int len, BigInteger &r, BigInteger &s){ cout << "接收到消息的MD5散列值为:"; unsigned char result[16] ={0}; md5(message, len, result); for (int i = 0; i < 16; i++) printf ("%02x", result[i]); cout << endl; BigInteger leftValue, rightValue; BigInteger m(result, 16); leftValue = (y.modPow(r, p) * r.modPow(s, p)) % p; rightValue = g.modPow(m, p); if (leftValue == rightValue) { return true; } else { return false; }}最后上一个主函数测试一下!

main.cpp

[cpp] view plain copy
print?
  1. //本原元的概念:若模n下a的阶d=φ(n),a就是n的本原元(又称为原根)。此时a是Z*_n的生成元。  
  2. /*====================================================== 
  3. Diffie-Hellman 算法下面就给出一个快速求大素数 p 及其本原根的算法 
  4. 算法如下: 
  5. P1. 利用素性验证算法,生成一个大素数 q; 
  6. P2. 令 p = q * 2 + 1; 
  7. P3. 利用素性验证算法,验证 p 是否是素数,如果 p 是合数,则跳转到 P1; 
  8. P4. 生成一个随机数 g,1 < g < p - 1; 
  9. P5. 验证 g2 mod p 和 gq mod p 都不等于 1,否则跳转到 P4; 
  10. P6. g 是大素数 p 的本原根。 
  11. ======================================================*/  
  12. #include “ELGamal.h”  
  13.   
  14. int main()  
  15. {  
  16. /*================================================================ 
  17. //求一个大素数以及其本原元有点难度,速度慢到不行,我丢弃了这个想法,素数和本原元直接输入 
  18. BigInteger p((__int64)3), q, two((__int64)2), one((__int64)1), g, zero; 
  19. srand((unsigned)time(0)); 
  20. bool flag = false; 
  21. while(!flag) 
  22. { 
  23.     q = GetPrime(); //得到一个大素数 
  24.     //cout << q << endl; 
  25.     //system(“pause”); 
  26.     p = q * two + one; 
  27.     if(IsPrime(p)) 
  28.     flag = true; 
  29. } 
  30.         
  31. while ((g * g) % p != one && (g * q) % p != one ) 
  32. {    
  33.     unsigned int len = rand() % 20; 
  34.     for (int i = 0; i < len; i++)   //产生一个随机数g 
  35.     { 
  36.         g.data[i] = (unsigned int)rand (); 
  37.         if(g.data[i] != 0) 
  38.         g.dataLength = i + 1; 
  39.     } 
  40. } 
  41. cout << p << endl; 
  42. cout << g << endl; 
  43. ========================================================*/  
  44.     cout << ”签名者 A:” << endl;  
  45.       
  46.     string message;  
  47.     BigInteger r, s;  
  48.   
  49.     cout << ”请输入要签名的消息:” << endl;  
  50.     cin >> message;  
  51.       
  52.     elgamalSign((unsigned char *)message.c_str(), message.length(), r, s);  
  53.   
  54.     cout << ”签名信息如下:” << endl;  
  55.   
  56.     /*不要奇怪为什么r总是等于d,去看一下r的定义就知道了。 
  57.     *r  = g^k mod p[g是mod p 下的本原元, k是任意取的常数(k 与 p - 1互素),p是素数] 
  58.     *由于以上的这些数都提前给定了,所以结果也肯定是一个常数 
  59.     */  
  60.     cout << ”r = ” << r << endl;  
  61.     cout << ”s = ” << s << endl;  
  62.     cout << endl;  
  63.     /* 
  64.     unsigned int len = rand() % 10; 
  65.     for (int i = 0; i < len; i++) 
  66.     { 
  67.         k.data[i] = (unsigned int)rand (); 
  68.         if(k.data[i] != 0) 
  69.         k.dataLength = i + 1; 
  70.     } 
  71.     temp = p - one; 
  72.     while(Gcd(k,p - one) != one) 
  73.     { 
  74.         k = k + two; 
  75.     } 
  76.     cout << k <<endl; 
  77.     */  
  78.   
  79.     cout << ”现在将 消息 以及 r s 传递给接收方 B ~~~ ~~~” << endl;  
  80.     cout << endl;  
  81.     cout << ”接受者 B:” << endl;  
  82.     if (elgamalVerifiSign((unsigned char *)message.c_str(), message.length(), r, s))  
  83.     {  
  84.         cout << ”签名有效” << endl;  
  85.     }  
  86.     else  
  87.     {  
  88.         cout << ”签名无效” << endl;  
  89.     }  
  90.   
  91.     system (”pause”);  
  92.     return 0;  
  93. }  
//本原元的概念:若模n下a的阶d=φ(n),a就是n的本原元(又称为原根)。此时a是Z*_n的生成元。/*======================================================Diffie-Hellman 算法下面就给出一个快速求大素数 p 及其本原根的算法算法如下:P1. 利用素性验证算法,生成一个大素数 q;P2. 令 p = q * 2 + 1;P3. 利用素性验证算法,验证 p 是否是素数,如果 p 是合数,则跳转到 P1;P4. 生成一个随机数 g,1 < g < p - 1;P5. 验证 g2 mod p 和 gq mod p 都不等于 1,否则跳转到 P4;P6. g 是大素数 p 的本原根。======================================================*/
#include "ELGamal.h"int main(){/*================================================================//求一个大素数以及其本原元有点难度,速度慢到不行,我丢弃了这个想法,素数和本原元直接输入BigInteger p((__int64)3), q, two((__int64)2), one((__int64)1), g, zero;srand((unsigned)time(0));bool flag = false;while(!flag){ q = GetPrime(); //得到一个大素数 //cout << q << endl; //system("pause"); p = q * two + one; if(IsPrime(p)) flag = true;}while ((g * g) % p != one && (g * q) % p != one ){ unsigned int len = rand() % 20; for (int i = 0; i < len; i++) //产生一个随机数g { g.data[i] = (unsigned int)rand (); if(g.data[i] != 0) g.dataLength = i + 1; }}cout << p << endl;cout << g << endl;========================================================*/ cout << "签名者 A:" << endl; string message; BigInteger r, s; cout << "请输入要签名的消息:" << endl; cin >> message; elgamalSign((unsigned char *)message.c_str(), message.length(), r, s); cout << "签名信息如下:" << endl; /*不要奇怪为什么r总是等于d,去看一下r的定义就知道了。 *r = g^k mod p[g是mod p 下的本原元, k是任意取的常数(k 与 p - 1互素),p是素数] *由于以上的这些数都提前给定了,所以结果也肯定是一个常数 */ cout << "r = " << r << endl; cout << "s = " << s << endl; cout << endl; /* unsigned int len = rand() % 10; for (int i = 0; i < len; i++) { k.data[i] = (unsigned int)rand (); if(k.data[i] != 0) k.dataLength = i + 1; } temp = p - one; while(Gcd(k,p - one) != one) { k = k + two; } cout << k <<endl; */ cout << "现在将 消息 以及 r s 传递给接收方 B ~~~ ~~~" << endl; cout << endl; cout << "接受者 B:" << endl; if (elgamalVerifiSign((unsigned char *)message.c_str(), message.length(), r, s)) { cout << "签名有效" << endl; } else { cout << "签名无效" << endl; } system ("pause"); return 0;}

0 0