Principle and program demonstration of Diffie-Hellman Key Exchange Algorithm

Source: Internet
Author: User

In. Its mathematical basis is the mathematical difficulty of discrete logarithm. The key exchange process is described as follows:
Select two large numbers p and g and make them public. p is a prime number, and g is a module p of p. The original unit root (primitive root module p ), the original unit root refers to the power 1 and power 2 of g under the modulo p multiplication operation ...... (P-1) the numbers of the first power are different from each other and are retrieved from 1 to the first power;
For Alice (one of them), a random integer a is generated, a is kept confidential, Ka = g ^ a mod p is calculated, and Ka is sent to Bob;
For Bob (another contact), a random integer B is generated, B is kept confidential, Kb = g ^ B mod p is calculated, and Kb is sent to Alice;
For Alice, after receiving the Kb sent by Bob, the calculated key is: key = Kb ^ a mod p = (g ^ B) ^ a = g ^ (B *) mod p;
For Bob, after receiving the Ka sent by Alice, the calculated key is: key = Ka ^ B mod p = (g ^ a) ^ B = g ^ (a * B) mod p.
The attacker knows p and g and intercepts Ka and Kb. However, when they are all very large numbers, it is very difficult to calculate a and B Based on these four numbers, this is the mathematical problem of discrete logarithm.
To implement the Diffie-Hellman Key Exchange Protocol, you must be able to quickly calculate the power of a big digital model. In the modulo algorithm, you still need to calculate the multiplication and modulo operations of large numbers. Therefore, the entire process requires three algorithms: high-Precision multiplication and high-precision Division (used to calculate the quotient and remainder of A large number divided by another large number at the same time), a fast Modulo-power algorithm.
High-Precision multiplication and division can be simulated by a program. The quick modulo algorithm also summarizes the rule from the manual calculation, for example:
5 ^ 8 = (5 ^ 2) ^ 4 = (25) ^ 4 = (25 ^ 2) ^ 2 = (625) ^ 2. In this way, originally, 8 multiplications were required for calculation of 5 ^ 8, but now only three multiplications are required: 5 ^ 2, 25 ^ 2,625 ^ 2. This is the basis of the rapid Modulo-power algorithm. Describe the algorithm, that is:
Algorithm M: Input integer A, B, P, calculate a ^ B mod P:
M1. initialize c = 1
M2. if B is 0, C is the result to be calculated. Returns the value of C. The algorithm ends.
M3. If B is odd, C = C * a mod P, B = B-1, to M2.
M4. if B is an even number, convert a = A * a mod P, and B = B/2 to M2.
The high-precision Trial Division principle is simple, but the code implementation requires careful consideration of some details.
My DEMO code is as follows:
High-Precision computing:

  1. Class supernumber {
  2. Public:
  3. Supernumber (){
  4. Memset (data, 0, max_size );
  5. High = 0;
  6. }
  7. // General integer to supernumber conversion. This version does not support negative numbers
  8. Supernumber (unsigned long l ){
  9. Memset (data, 0, max_size );
  10. High = 0;
  11. While (l ){
  12. Data [++ high] = l % 10;
  13. L/= 10;
  14. }
  15. }
  16. // STR represents the decimal number in the string format
  17. Supernumber (const char * Str ){
  18. Assert (STR! = NULL );
  19. High = strlen (STR );
  20. For (int I = high, j = 0; I> = 1; I --, j ++ ){
  21. Data [I] = str [j]-'0 ';
  22. }
  23. }
  24. SuperNumber (const SuperNumber & s ){
  25. Memcpy (data, s. data, MAX_SIZE );
  26. High = s. high;
  27. }
  28. Operator const char * () const {
  29. Return toString (10 );
  30. }
  31. Supernumber & operator = (const supernumber & S ){
  32. If (this! = & S ){
  33. Memcpy (data, S. Data, max_size );
  34. High = S. High;
  35. }
  36. Return * this;
  37. }
  38. // Set the data to 0
  39. Void reset (){
  40. Memset (data, 0, max_size );
  41. High = 0;
  42. }
  43. // Str represents the decimal number in the string format
  44. Void setToStr (const char * str ){
  45. Assert (str! = NULL );
  46. High = strlen (str );
  47. For (int I = high, j = 0; I> = 1; I --, j ++ ){
  48. Data [I] = str [j]-'0 ';
  49. }
  50. }
  51. // Convert the data to a base-specified string. The default value is decimal.
  52. Const char * toString (int base = 10) const {
  53. Static char buf [MAX_SIZE];
  54. Const char table [] = "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
  55. If (high = 0) return "0 ";
  56. Assert (base> = 2); // The specified hexadecimal value should not be less than 2
  57. // Hexadecimal conversion
  58. Buf [MAX_SIZE-1] = '/0 ';
  59. Int begin = MAX_SIZE-1;
  60. Char temp [MAX_SIZE];
  61. Memcpy (temp, data, MAX_SIZE );
  62. While (1 ){
  63. // Locate the start position of the highest bit
  64. Int h = high;
  65. While (temp [h] = 0 & h> = 1) h --;
  66. If (h = 0) break;
  67. // Except the base
  68. Int t = 0;
  69. While (h> = 1 ){
  70. T = t * 10 + temp [h];
  71. Temp [h] = t/base;
  72. T = t % base;
  73. H --;
  74. }
  75. Buf [-- begin] = table [t];
  76. }
  77. Return buf + begin;
  78. }
  79. // Multiplication
  80. SuperNumber operator * (const SuperNumber & s) const {
  81. SuperNumber result; // default set to 0
  82. Int I, j;
  83. // Multiply
  84. For (I = 1; I <= high; I ++ ){
  85. For (j = 1; j <= s. high; j ++ ){
  86. Int k = data [I] * s. data [j] + result. data [I + J-1];
  87. Result. data [I + J-1] = k % 10;
  88. Result. data [I + j] + = k/10;
  89. }
  90. }
  91. // Carry
  92. For (I = 1; I <MAX_SIZE-1; I ++ ){
  93. If (result. Data [I]> = 10 ){
  94. Result. Data [I + 1] + = result. Data [I]/10;
  95. Result. Data [I] % = 10;
  96. }
  97. }
  98. // Determine the highest bit
  99. For (I = MAX_SIZE-1; I> = 1 & result. Data [I] = 0; I --);
  100. Result. High = I;
  101. Return result;
  102. }
  103. // Division, which is implemented by calling doDivide internally
  104. SuperNumber operator/(const SuperNumber & s) const {
  105. SuperNumber q, r;
  106. DoDivide (s, q, r );
  107. Return q;
  108. }
  109. // Modulo operation, which is implemented by calling doDivide internally
  110. SuperNumber operator % (const SuperNumber & s) const {
  111. SuperNumber q, r;
  112. DoDivide (s, q, r );
  113. Return r;
  114. }
  115. // Division operation. In a division operation, the operator and remainder, operators, and % are reloaded simultaneously.
  116. // This function is called internally. dest is the divisor, Q is the quotient, and R is the remainder. The algorithm uses the Trial Division.
  117. Void doDivide (const SuperNumber & dest, SuperNumber & Q, SuperNumber & R) const {
  118. Int I, j, t;
  119. Q. reset ();
  120. Q. high = high-dest. high + 1; // initial bid of the operator
  121. R = * This; // the remainder is actually the dividend.
  122. T = DeST. High;
  123. // Judge whether the Division ends
  124. While (r> = DEST ){
  125. // Perform cyclic subtraction for Trial Division
  126. While (DEST> = R. sub (1, t )){
  127. Q. Data [q. High --] = 0;
  128. ++ T;
  129. }
  130. While (R. sub (1, t)> = DEST ){
  131. // When I is subtraction, the lowest subscript OF THE devisor and J is the lowest subscript OF THE devisor.
  132. For (I = R. High-t + 1, j = 1; j <= DeST. High; I ++, J ++ ){
  133. R. Data [I]-= DeST. Data [J];
  134. If (R. data [I] <0 ){
  135. R. data [I] + = 10;
  136. R. data [I + 1]-= 1;
  137. }
  138. }
  139. While (R. data [I] <0 & I <= R. high ){
  140. R. data [I] + = 10;
  141. R. data [I + 1]-= 1;
  142. ++ I;
  143. }
  144. Q. data [Q. high] + = 1;
  145. }
  146. // The maximum subscript of the Updater after a Trial Division is completed
  147. Q. high-= 1;
  148. // Update the highest subscript of the divisor.
  149. While (R. data [R. high] = 0 ){
  150. R. high --;
  151. T --;
  152. }
  153. T + = 1; // The next Divisor
  154. }
  155. Q. high = high-dest. high + 1;
  156. While (Q. data [Q. high] = 0) Q. high-= 1;
  157. R. high = high;
  158. While (R. data [R. high] = 0) R. high-= 1;
  159. }
  160. // Big digital-to-analog power algorithm. It is a simple natural algorithm, that is, to break down an index into binary values.
  161. // More simply, it is to constantly find the square modulo power, instead of multiplying all squares before
  162. // Perform a final modulo operation
  163. // A. power_mod (p, n) calculates a ^ p mod n
  164. SuperNumber power_mod (int power, SuperNumber n) const {
  165. Supernumber C ("1"), T (* This );
  166. While (Power ){
  167. If (Power % 2 ){
  168. C = C * T % N;
  169. Power-= 1;
  170. } Else {
  171. T = T * T % N;
  172. Power/= 2;
  173. }
  174. }
  175. Return C % N;
  176. }
  177. Bool operator> = (const supernumber & S) const {
  178. If (high = S. High ){
  179. Int K = high;
  180. While (data [k] = S. Data [k] & K> = 1) k --;
  181. If (k <1) return true; // equal
  182. Return data [k]> s. data [k];
  183. } Else if (high> s. high) return true;
  184. Return false;
  185. }
  186. Bool operator <(const SuperNumber & s) const {
  187. Return! (* This> = s );
  188. }
  189. // Start from the highest digit in decimal format, count to the first digit, and intercept consecutive digits from the second digit.
  190. // The c-digit to form a new number. For example, if the data is 12345678925698
  191. // Sub (3, 5) returns the number 34567. If the number is not enough, run
  192. // Sub (3, 5), because 34567 is 5 from the high digits, and the remaining number is 3rd,
  193. // There are three at most, and five are not enough. At this time, 567 is returned and no error is returned.
  194. SuperNumber sub (int I, int c) const {
  195. SuperNumber ret;
  196. Assert (high> = I); // ensure intercept
  197. I = high-I + 1; // subscript of the I-th digit starting from the high digit
  198. If (I> = c ){
  199. Ret. high = c;
  200. While (C> = 1) ret. Data [c --] = data [I --];
  201. } Else {
  202. Ret. High = I;
  203. While (I> = 1 ){
  204. Ret. Data [I] = data [I];
  205. I --;
  206. }
  207. }
  208. // Filter the leading 0
  209. While (ret. data [ret. high] = 0) ret. high --;
  210. Return ret;
  211. }
  212. // I/O
  213. Friend istream & operator> (istream & in, SuperNumber & s ){
  214. Char t [256];
  215. In> t;
  216. S. setToStr (t );
  217. Return in;
  218. }
  219. Friend ostream & operator <(ostream & out, const SuperNumber & s ){
  220. Return out <s. toString (10 );
  221. }
  222. Private:
  223. Enum {MAX_SIZE = 256}; // maximum decimal digits
  224. // Note that using data [0] to store the subscript of the highest bit is a bit clever. Later
  225. // This is a huge error during debugging, but it can be handled for this question.
  226. Char data [MAX_SIZE]; // internal representation of the data, in decimal format
  227. // Where data [0] stores the subscript of the highest bit, data [1]
  228. // The bitwise of the stored data, that is, the bitwise
  229. Int high;
  230. };

