零知识证明-公钥分发方案DH((六)

前言

椭圆曲线配对,是各种加密构造方法(包括 确定性阀值签名、zk-SNARKs以及相似的零知识证明)的关键元素之一。椭圆曲线配对(也叫"双线性映射")有了30年的应用历史,然而最近这些年才把它应用在密码学领域。配对带来了一种"加密乘法"的形式,这很大的拓展了椭圆曲线协议的应用范围。本文的目的是详细介绍椭圆曲线配对,并大致解释它的内部原理

先了解DH 协议

Diffie-Hellman协议

简称DH,是一种公钥分发方案,该协议允许双方通过交换窃听者可见的信息来建立共享秘密。

1:DH

Diffie-Hellman 算法是第一个公开密钥算法,早在 1976 年就发明了。其安全性源于在有限域上计算离散对数比计算指数更为困难。Diffie-Hellman 算法能够用于密钥分配 (A 和 B 能用它产生秘密密钥),但是它不能用于加密或解密消息。

数学原理很简单。首先,A 和 B 协商一个大的素数n 和g , g是模 n 的本原元。这两个整数不必是秘密的,故 A 和 B 可以通过即使是不安全的途径协商它们。它们可在一组用户中公用。

原根(也是循环群的生成元)(primitive root)的概念和性质
如果 a与 m互质,那么我们把满足 a^k^ ≡ 1 mod m 的最小正整数 k 称为 a的模 m 的阶
由欧拉定理 a^Φ(m)^ ≡ 1 mod m, a的模 m的阶一定是Φ(m)的因数
阶刚好等于Φ(m)的余数(同余类) 称为 模m的原根(注意1只是模2的原根,其他不是)

给定一个正整数n,如果存在一个正整数k,使得k的某个幂对n取模的结果依次不为0,并且最终结果循环出现所有取值为1,2,...,n-1,则称k为模n的原根。

n=3 简化剩余系(1,2)Φ(n) =2 阶为2 ,2 是模3的原根 k=2

2^0^ %3 =1 2^1^ %3 =2 2^2^ %3 =1 2^3^ %3 =2 2^4^ %3 =1 2^5^ %3 =2

n=5 简化剩余系{1,2,3,4} Φ(n) =2 阶为4

2^0^ %5= 1 -> 简写 (0,1) (1,2) (2,4) (3,3) (4,1) (5,2) (6,4)(7,3) 重复 1,2,4,3 这样重复

3^0^%5=1 -> 简写 (0,1) (1,3) (2,4) (3,2) (4,1) (5,3) (6,4)(7,2) 重复 1,3,4,2 这样重复

欧拉函数 对于任何一个正整数 n,定义 Φ(n) 为不超过 n 的与 n互质的正整数个数
模m原根存在的条件是 m=1,2,4,p^a^,2p^a^,其中 p为奇素数, a >=1
S是模 n的简化剩余系,是指 S是由 φ(n)个数组成的集合,其中集合中的数都与 n互质且两两模 n不同余(就是余数不重复)

eg: m=2 简化剩余系(1) Φ(n) =1 阶为1 ,1 是模2的原根

m=3 简化剩余系(1,2)Φ(n) =2 阶为2 ,2 是模3的原根 2^2^ %3 =1

m=4 简化剩余系(1,3)Φ(n) =2 阶为2,3 是模4的原根 3^2^ %4 =1

m=6 简化剩余系(1,5)Φ(n) =2 阶为2,5 是模6的原根 5^2^ %6 =1

m=5 简化剩余系{1,2,3,4} Φ(n) =2 阶为4, 2^4^ % 5 = 1 3^4^ %5 =1 4^2^%5=1

阶为4 ,所以 4不是原根,2 ,3 都是原根
总结 可逆元^Φ(n)^ mod m == 1 , 可逆元 是 模 m 的原根(注意1只是模2的原根,其他不是)

协议如下:

g n 是公开的 n 为大素数 g是n的原根

A 选取一个大的随机整数ra ,并发送给 B ; X=g^ra^ mod n

B 选取一个大的随机整数rb,并发送给 A Y=g^rb^ mod n

A 计算 S=Y^ra^ mod n

B计算 S=X^rb^ mod n

S 应该等于 g^ra*rb^ mod n

S 作为计算出的共享密钥,可用于对称加密

即使线路上的窃听者也不可能计算出这个值,他们只知道 n,g,X,Y 除非他们计算离散对数,恢复 ra,rb,否则无济于事。因此 S 是 A 和 B 独立计算的秘密密钥。

g和n 的选取对系统的安全性有很大的影响。(n-1)/2 也应该是一个素数。最重要的是 n应该很大:因为系统的安全性取决于与 n同样长度的数的因子分解的难度。可以选择任何满足模n 的原根g ,没有理由不选择所能选择的最小g ------ 通常只是个 1 位数 (实际上 g不必是素数,但它必须能产生一个大的模n 的乘法组子群)

eg: g=6 n=11 (g是n的原根) 11的原根有(2,6,7,8) 这里选择6

A 私钥ra =7 公开密钥 X= g^ra^ mod n = 6^7^ = 279936 %11= 8

B 私钥rrb = 12 公开密钥 Y = g^rb^ mod n = 6^12^ = 2176782336 %11 = 3

A 计算 共享密钥 S = Y^ra^ mod n = 3^7^ % 11 = 2187 %11 = 9

B 计算 共享密钥 S= X^rb^ mod n = 8^12^%11 = 68719476736%11 = 9

g^ra*rb^ mod n = 6 ^7*12^ = 6^84^ %11 = 9 == S

go 复制代码
package main

import (
	"fmt"
	"github.com/ethereum/go-ethereum/common/math"
	"math/big"
)

func main()  {
	valuea ,power,mod := 0,0,0
	//89 ^2011 %3127
	for ;; {

		fmt.Printf("please input value1, power and mod:")
		if _,err := fmt.Scan(&valuea,&power,&mod);err !=nil{
			fmt.Printf("input error")
			break

		}
		a := int64(valuea)
		b := int64(power)
		big1 := math.BigPow(a,b)
		m := big.NewInt(int64(mod))
	//	z := big.NewInt(0)
		big2 := m.Mod(big1,m)

		fmt.Printf("(%v ^ %v)mod %v = %v (%v)\n",valuea,power,mod,big2,big1)
	}

	fmt.Printf("ready exit \n")
}

2:三方或多方 Diffie-Hellman

以三方为例

g n 公开

1> A 私钥 选择大随机数 ra 把 X = g^ra^ mod n 发送给 B

2> B 私钥 选择大随机数 rb 把 Y = g^rb^ mod n 发送给 C

3> C 私钥 选择大随机数 rc 把 Z = g^rc^ mod n 发送给 A

4> A 把 Z1 = Z^ra^ mod n 发送给 B ,( Z 为 C 发送给A的)

5> B 把 X1 = X^rb^ mod n 发送给 C (X 为 A 发送给B的)

6> C 把 Y1 = Y^rc^ mod n 发送给 A (Y 为 B发送给C的)

7> A 计算共享密钥 S = (Y1^)ra^ mod n

8> B 计算共享密钥 S = (Z1^)rb^ mod n

9>C 计算共享密钥 S = (x1^)rc^ mod n

S == g^ra*rb*rc^ mod n

eg: g=8 n=11 (g是n的原根) 11的原根有(2,6,7,8) 这里选择6

1> A 私钥 ra = 13 X= g^ra^ mod n = 8^13^ mod 11 = 549755813888 %11 = 6

2>B 私钥 rb = 16 Y= g^rb^ mod n = 8^16^ mod 11 = 281474976710656 %11 = 3

3>C 私钥 rc = 27 Z= g^rc^ mod n = 8^27^ mod 11 = 2417851639229258349412352%11 = 2

4>A Z1 = Z^ra^ mod n = 2^13^ %11 = 8192%11 =8

5>B X1 = X^rb^ mod n = 6^16^ %11 = 2821109907456%11 = 5

6>C Y1 = Y^rc^ mod n = 3^27^ %11 = 7625597484987%11 = 9

7> A S= Y1^ra^ mod n = 9^13^ % 11 = 2541865828329 %11 = 3 //跟B 给C的Y 相等, 因为n太小,碰撞到一起了

8> B S= Z1^rb^ mod n = 8^16^ % 11 = 281474976710656%11 = 3

8> C S= X1^rc^ mod n = 5^27^ % 11 = 7450580596923828125%11 = 3

g^ra*rb*rc^ mod n = 8^13*16*27^ % 11 = 8^5616^ % 11 = 3

8^5616^= 用上面的程序计算 =

(56671792158458189462788480435325250053000506492933346240406207383911706480845603129490692058630716611中间省略69124622157307694933662452678656)

DH 需要防止中间人攻击

如果觉得有用,麻烦点个赞,加个收藏

相关推荐
励志成为嵌入式工程师40 分钟前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉1 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer1 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
wheeldown2 小时前
【数据结构】选择排序
数据结构·算法·排序算法
观音山保我别报错3 小时前
C语言扫雷小游戏
c语言·开发语言·算法
TangKenny4 小时前
计算网络信号
java·算法·华为
景鹤4 小时前
【算法】递归+深搜:814.二叉树剪枝
算法
iiFrankie4 小时前
SCNU习题 总结与复习
算法
Dola_Pan5 小时前
C++算法和竞赛:哈希算法、动态规划DP算法、贪心算法、博弈算法
c++·算法·哈希算法
小林熬夜学编程5 小时前
【Linux系统编程】第四十一弹---线程深度解析:从地址空间到多线程实践
linux·c语言·开发语言·c++·算法