拜占庭将军问题之签名算法(二)

时间:2024-04-12 07:01:14

拜占庭将军问题的第一个解法是口头协议,在之前的文章中已经有详细的举例说明,这次我们来看下另一个解法,签名协议(signed message algorithm)。这个算法可以在不管有多少叛军的情况下,都能让忠诚的将军们保持一致的行动,没有口头协议算法那个n>3m+1的限制。


回顾下口头协议的几个假设条件:

A1. 军队中的通讯兵完全可以相信,所有的消息都能被正确的发送;

A2. 收到消息的人知道消息是谁发出来的;

A3. 缺少的消息能被察觉出来;(这里,如果叛军不配合发送消息,算法默认一个值“撤退”的来替代);

签名协议算法增加了2条:

A4.1 忠诚的将军的签名不能被篡改,签名的内容一旦有人篡改了就能被发现;

A4.2 任何人都能验证将军签名的可靠性;

这里注意下,叛军的签名是可以被篡改的,叛军A也可以篡改叛军B的签名。

SM(m)算法的一个表达特点先说明下,比如x:i的意思是值x是被将军i签名过的, v:j:i意味着值v被将军j签名过,然后将军i再签名一次v:j,同时约定v:0即来自司令官的命令。


算法具体如下 SM(m):

初始化Vi=∅ (空集)

1. 司令官发送已经签名的信息给所有其他将军;

2.对于每个将军 i 来说:

a. 如果将军 i 是第一次收到消息,即收到的是司令官v:0的消息,那么将军 i 的Vi ={v},同时将军i发送v:0:i给其他将军;

b. 如果将军 i 收到的是将军 k 的消息(即v:0:1...k), 1<= k <= m, 意味着已经不是第一次收到消息,这时如果收到的Vk值与Vi不同,把Vk值加入到Vi的集合中, 但k<m时,将军i继续把收到的这条消息签名(v:0:1...k:i)后发送给其他不在i...k中的将军;

3. 在第m轮消息发送后,每个将军i使用Choice(Vi)函数获得一致的行动;

算法解析:

1.  这个算法要求m+1轮信息互换;

2. 在第2步中,入股将军 i 收到的Vk与已经在集合中的Vi相同,自动忽略;

3. Choice(Vi)函数即每个忠诚的将军都知道规则的函数,由于SM(m)算法完成后每个将军获得的{V}都是相同的,所以每个忠诚的将军都能根据同样的规则计算出函数值;


举例说明,n=4, m=2并且司令官是叛军的情况,也就是口头协议无法解的情况:

拜占庭将军问题之签名算法(二)

通过SM(m)算法,将军A最终的Va={x:0,y:0:b,z:0:x, z:0:c:b}= {x,y,z}, 将军B最终的Vb={y:0,x:0:a,z:0:c,z:0:c:a}={y,x,z}, Choice()得出来的将军A和B的结果肯定是一样的。

证明过程还是看大神文章: https://www.microsoft.com/en-us/research/uploads/prod/2016/12/The-Byzantine-Generals.pdf 

至此, Leslie Lamport等人提出的2种拜占庭将军问题解法已经了解清楚,那么,既然SM(m)算法的结论如此好用,问题是不是就此解决了呢?  答案是没这么简单,由于解法中的4个假设条件中有几个在现实中很难满足:

1. 如果传送信息过程的时间太长,A3假设就很难满足,需要考虑超时场景;

2. 假设A4.2, 每个将军都能验证签名是否可靠的话,签名的系统还是需要一个中心化的认证机构支持;

据说工作量证明(proof of work)提供了另外的思路,后续再研究吧。