Main function:

  1. Int main (INT argc, char ** argv ){
  2. Freopen ("in.txt", "r", stdin );
  3. Supernumbertest st;
  4. // St. Run ();
  5. // Both g and n are prime numbers greater than 2 ^ 127. They are made public in DH algorithms.
  6. Supernumber g, N;
  7. Int A, B;
  8. Supernumber ka, kb, key;
  9. Srand (time (0 ));
  10. Cin> g> n;
  11. Cout <"g =" <g <endl
  12. <"N =" <n <endl;
  13. Cout <"/nThis is Alice:/n ";
  14. A = rand ();
  15. Cout <"Alice get a random integer a =" <a <endl;
  16. Cout <"Alice computer g ^ a mod n:/n ";
  17. Ka = g. power_mod (a, n );
  18. Cout <"Alice compute out ka =" <ka <endl;
  19. Cout <"/nThis is Bob:/n ";
  20. B = rand ();
  21. Cout <"Bob get a random integer B =" <B <endl;
  22. Cout <"Bob compute g ^ B mod n:/n ";
  23. Kb = g. power_mod (B, n );
  24. Cout <"Bob compute out kb =" <kb <endl;
  25. Cout <"/nalice get Kb from Bob, she compute out key is:/N ";
  26. Cout <kb. power_mod (A, n) <Endl;
  27. Cout <"/nbob get Ka from Alice, he compute out key is:/N ";
  28. Cout <ka. power_mod (B, n) <Endl;
  29. Return 0;
  30. }

Running result:
G = 170141183460469231731687303715884105757
N = 170141183460469231731687303715884106309

This is Alice:
Alice get a random integer a = 20276
Alice computer G ^ A mod N:
Alice compute out Ka = 102075421398841759242347870420481896337

This is Bob:
Bob get a random integer B = 28664
Bob compute G ^ B mod N:
Bob compute out kb = 62348451302684698452476840835428450852

Alice get Kb from Bob, she compute out key is:
80402514625208456390620786920929643017

Bob get Ka from Alice, he compute out key is:
80402514625208456390620786920929643017
The Demo code of the algorithm implemented using the gnu gmp library is given in the http://oldpiewiki.yoonkn.com/cgi-bin/moin.cgi/DiffieHellmanKeyExchange.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.