diffie_hellman.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #
  2. # Copyright 2019 The FATE Authors. All Rights Reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. #
  16. import random
  17. import gmpy2
  18. from gmpy2 import mpz
  19. class DiffieHellman(object):
  20. @staticmethod
  21. def _decode_hex_string(number_str):
  22. return mpz("0x{0}".format("".join(number_str.split())))
  23. @staticmethod
  24. def _oakley_group_768_768():
  25. """
  26. from RFC 2409, refer to https://tools.ietf.org/html/rfc2409#page-21
  27. """
  28. p = DiffieHellman._decode_hex_string("""
  29. FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
  30. 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
  31. EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
  32. E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF
  33. """)
  34. g = DiffieHellman._decode_hex_string("2")
  35. return p, g
  36. @staticmethod
  37. def _oakley_group_1024_1024():
  38. """
  39. from RFC 2409, refer to https://tools.ietf.org/html/rfc2409#page-22
  40. """
  41. p = DiffieHellman._decode_hex_string("""
  42. FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
  43. 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
  44. EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
  45. E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
  46. EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381
  47. FFFFFFFF FFFFFFFF
  48. """)
  49. g = DiffieHellman._decode_hex_string("2")
  50. return p, g
  51. @staticmethod
  52. def _additional_group_1024_160():
  53. """
  54. from RFC 5114, has 160 bits subgroup size:
  55. 0xF518AA8781A8DF278ABA4E7D64B7CB9D49462353
  56. refer to https://tools.ietf.org/html/rfc5114
  57. """
  58. p = DiffieHellman._decode_hex_string("""
  59. B10B8F96 A080E01D DE92DE5E AE5D54EC 52C99FBC FB06A3C6
  60. 9A6A9DCA 52D23B61 6073E286 75A23D18 9838EF1E 2EE652C0
  61. 13ECB4AE A9061123 24975C3C D49B83BF ACCBDD7D 90C4BD70
  62. 98488E9C 219A7372 4EFFD6FA E5644738 FAA31A4F F55BCCC0
  63. A151AF5F 0DC8B4BD 45BF37DF 365C1A65 E68CFDA7 6D4DA708
  64. DF1FB2BC 2E4A4371
  65. """)
  66. g = DiffieHellman._decode_hex_string("""
  67. A4D1CBD5 C3FD3412 6765A442 EFB99905 F8104DD2 58AC507F
  68. D6406CFF 14266D31 266FEA1E 5C41564B 777E690F 5504F213
  69. 160217B4 B01B886A 5E91547F 9E2749F4 D7FBD7D3 B9A92EE1
  70. 909D0D22 63F80A76 A6A24C08 7A091F53 1DBF0A01 69B6A28A
  71. D662A4D1 8E73AFA3 2D779D59 18D08BC8 858F4DCE F97C2A24
  72. 855E6EEB 22B3B2E5
  73. """)
  74. return p, g
  75. @staticmethod
  76. def _additional_group_2048_224():
  77. """
  78. from RFC 5114, has 224 bits subgroup size:
  79. 0x801C0D34C58D93FE997177101F80535A4738CEBCBF389A99B36371EB
  80. refer to https://tools.ietf.org/html/rfc5114
  81. """
  82. p = DiffieHellman._decode_hex_string("""
  83. AD107E1E 9123A9D0 D660FAA7 9559C51F A20D64E5 683B9FD1
  84. B54B1597 B61D0A75 E6FA141D F95A56DB AF9A3C40 7BA1DF15
  85. EB3D688A 309C180E 1DE6B85A 1274A0A6 6D3F8152 AD6AC212
  86. 9037C9ED EFDA4DF8 D91E8FEF 55B7394B 7AD5B7D0 B6C12207
  87. C9F98D11 ED34DBF6 C6BA0B2C 8BBC27BE 6A00E0A0 B9C49708
  88. B3BF8A31 70918836 81286130 BC8985DB 1602E714 415D9330
  89. 278273C7 DE31EFDC 7310F712 1FD5A074 15987D9A DC0A486D
  90. CDF93ACC 44328387 315D75E1 98C641A4 80CD86A1 B9E587E8
  91. BE60E69C C928B2B9 C52172E4 13042E9B 23F10B0E 16E79763
  92. C9B53DCF 4BA80A29 E3FB73C1 6B8E75B9 7EF363E2 FFA31F71
  93. CF9DE538 4E71B81C 0AC4DFFE 0C10E64F
  94. """)
  95. g = DiffieHellman._decode_hex_string("""
  96. AC4032EF 4F2D9AE3 9DF30B5C 8FFDAC50 6CDEBE7B 89998CAF
  97. 74866A08 CFE4FFE3 A6824A4E 10B9A6F0 DD921F01 A70C4AFA
  98. AB739D77 00C29F52 C57DB17C 620A8652 BE5E9001 A8D66AD7
  99. C1766910 1999024A F4D02727 5AC1348B B8A762D0 521BC98A
  100. E2471504 22EA1ED4 09939D54 DA7460CD B5F6C6B2 50717CBE
  101. F180EB34 118E98D1 19529A45 D6F83456 6E3025E3 16A330EF
  102. BB77A86F 0C1AB15B 051AE3D4 28C8F8AC B70A8137 150B8EEB
  103. 10E183ED D19963DD D9E263E4 770589EF 6AA21E7F 5F2FF381
  104. B539CCE3 409D13CD 566AFBB4 8D6C0191 81E1BCFE 94B30269
  105. EDFE72FE 9B6AA4BD 7B5A0F1C 71CFFF4C 19C418E1 F6EC0179
  106. 81BC087F 2A7065B3 84B890D3 191F2BFA
  107. """)
  108. return p, g
  109. @staticmethod
  110. def _additional_group_2048_256():
  111. """
  112. from RFC 5114, has 256 bits subgroup size:
  113. 0x8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3
  114. refer to https://tools.ietf.org/html/rfc5114
  115. """
  116. p = DiffieHellman._decode_hex_string("""
  117. 87A8E61D B4B6663C FFBBD19C 65195999 8CEEF608 660DD0F2
  118. 5D2CEED4 435E3B00 E00DF8F1 D61957D4 FAF7DF45 61B2AA30
  119. 16C3D911 34096FAA 3BF4296D 830E9A7C 209E0C64 97517ABD
  120. 5A8A9D30 6BCF67ED 91F9E672 5B4758C0 22E0B1EF 4275BF7B
  121. 6C5BFC11 D45F9088 B941F54E B1E59BB8 BC39A0BF 12307F5C
  122. 4FDB70C5 81B23F76 B63ACAE1 CAA6B790 2D525267 35488A0E
  123. F13C6D9A 51BFA4AB 3AD83477 96524D8E F6A167B5 A41825D9
  124. 67E144E5 14056425 1CCACB83 E6B486F6 B3CA3F79 71506026
  125. C0B857F6 89962856 DED4010A BD0BE621 C3A3960A 54E710C3
  126. 75F26375 D7014103 A4B54330 C198AF12 6116D227 6E11715F
  127. 693877FA D7EF09CA DB094AE9 1E1A1597
  128. """)
  129. g = DiffieHellman._decode_hex_string("""
  130. 3FB32C9B 73134D0B 2E775066 60EDBD48 4CA7B18F 21EF2054
  131. 07F4793A 1A0BA125 10DBC150 77BE463F FF4FED4A AC0BB555
  132. BE3A6C1B 0C6B47B1 BC3773BF 7E8C6F62 901228F8 C28CBB18
  133. A55AE313 41000A65 0196F931 C77A57F2 DDF463E5 E9EC144B
  134. 777DE62A AAB8A862 8AC376D2 82D6ED38 64E67982 428EBC83
  135. 1D14348F 6F2F9193 B5045AF2 767164E1 DFC967C1 FB3F2E55
  136. A4BD1BFF E83B9C80 D052B985 D182EA0A DB2A3B73 13D3FE14
  137. C8484B1E 052588B9 B7D2BBD2 DF016199 ECD06E15 57CD0915
  138. B3353BBB 64E0EC37 7FD02837 0DF92B52 C7891428 CDC67EB6
  139. 184B523D 1DB246C3 2F630784 90F00EF8 D647D148 D4795451
  140. 5E2327CF EF98C582 664B4C0F 6CC41659
  141. """)
  142. return p, g
  143. @staticmethod
  144. def _key_pair(num_bits=1024):
  145. available = {
  146. 768: [DiffieHellman._oakley_group_768_768],
  147. 1024: [DiffieHellman._oakley_group_1024_1024, DiffieHellman._additional_group_1024_160],
  148. 2048: [DiffieHellman._additional_group_2048_224, DiffieHellman._additional_group_2048_256]
  149. }
  150. assert num_bits in available,\
  151. "key pairs with specified size({0} bits) not found, please use one of {1}".format(
  152. num_bits, available.keys()
  153. )
  154. return random.choice(available[num_bits]).__call__()
  155. @staticmethod
  156. def key_pair(num_bits=1024, pair_name=None):
  157. """
  158. Generate a primitive root for a big prime number is really slow!
  159. Notice the fact that:
  160. 1. we don't need the generator to be a primitive element of the group
  161. but the one generates a large prime order.
  162. 2. There is no security issue with Diffie-Hellman if you reuse previously generated 𝑝 and 𝑔.
  163. We simply use key pairs from RFC 5114 and RFC 2409
  164. @:param pair_name: one of "additional_group_1024_160", "additional_group_2048_224",
  165. "additional_group_2048_256", "oakley_group_768_768", "oakley_group_1024_1024"
  166. use additional_group_1024_160 as default
  167. @:param num_bits: specify size of p
  168. @:return p, g, where p is a prime number, g is a generator
  169. """
  170. if pair_name is None:
  171. if num_bits:
  172. return DiffieHellman._key_pair(num_bits)
  173. else:
  174. return DiffieHellman._additional_group_1024_160()
  175. assert pair_name in {
  176. "additional_group_1024_160", "additional_group_2048_224", "additional_group_2048_256",
  177. "oakley_group_768_768", "oakley_group_1024_1024"
  178. }, "unsupported pair name: {0}".format(pair_name)
  179. if pair_name == "additional_group_1024_160":
  180. return DiffieHellman._additional_group_1024_160()
  181. if pair_name == "additional_group_2048_224":
  182. return DiffieHellman._additional_group_2048_224()
  183. if pair_name == "additional_group_2048_256":
  184. return DiffieHellman._additional_group_2048_256()
  185. if pair_name == "oakley_group_768_768":
  186. return DiffieHellman._oakley_group_768_768()
  187. if pair_name == "oakley_group_1024_1024":
  188. return DiffieHellman._oakley_group_1024_1024()
  189. # noinspection PyArgumentList
  190. @staticmethod
  191. def generate_secret(p, num_bits=1024):
  192. return mpz(random.SystemRandom().getrandbits(num_bits)) % p
  193. @staticmethod
  194. def encrypt(g, r, p):
  195. return gmpy2.powmod(g, r, p)
  196. @staticmethod
  197. def decrypt(gr, r, p):
  198. return gmpy2.powmod(gr, r, p)