Diffie-Hellman密钥交换算法简介
两张图不废话。
原根部分理解
原根性质
简单理解,以原根a为底数时,i从1到p-1,生成 (m=p),bi会是1到p-1的集合只是乱序。
找原根
对于小于m的正整数,满足上面所说性质的可以做原根。
循环群构造
现选取p为素数89,查表计算等方式得知6是其原根,即将6作为底。
A随机选个数作为私钥,如20,攻击者E想要知道私钥
现在A选X=20,生成85发出
E只知道85,拿85继续算,生成11,
再拿11算,生成的再算,
..........
最终拿20算出85,得出20是X
[20, 85, 82, 49, 56, 45, 83, 27, 54, 68, 22, 34, 72, 32, 2, 36, 11, 37, 66, 55, 52, 81, 23, 26, 9, 48, 39, 62, 10, 21, 65, 24, 67, 63, 60, 25, 46, 53, 41, 7, 31, 30, 5, 33, 12, 44, 88, 1, 6, 20, 85]
共进行40多次该过程,这还是素数为89的情况下,若素数稍微大些就无法算了。
在【20, 85, 82, 49, 56, 45, 83, 27, 54, 68, 22, 34, 72, 32, 2, 36, 11, 37, 66, 55, 52, 81, 23, 26, 9, 48, 39, 62, 10, 21, 65, 24, 67, 63, 60, 25, 46, 53, 41, 7, 31, 30, 5, 33, 12, 44, 88, 1, 6】中的数是从前往后依次生成的,该过程不能直接逆推(无规律且穷举无意义),必须通过大量计算递推,就算有优化也一样。若用大素数生成,A,B从中任选两个作为私钥生成公钥发出后无所畏惧。
其他例子 p=71,原根a=7
[20, 37, 22, 38, 12, 4, 58, 18, 8, 27, 21, 46, 40, 20, 37, 22, 38, 12, 4, 58, 18, 8, 27, 21, 46, 40, 20, 37, 22, 38]
实现代码
# 求原根
import math
def find_primitive_roots(n):
# Function to find order of an integer 'a' modulo 'n'
def order(a, n):
for i in range(1, n):
if pow(a, i, n) == 1:
return i
return n
# Function to check if 'g' is a primitive root modulo 'n'
def is_primitive_root(g, n):
return order(g, n) == n - 1
# Check for each number if it is a primitive root
roots = []
for i in range(1, n):
if math.gcd(i, n) == 1: # 'g' must be coprime to 'n'
if is_primitive_root(i, n):
roots.append(i)
return roots
# Find all primitive roots of gg
gg=71
primitive_roots_23 = find_primitive_roots(gg)
print(primitive_roots_23)
# 生成循环群
zz=[20]
for i in range(50):
# 前50个里看看
zz+=[7**zz[i] %gg]
print(zz)