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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
| import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;
import java.util.stream.Collectors;
import javax.crypto.Cipher;
class SignatureEntry {
private int signerId;
private String signature;
public SignatureEntry(int signerId, String signature) {
this.signerId = signerId;
this.signature = signature;
}
public int getSignerId() { return signerId; }
public String getSignature() { return signature; }
}
class SignedMessage {
private int value;
private int senderId;
private List<SignatureEntry> signatureChain;
public SignedMessage(int value, int senderId) {
this.value = value;
this.senderId = senderId;
this.signatureChain = new ArrayList<>();
}
public SignedMessage(int value, int senderId, List<SignatureEntry> chain) {
this.value = value;
this.senderId = senderId;
this.signatureChain = new ArrayList<>(chain);
}
/**
* 为消息添加数字签名
*/
public SignedMessage sign(PrivateKey privateKey, int signerId) throws Exception {
// 创建消息摘要
String messageData = String.format("{value:%d,senderId:%d,chainSize:%d}",
value, senderId, signatureChain.size());
// 生成签名
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(messageData.getBytes());
byte[] signatureBytes = signature.sign();
// 添加到签名链
signatureChain.add(new SignatureEntry(signerId,
Base64.getEncoder().encodeToString(signatureBytes)));
return this;
}
public int getValue() { return value; }
public int getSenderId() { return senderId; }
public List<SignatureEntry> getSignatureChain() { return signatureChain; }
}
public class ByzantineGeneralsSM {
private int n;
private int f;
private Map<Integer, KeyPair> keyPairs;
private Set<Integer> byzantineNodes;
public ByzantineGeneralsSM(int n, int f) throws Exception {
this.n = n;
this.f = f;
this.byzantineNodes = new HashSet<>();
generateKeys();
}
/**
* 为每个节点生成公私钥对
*/
private void generateKeys() throws Exception {
keyPairs = new HashMap<>();
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
for (int i = 0; i < n; i++) {
KeyPair keyPair = keyGen.generateKeyPair();
keyPairs.put(i, keyPair);
}
}
/**
* SM算法实现
*/
public Map<Integer, Integer> signedMessageAlgorithm(int commanderValue, int commanderId)
throws Exception {
// 第一阶段:指挥官签名并广播
SignedMessage initialMessage = new SignedMessage(commanderValue, commanderId);
initialMessage.sign(keyPairs.get(commanderId).getPrivate(), commanderId);
// 模拟消息传播
Map<Integer, List<SignedMessage>> nodeMessages = new HashMap<>();
for (int i = 0; i < n; i++) {
nodeMessages.put(i, new ArrayList<>());
}
// 指挥官向所有节点发送签名消息
for (int i = 0; i < n; i++) {
if (i != commanderId) {
nodeMessages.get(i).add(initialMessage);
}
}
// 多轮转发和签名
for (int round = 0; round < f; round++) {
Map<Integer, List<SignedMessage>> newMessages = new HashMap<>();
for (int i = 0; i < n; i++) {
newMessages.put(i, new ArrayList<>());
}
for (int nodeId = 0; nodeId < n; nodeId++) {
if (nodeId == commanderId || isByzantine(nodeId)) {
continue;
}
// 诚实节点转发收到的消息
for (SignedMessage msg : nodeMessages.get(nodeId)) {
if (msg.getSignatureChain().size() <= f) {
// 添加自己的签名并转发
SignedMessage forwardedMsg = new SignedMessage(
msg.getValue(), msg.getSenderId(), msg.getSignatureChain());
forwardedMsg.sign(keyPairs.get(nodeId).getPrivate(), nodeId);
// 发送给其他节点
Set<Integer> signerIds = msg.getSignatureChain().stream()
.map(SignatureEntry::getSignerId)
.collect(Collectors.toSet());
for (int targetId = 0; targetId < n; targetId++) {
if (targetId != nodeId && !signerIds.contains(targetId)) {
newMessages.get(targetId).add(forwardedMsg);
}
}
}
}
}
// 更新消息集合
for (int nodeId = 0; nodeId < n; nodeId++) {
nodeMessages.get(nodeId).addAll(newMessages.get(nodeId));
}
}
// 决策阶段
Map<Integer, Integer> decisions = new HashMap<>();
for (int nodeId = 0; nodeId < n; nodeId++) {
if (!isByzantine(nodeId)) {
decisions.put(nodeId, makeDecision(nodeMessages.get(nodeId)));
}
}
return decisions;
}
/**
* 验证签名链的有效性
*/
private boolean verifySignatureChain(SignedMessage message) {
// 简化实现,实际中需要完整的签名验证
Set<Integer> signerIds = message.getSignatureChain().stream()
.map(SignatureEntry::getSignerId)
.collect(Collectors.toSet());
return signerIds.size() >= f + 1;
}
/**
* 基于收到的消息做出决策
*/
private Integer makeDecision(List<SignedMessage> messages) {
List<SignedMessage> validMessages = messages.stream()
.filter(this::verifySignatureChain)
.collect(Collectors.toList());
if (validMessages.isEmpty()) {
return null; // 默认值
}
// 选择具有最多有效签名的值
Map<Integer, Integer> valueCounts = new HashMap<>();
for (SignedMessage msg : validMessages) {
int value = msg.getValue();
int weight = msg.getSignatureChain().size();
valueCounts.put(value, valueCounts.getOrDefault(value, 0) + weight);
}
return valueCounts.entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElse(null);
}
/**
* 检查是否为拜占庭节点
*/
private boolean isByzantine(int nodeId) {
return byzantineNodes.contains(nodeId);
}
public void setByzantineNodes(Set<Integer> nodes) {
this.byzantineNodes = nodes;
}
// 使用示例
public static void main(String[] args) throws Exception {
ByzantineGeneralsSM bgSm = new ByzantineGeneralsSM(4, 1);
bgSm.setByzantineNodes(Set.of(3));
Map<Integer, Integer> decisions = bgSm.signedMessageAlgorithm(1, 0);
System.out.println("各节点决策结果: " + decisions);
}
}
|