ECC-ElGamal

本文最后更新于:2024年7月21日 下午

以下是 ECC-ElGamal 的算法原理:

公共参数

1.G:椭圆曲线基点

2.SK:私钥,SK=d

(d 是 0 到椭圆曲线的阶 q 之间的随机数)

3.PK:公钥,PK=dG

加密

1.明文 m,随机数 r

2.计算密文 C

img

(3)明文 m 的取值范围为模 order(G) 的模空间,但实际使用时 m 需限制为较小的数(例如 32 比特长度),否则椭圆曲线离散对数问题(ECDLP)无法求解。

解密
1.计算 rPK

img

2.计算 mG

img

3.计算 mG 的 ECDLP,获得明文 m。

密文加法、密文减法

1.两个密文

img

2**.密文加**:

对 2 个密文的 2 个 ECC 点分别做点加,共 2 个点加,公式如下:

img

3.密文减

对 2 个密文的 2 个 ECC 点分别做点减,共 2 个点减,公式如下:

img

img

密文标量乘法

1.密文

img

2.对密文的 2 个 ECC 点分别用 _2 做点乘,共 2 个点乘,公式如下:

img

3.如上公式与明文m2m1的同态加密结果一致:

img

这里 r=m2r1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
class Pare {
long x;
long y;

public Pare() {
super();
}

public Pare(long x, long y) {
super();

this.x = x;
this.y = y;
}

//加法
public Pare add(Pare pare) {
if (this.x == Integer.MAX_VALUE) {//为无穷大时O+P=P
return pare;
}
Pare res = new Pare();
if (this.y == pare.y && this.x == pare.x) {//相等时
long d = moddivision(3 * this.x * this.x + EccUtil.e.a, EccUtil.e.p, 2 * this.y);

res.x = d * d - 2 * this.x;
res.x = mod(res.x, EccUtil.e.p);

res.y = d * (this.x - res.x) - this.y;
res.y = mod(res.y, EccUtil.e.p);
} else if (pare.x - this.x != 0) {
long d = moddivision(pare.y - this.y, EccUtil.e.p, pare.x - this.x);
res.x = d * d - this.x - pare.x;
res.x = mod(res.x, EccUtil.e.p);

res.y = d * (this.x - res.x) - this.y;
res.y = mod(res.y, EccUtil.e.p);
} else {//P Q互逆,返回无穷大
res.x = Integer.MAX_VALUE;
res.y = Integer.MAX_VALUE;
}

return res;
}

//减法
public Pare less(Pare p) {
p.y *= -1;
return add(p);
}

//乘法
public Pare multiply(long num) {
Pare p = new Pare(this.x, this.y);
for (long i = 1; i < num; i++) {
p = p.add(this);
}
return p;
}

//求余,解决负号问题
public long mod(long a, long b) {
a = a % b;
while (a < 0) {
a += b;
}
return a;
}

//求余取商(a mod b)/c
/*public long moddivision(long a, long b, long c) {
a = mod(a,b);
while(a%c != 0) {
a += b;
}
a = a/c;
return a;
}*/
public long moddivision(long a, long b, long c) {
a = mod(a, b);
c = mod(c, b);
a = a * EccMath.exgcd(c, b);
return mod(a, b);
}

@Override
public String toString() {
return EccTools.obox(EccTools.long2hexStr(this.x), 4) + " " + EccTools.obox(EccTools.long2hexStr(this.y), 4);
}
}

//加密
public Message encryption(Pare g, Pare pbk, Pare word) {
pbk = g.multiply(privatekey);//公钥
int d = new Random().nextInt(1024);//随机数
Pare dg = g.multiply(d);
Pare dp = pbk.multiply(d);
Pare send = word.add(dp);
return new Message(dg, send);
}

//解密
public Pare decryption(Message m) {
Pare pab = m.pa.multiply(this.privatekey);
Pare result = m.pb.less(pab);
return result;
}


jpg202405251725582.webp


ECC-ElGamal
https://forever0823.github.io/2024/05/25/ECC_EIGamal/
作者
Alan
发布于
2024年5月25日
许可协议