分布式系统

分布式理论(1):The Byzantine General Problem(译)

2011年3月6日 阅读(1,843)

       作者:LESLIE LAMPORT, ROBERT SHOSTAK, and MARSHALL 1982

译者:phylips@bmy 

出处:http://duanple.blog.163.com/blog/static/7097176720112643946178/

[序:我一直觉得正是因为通过用一组围坐在圆桌旁的哲学家来表述,Dijkstra 的哲学家就餐问题才变得如此让人关注。(比如在理论界,它可能比读者/写者问题都引人注目,尽管读者/写者问题可能更具实际意义),我认为<<Reaching Agreement in the Presence of Faults >>所描述的问题十分重要,值得计算机科学家们去关注。哲学家就餐问题使我认识到,把问题以讲故事的形式表达出来更能引起人们的关注。

在分布式计算领域有一个被称作中国将军问题的问题。在这个问题中,两个将军必须在进攻还是撤退上达成一致,但是相互只能通过信使传送消息,而且这个信使可能永远都无法到达。我借用了这里的将军的叫法,并把它扩展成一组将军,同时这些将军中有的是叛徒,他们需要达成一致的决定。同时我想给这些将军赋予一个国家,同时不能得罪任何读者。那时候,阿尔巴尼亚还是一个完全封闭的国家,所以我觉得应该不会有阿尔巴尼亚人看到这篇文章,所以最初的时候这篇论文题目实际是The Albanian Generals Problem。但是Jack Goldberg后来提醒我在这个世界上阿尔巴尼亚之外还有很多阿尔巴尼亚移民,所以建议我换个名字。于是就想到了这个更合适的Byzantine generals的叫法。

写这篇论文的主要目的是将Byzantine generals这个叫法用在这个问题上。但是一篇新的论文需要有新的想法,于是提出了一种描述通用的3n+1处理单元的算法简单方式(Shostak的4处理单元算法很精妙而且容易理解,但是Pease的通用化扩展算法却不那么好懂)。同时我们将网络扩展到非全互联网络的情况,而且增加了一些实现相关的细节。

 {!本部分摘自Lamport的my writings,my writings是Lamport本人对自己以往发表的论文的一些总结,其中很多文字涉及到这些论文的创作来源。从上面的文字可以看出,该论文的内容实际上已发表在1980年的<<Reaching Agreement in the Presence of Faults>>中,只是引入了拜占庭将军这一说法,同时增加了一些新的内容。。}]

 一个可靠的计算机系统必须处理有故障的组件,这些组件可能引入与系统其它部分相冲突的信息。这样的场景可以用一组指挥军队围困敌国城市的拜占庭将军来描述。将军之间只能通过信使传递信息,他们必须在相同的作战方案上达成一致。但是,他们之中可能存在叛徒,这些叛变的将军会竭力的扰乱其它人。拜占庭将军问题,就是指找到一种算法可以保证那些忠诚的将军可以达成一致。结果表明,如果使用口头信息,当且仅当超过三分之二的将军是忠诚的时候该问题才可解,也就是说一个将军可以扰乱两个将军。如果使用不可伪造的书面信息,对于任何数目的将军和叛徒,该问题都是可解的。此外,本文还讨论了如何将该问题的解应用于可靠的计算机系统实现中。

 1.   导引

 一个可靠的计算机系统必须能够处理一个或多个的组件的失败。一个失败的组件可能会表现出一种经常被忽略的行为:向系统的其他部分发送相矛盾的信息。可以将处理这种失败的情况的问题抽象出来,就是这里的拜占庭将军问题。我们在论文的绝大部分内容都是讨论这个抽象后的问题,只是在末尾会讨论如何将该问题的解应用在可靠计算机系统的实现中。

 假设有几股拜占庭军队现在正在一个敌城外扎营,每股军队由一个将军指挥。将军之间只能通过信使通信。观察完敌情后,他们必须达成一个相同的行动计划。然而,有些将军可能是叛徒,他们会尽力阻止那些忠诚的将军达成一致。将军们必须有一个算法来保证如下条件:

 A.      所有忠诚的将军必须达成相同的行动计划。

 忠诚的将军将会做该算法要求他们做的事情,但是叛变的将军可以做任何他们想做的事情。无论叛变的将军会做什么,算法必须要保证条件A。

 诚实的将军不能仅仅达成一致,他们还应该达成一个合理的行动计划。也就是说,实际上我们想保证:

 B.      当只有少数人是叛徒的时候,他们不能导致那些诚实的将军们采纳一个糟糕的计划。

 条件B很难去形式化,因为它需要精确的定义何谓糟糕的计划,当然我们也并不尝试去给出这样的一个定义。我们来考虑将军们如何做出决定,每个将军都会观察敌情,并将他的观察结果告诉其他将军。假设v(i)代表第i个将军发送的信息。每个将军使用某种方法来根据这些信息v(1),v(2)……v(n)来拟定作战计划(n代表将军的总数)。通过让所有的将军使用同一种方法就可以满足条件A,通过使用一种健壮的方法条件B也可以满足。比如,现在需要决定是进攻还是撤退,v(i)代表第i个将军关于进攻还是撤退的意见,最终的决定可以通过在他们之间进行一个多数决的投票来决定。在这种情况下,只有当持两种意见的忠诚将军数目几乎相同时,少数的叛变将军才能影响最终的结果。但是这种情况下,无论是进攻还是撤退都算不上是糟糕的方案{!这就说明满足条件B}。

 虽然这种策略可能不是满足条件A和B的唯一一种方式,但是目前我们仅想到这一个。该方法假设存在一种方法,将军们可以相互传递各自的v(i)值。很明显的一种方法是,将军i,让他的信使将v(i)送给所有的将军。但是,这样行不通,因为如果要满足条件A,需要每个忠诚的将军收到相同的v(1),v(2)……v(n),但是一个叛变的将军可能会给不同的将军发送不同的值。对于条件A来说,如果要满足下面的条件必须成立:

 

1.      每个忠诚的将军必须收到相同的v(1),v(2)……v(n)

 

条件1暗示一个将军并没有必要使用一个直接从第i个将军那收到的v(i)值,因为一个叛变的第i将军可能给不同的将军发送不同的v(i)值。但是这样意味着,满足条件1的同时,很可能一不小心就使用了一个与第i将军发送的v(i)不同的值,即使第i个将军是诚实的{!因为我们可能采用了从其他将军处得来的关于v(i)的值,但是这个将军可能是叛变者,它可能自己已经改变了v(i)的值,这样即使第i将军是诚实的,但是经过叛变者之后它的值也已不再受控了}。但是为了满足条件B,我们绝不允许这种情况发生。比如我们,我们不能允许少数的叛变者就使得忠诚的将军们在一个个”retreat”, ”retreat”…… ”retreat”,中做决定,而每个忠诚的将军发送的明明是”attack”。因此,我们还要为每个i增加如下的需求:

 

2.      如果第i个将军是忠诚的,那么其他的忠诚的将军必须使用他发送的值作为v(i)的值。

 

我们可以改写条件1,使得它是针对任意i的条件(无论第i个将军是否是忠诚的):

 

1’. 任意两个忠诚的将军使用相同的v(i)值

 

条件1’.和2现在都是针对第i个将军的值v(i)的了。因此,我们可以只考虑一个将军如何发送他的值给其他人。现在我们用一个发令将军向它的下属发送命令的形式来重新描述这个问题,就得到如下问题:

 

拜占庭将军问题。一个发令将军向他的n-1个下属将军发送命令,使得:

 

IC1.所有忠诚的下属都遵守相同的命令

IC2.如果发令将军是忠诚的,那么每个忠诚的下属必须遵守他发出的命令。

 

条件IC1和IC2被称为交互一致性(interactive consistency)条件。可以看到,当发令将军是忠诚的时候,IC1可以由IC2导出。然而,发令将军不一定是忠诚的。

 

为了解决最初的问题,第i个将军只需要利用拜占庭将军问题的解法发送命令”使用v(i)作为我的值”,就可以将他的值v(i)发送给其他的将军。此时其他的将军就扮演拜占庭将军问题中的下属的角色。

 

2.   不可能性

 

拜占庭将军问题看似很简单。它的难解之处是通过一个令人惊讶的事实而体现出来的:如果将军们只能发送口头消息,除非有超过三分之二的将军是忠诚的,否则该问题无解。尤其是,如果只有三个将军,其中一个是叛变者,那么此时无解。口头消息是指信息的内容完全在发送者控制之下,这样一个叛变了的发送者可能会传送任何可能的消息。正常情况下计算机之间传输的消息就属于这种类型。在第4节,我们会考虑签名的,书面消息,对于这种类型该结论不成立。

我们现在来说明使用口头消息,当三个将军中有一个叛变时是无解的。为了简单起见,我们只考虑是”进攻”还是”撤退”这一简单的决定的情况。首先看图1里的情形,发令者是忠诚的并且发送了一个”进攻”命令。但是下属2是个叛变者,他对下属1说,他收到了一个”撤退”命令。如果要保证IC2满足,将军1必须遵守命令去进攻。

现在考虑图2所展示的另一种情形,发令者是一个叛变的将军,发送了一个“进攻”命令给下属1,但是给2发送的是“撤退”命令。下属1,不知道谁是叛变者,同时他也无法判断发令者发送给下属2的真实的命令到底是什么。因此,这两幅图中的情形,对于1来说是完全相同的{!他不知道谁是叛变者,两种情况下他都是只知道发令者告诉他要进攻,但是2说发令者说要撤退。所以他无法区分出这两种情形,但是如果是情形1,他必须进攻,如果是情形2他如果也进攻,那就是说无论如何他都听发令者的命令,如果选定了这1算法,因为1,2本质上是等价的角色,那么2也需要采纳该算法,这样2就会选择撤退,这就违发了IC1。如果他选择撤退,那么意味着他要区分这两种情况,但是实际它是无法区分的,因此无解。}。如果叛变者总是在说谎的话,对于1来说就无法区分这两种情况,因此他就必须选择遵守进攻命令,因此无论何时,下属1从发令者那收到进攻命令,他都必须遵守它。

 

然而,类似的结论也指出{!进攻与撤退不过是两个称谓,将2者互换一下就可以得出结论},如果下属2从发令者那收到了撤退命令,他都必须要遵守,即使1告诉他发令者的命令是进攻。因此对于图2的情形来说,2必须遵守撤退命令,而1必须遵守进攻命令,因此违法了条件IC1。因此三个将军中有一个是叛变者时,该问题无解。

 

这个结论可能看起来很令人信服,但是我们仍然强烈的建议读者对这种非严格的推理保持怀疑态度。尽管该结论实际上也是正确的,但是我们也碰到过对一些错误结论的类似这样的似是而非的证明。在计算机科学和数学领域中,非严格的证明在对这种类型的算法研究中最有可能导致错误了。对于该问题的严格证明可以参考【3】。

 

利用这个结论,我们可以说明当有m个叛徒,而将军数小于3m+1时,该问题无解。证明采用反证法:我们假设当将军数小于等于3m时存在一个解,然后用它来构造一个3将军1叛徒的拜占庭将军问题解。为了避免这两个算法的混淆,我们将假设解中的将军们叫做阿尔巴尼亚将军,构造解中的将军叫做拜占庭将军。因此,下面我们从一个允许有m个叛徒,但阿尔巴尼亚将军小于等于3m的算法开始,我们来构造一个3将军1叛徒的拜占庭将军问题的解。

 

这个3将军解,是通过让每个拜占庭将军来模拟1/3的阿尔巴尼亚将军们来得到的,这样每个拜占庭将军最多模拟m个阿尔巴尼亚将军。拜占庭的发令将军来模拟阿尔巴尼亚发令将军以及最多m-1个阿尔巴尼亚下属将军。两个拜占庭下属将军模拟最多m个阿尔巴尼亚下属将军。由于只有一个拜占庭将军是叛徒,而且他最多可以模拟m个阿尔巴尼亚将军,而最多只有m个阿尔巴尼亚将军是叛徒。因此,假设解可以确保IC1和IC2对于阿尔巴尼亚将军是成立的。根据IC1,被一个忠诚的拜占庭下属将军模拟的阿尔巴尼亚下属将军都遵守相同的命令,这个命令也是他应该遵守的那个命令。很容易看出阿尔巴尼亚将军解的条件IC1和IC2也隐含着拜占庭将军的相应条件,这样我们就构造出了那个不可能的解。{!?模拟属于外部行为,也就是说将军之间不知道谁是叛徒,但是我们在模拟的时候,可以知道这些情况,而让叛变的那个拜占庭将军模拟叛变的那些阿尔巴尼亚将军,然后把拜占庭将军放到阿尔巴尼亚将军的执行环境中,他们一人扮演多个将军,执行阿尔巴尼亚将军解的算法,阿尔巴尼亚将军之间可以保证IC1和IC2这两个条件,而拜占庭将军只需要遵守他所扮演的将军们所遵守的那些命令,就达到了他自己的IC1和IC2条件}

 

可能有人认为解决拜占庭将军问题的难点在于它要求达到精确的一致。下面我们通过证明近似一致实际与精确一致一样困难来说明情况并不是这样。我们现在假设不是要达到一个精确的战斗计划,将军们只需要达成近似的进攻时间。详细来说,我们假设发令者需要确定进攻时间,同时需要满足如下两个条件:

 

IC1’.所有的忠诚的下属相互之间在10分钟内发起进攻

IC2’.如果发令将军是忠诚的,所有的忠诚的下属在发令者给定的命令时间点的10分钟之内发起进攻。

 

(我们假设命令是在进攻的前一天下达并被处理的,而且与命令的接收时间无关,只需要关注命令中给定的进攻时间)

 

类似于拜占庭将军问题,这个问题只有在超过三分之二的将军是忠诚的时候才有解。我们通过表明这样的一个事实来证明它:如果存在这个问题的一个三将军解,我们可以通过这个解构造出拜占庭将军问题的一个三将军解。假设发令者希望发送一个进攻或者撤退命令。他会使用假设的那个算法,通过发送一个在1:00进行攻击的命令来作为进攻命令,通过发送在2:00进行攻击的命令作为撤退命令。每个下属使用下面的过程来获取命令:

 

(1)   从发令者那收到攻击时间后,下属会执行下面中的一个:

(a)   如果时间是1:10或者更早,那么进攻

(b)   如果时间是1:50或者更晚,那么撤退

(c)        否则进行步骤(2)

(2)   询问其他下属在步骤(1)得出的结果

(a)   如果其他下属得到了一个决定,那么使用与他相同的决定

(b)   否则撤退

根据IC2’如果发令者是忠诚的,那么一个忠诚的下属会在第一步里获取正确的命令,这样IC2就满足了。如果发令者是忠诚的,IC1可以由IC2导出。因此只需要证明当发令者是叛徒时的IC1成立即可。因为最多有一个叛徒,意味着两个下属都是忠诚的。根据IC1’,如果一个下属在步骤(1)里决定进攻,那么另一个就不能在步骤(1)决定撤退,因此要么他们在步骤(1)里都达到了相同的决定,要么至少其中一个将其决定推迟到了步骤(2) {!为什么会进入步骤2呢?因为当发令者是叛徒时,两个忠诚的下属达成的时间虽然相差在10分钟内但可能是随意的,比如可能在1:10-1:50之间,所以最后有可能两个都没有在第(1)阶段得出决定,而最后都选择撤退}。在这种情况下,很容易看出他们都达到了相同的决定,因此IC1满足。这样我们就构造出了对于存在一个叛徒的拜占庭将军问题的三将军解,而这是不可能的。因此我们假设存在一个满足IC1’和IC1’的三将军解是不成立的。

 

让1个将军模拟m个的方法也可以用在这里对于m个叛徒,小于3m+1个将军的情况下的证明。与之前原始的拜占庭将军问题的证明类似,因此我们将该证明留给读者来完成。

 

3.   使用口头消息的解

 

前面我们指出,使用口头消息时对于一个含有m个叛徒的拜占庭将军问题,至少有3m+1个将军才可解。现在我们给出一个针对3m+1或更多将军的情况下的解。但是,首先我们需要明确“口头消息”的含义。每个将军都会执行某个算法来把消息传送给其他将军,同时我们假设忠诚的将军会正确地执行该算法。“口头消息”可以通过如下我们为将军消息系统所做的假设来具体定义:

 

A1.每个发送的消息都会被正确的传输

A2.消息的接收者知道是发送者是谁

A3.消息的缺席可以检测出来

 

假设A1和A2是防止叛徒介入其他两个将军的通信中,根据A1,他无法妨碍其他两位将军发送的消息,根据A2他不能伪造消息来搅乱其他两位将军的交流。假设A3是为了防止一个叛徒通过简单的不发送消息来阻止一次决定。这些假设在实际中的实现将会在第6节进行讨论。

 

本节以及下一节的算法,要求每个将军都能够直接向其他将军发送消息。在第5节我们会描述没有该条件限制下的算法。

 

一个叛变的发令者可能会决定不发送任何命令。由于下属们必须遵守相同的命令,因此这种情况下他们必须有一个默认的命令。我们使用RETREAT作为该默认命令。

 

我们归纳性的定义该口头消息(Oral Message简称OM)算法OM(m),m是非负整数,通过这个算法一个发令者向n-1个下属发送命令。可以证明对于3m+1或者更多个将军时,OM(m)解决了拜占庭将军问题。我们觉得用”获取一个值”来取代”遵守一个命令”这样的说法在描述该算法时显得更方便一些。

算法首先需要一个函数majority,该函数有一个属性,当一系列元素(v1,v2…vn)中出现次数占半数以上的元素为v时,majority(v1,v2…vn) {!这样说更准确些,也就是说该函数并没有规定当不存在出现半数以上的元素时的值,所以该函数就有多种选择}。对于majority(v1,v2…vn)有两种自然的选择:

 

1.      如果存在出现半数以上的元素,它的值就是它,否则值为RETREAT。

2.      Vi的中位数,假设他们是一组有序集合。

 

下面的算法仅需要借助于majority的前述属性。

 

算法OM(0)

 

(1)   发令者发送他的值给每个下属

(2)   每个下属使用他从发令者那收到的值,如果没有收到则使用值RETREAT

 

算法OM(m)

 

(1)    发令者发送他的值给每个下属

(2)    对于任意i,vi代表下属i从发令者处收到的值,如果没有收到则采用RETREAT。下属i扮演算法OM(m-1)中的发令者,并采用该算法将值vi发送给其余的n-2个下属。

(3)    对于任意i以及任意的j!=i,让vj代表下属i在步骤2中(使用算法OM(m-1))从下属j处收到的值,如果他没有收到这样的值,就采用RETREAT。下属i采用函数majority(v1,v2…vn-1)的值  

为了理解该算法是如何工作的,考虑m=1,n=4的情况,图3解释了当发令者发送值v,下属3为叛徒时,下属2接收到的消息。在OM(1)的第一步,发令者向所有其他三个下属发送值v。在第二步,下属1使用算法OM(0)将值v发送给下属2。也是在第二步里,下属3向下属2发送了某个其他值x。在第三步,下属2现在又v1=v2=x,及v3=x,因此他会得到正确的值v=majority(v,v,x)。

 

下面我们看下,如何发令者是叛徒会如何。图4展示了当作为叛徒的发令者向三个下属发送三个的值x,y,z时,每个下属收到的值。每个下属都收到了v1=x,v2=y,v3=z,因此他们在第三步都获得了相同的值majority(x,y,z),而无论这三个值x,y,z是否相等。

 

递归算法OM(m)会调用n-1个算法OM(m-1)的独立的执行实例,而每一个OM(m-1)又会调用n-2个OM(m-2)…。这意味着,对于m>1,一个下属会向其他下属发送很多独立的消息。必须要有某种方式用来区分这些不同的消息。读者可以验证,如果每个下属i将数字i加入到他在步骤2中发送的值vi的前缀中,所有的混淆之处都可以消除。伴随着递归的展开,算法OM(m-k)可能会被调用(n-1)…(n-k)次来发送由k个下属的数字组成的序列为前缀的值。

 

为了证明算法OM(m)对于任意m的正确性,我们首先证明如下的辅助定理:

 

Lemma 1.对于任意的m和k,如果存在超过2k+m个将军及最多k个叛徒,那么算法OM(m)满足IC2。

 

证明:证明是通过对m进行归纳法达到。IC2仅说明了当发令者是忠诚的时候需要满足的条件。根据A1,很容易得出如果发令者是忠诚的,算法OM(0)明显可以保证正确性,因此该定理在m=0时成立。

 

在步骤(1),诚实的发令者会给所有的n-1个下属发送它的值。在步骤(2),每个忠诚的下属会在将军数为n-1的情况下应用OM(m-1) {!即每个下属调用OM(m-1)向其余的n-2个除它之外的下属发送它从发令者处得到的值。对于OM(m-1)来说,此时将军数为n-1,发令者变成了该下属}。根据假设n>2k+m,可以推出n-1>2k+(m-1),因此我们可以利用归纳假设{!即OM(m-1)满足IC2。首先根据步骤1,忠诚的发令者发送给每个忠诚下属的值都是v,再根据OM(m-1)满足IC2可以保证每个忠诚的下属可以得到其他忠诚的下属发送的那个值v}得出每个忠诚的下属从其他的忠诚的下属j那得到vj=v。因为最多有k个叛徒,同时n-1>2k+(m-1)>2k,因此n-1个下属中,至少一半以上是忠诚的,这样每个忠诚的下属收到的(v1,v2…vn-1)中,就有一半以上是v,因此在步骤三,他会得到majority(v1,v2…vn-1)=v,这样就满足了条件IC2。

 

{!注意如何看待该OM算法中的m这个参数,一开始我认为m代表了叛徒的数目,但是通过结合上面对于Lemma的证明,发现实际上在此处我们可以认为m仅是一个数字,并无特殊含义,我们只需要假设OM(m-1)时可以保证IC2,然后证明OM(m)下IC2也成立。另外对于OM(m)本身,其步骤中也并未体现出要求m代表了叛徒的数目。}

 

下面的这个定理说明算法OM(m)解决了拜占庭将军问题。

 

THEOREM1.对于任意的m,如果有多于3m个将军及最多m个叛徒,则算法OM(m)可以满足条件IC1和IC2。

 

证明:证明是通过在m上进行归纳得出。如果没有叛徒,很明显OM(0)满足条件IC1和IC2。现在我们假设对于OM(m-1)成立,然后证明OM(m)也成立,m>0。

 

首先考虑发令者是忠诚的情况,根据Lemma1,那里的k即现在的m,可以得出OM(m)满足条件IC2,如果发令者是忠诚的,IC1可以直接由IC2导出。因此,我们现在只需要当发令者是叛徒的情况下,IC1是否成立。

 

由于最多有m个叛徒,而发令者现在是其中之一,因此最多有m-1个下属是叛徒。因为有多于3m个将军,这样就有多于3m-1个下属,同时3m-1>3(m-1)。因此我们现在可以利用归纳假设{!如果有多于3(m-1)个将军及最多m-1个叛徒,则算法OM(m-1)可以满足条件IC1和IC2},得出OM(m-1)满足IC1和IC2。因此对于任意的j,任两个忠诚的将军在步骤三会得到相同的vj值(如果两个将军其中一个j,则该结果可以通过IC2得出,否则可以通过IC1得出)。{!如果两个将军都不是j,那么意味着他们都是得到的下属j利用OM(m-1)发送的vj,根据IC1,因为他们都是忠诚的,因此会得到相同的值。如果其中一个为j,则意味着另一个得到的值是对方利用OM(m-1)发送的vj,根据IC2,可知他得到的就是对方发送的那个vj值}因此任意两个忠诚的将军会得到相同的序列(v1,v2…vn-1)值。因此在步骤三得到的majority(v1,v2…vn-1)的值相同,这就证明了IC1。

 

4.   使用签名消息情况下的解

 

正如我们从图1和图2看到的情形,正是叛徒可以撒谎的能力使得拜占庭将军问题变得难解。如果可以限制他们的这种能力,那么问题就会变得容易解决了。一种方式是允许将军发送不可伪造的签名的消息。准确的讲,我们可以给A1-A3增加如下新的加速:

 

A4

(a)   忠诚的将军的签名不可以被伪造,他的签名信息的内容的任何改动都可以被检测。

(b)   任何人可以验证签名的真实性。

 

注意我们没有对叛变的将军的签名做任何限制,尤其是我们允许他的签名可以被另一个叛徒伪造,因此可能出现在叛徒间的勾结。

 

引入签名消息之后,我们之前的处理一个叛徒至少需要四个将军的结论就不再成立了。实际上确实存在一个三将军情况下的解。下面我们给出一个算法,该算法可以处理任意将军数,m叛徒的情况。(当将军数小于m-2时,该问题是显而易见的){!将军数小于m-2,由于m个是叛徒,这就说明只有0个或者1个是忠诚的,当有0个忠诚者时,很明显IC1和IC2都成立,当有一个忠诚者,假设该忠诚者是发令者,很明显IC2也成立,如果该忠诚者是下属,则发令者就是叛徒,那么只需要满足IC1,而IC1要求所有忠诚者遵守相同的命令,而只有一个忠诚者,显然IC1也满足。}

 

在我们的算法中,发令者给他的每个下属发送一个签名命令,然后每个下属又在该命令上添加上自己的签名,然后再发送给其他人,收到消息的人,继续添加自己的签名,如何反复进行….。这就要求一个下属必须可以有效的接受签名消息,弄出很多份拷贝,签名然后发送出很多份拷贝。这些拷贝如何产生无关紧要,消息可能是被完全影印出来,可能是一系列的相同签名消息的栈,然后被分发出去。

 

算法假设有一个函数choice,用来从一组命令中选出一个来。对该函数唯一的需求是:

 

1.      如果集合V只有一个元素v,那么choice(V)=v

2.      Choice(空集)=RETREAT

 

一种可行的定义是,让choice(V)代表集合V的中位数-假设集合元素是可排序的。

 

在下面的算法中,我们让x:i代表值x经过将军i签名后的形式,因此v:j:i代表值v经过j签名的值v:j又经过了i的签名。假设0代表发令将军。在算法中,每个下属i维护一个集合Vi,包含了目前为止他所收到的有效的签名命令(如果发令者是忠诚的,那个该集合中不会超过一个元素) {!因为发令者已经对消息签了名,这样接收者只能接受他发出的真实的命令,其他人若对该消息进行伪造,那么就可以被检测出来,这样接收者会把这些消息扔掉}。不要把Vi,收到的命令集合与收到的消息集合搞混了,这两个是不同的概念。同一个命令可能会被包含在多个不同的消息中。

 

算法SM(m)

 

初始化,Vi=空集

(1)   发令者签名,然后将他的消息发送给每个下属

(2)   对于任意的i:

(A)   如果下属i从发令者处收到了一个形如v:0的消息,同时目前为止他还未收到任何其他命令,那么:

(i)                 让Vi={v}

(ii)               向其他下属发送消息v:0:i

(B)   如果下属i收到过形如v:0:j1:…:jk的消息,同时v还未出现在集合Vi中,那么:

(i)                 将v添加到Vi

(ii)               如果k<m,那么他就向除j1:…:jk之外的其他下属发送消息v:0:j1:…:jk:i

(3)   对于任意i:当下属i不再收到任何消息时,他选择choice(Vi)的值作为命令。

 

注意在步骤(2),下属i会忽略已经包含在集合Vi中的命令的所有消息。

 

目前,还有一点未说明的就是在每个下属在步骤(3)如何判断他不会再收到任何消息。通过对k进行归纳法,容易得到对于任意的下属序列j1,…,jk(k<=m),一个下属最多会收到一条形式为v:0:j1:…:jk的消息。如果我们要求下属i要么发送注这样的一条消息,要么发送一条消息报告他不会发送这样的一条消息,这样就很容易确定是否所有的消息已经被接收到。(根据假设A3,下属可以确定一个叛变的下属将军是否会选择不发送这两类消息)。此外超时机制也可以用来确定是否不再有消息到达。在第6节还会讨论关于超时的使用方法。

 

注意在步骤(2),下属i会忽略那些任何不具有正确形式的值+签名信息的消息。如果通过发送相同消息的多个信息包来避免消息的拷贝,这就意味着他会丢掉那些没有足够数目的完全相同的{?identical的真实含义为何?},具有正确签名的信息包。(经过某消息经k个下属签名后,该消息未来将会有(n-k-2)(n-k-3)…(n-m-2)份拷贝) {!?should be应该表示未来的意思吧?如果消息经过了k个下属签名,那么它将会被继续送往除0,他自己,及已经签名的k个下属之外的下属处,这样总共还有n-k-2个下属,故首先需要有n-k-2个拷贝,之后这些拷贝被收到后,又会被送往n-k-3个下属处,直到k等于m为止。}

图5代表了当有三个将军且发令者是叛徒的时候,算法SM(1)的执行情况。发令者给其中一个下属发送进攻命令,给另一个发送撤退命令。在步骤(2),两个下属都收到了这两个命令,因此步骤(2)之后,V1=V2={attack,retreat},这样他们会得到相同的choice({attack,retreat})值。注意,这里的情况与图2的情况不同,下属们可以判断出发令者是个叛徒,因为他的签名出现在两个不同的命令中,根据A4,只有当他是叛徒的时候才会出现这种情况。

 

在算法SM(m)中,一个下属签上他的名字来说明他收到了此命令。如果他是给命令添加签名的第m个下属,那么这个签名就不会在转播给其他人,因此实际上这时的签名就变得多余了(更准确的说,假设A2让它变得没有必要)。因此,实际上在SM(1)里,下属不必给他们的消息签名。

 

现在我们来证明算法的正确性。

 

THEOREM2.对于任意的m,如果最多有m个叛徒,那么算法SM(m)解决了拜占庭将军问题。

 

证明:首先证明IC2.如果发令者是忠诚的,那么他会在步骤(1)中发送他的签名消息v:0给每个下属。这样,每个忠诚的下属就会在步骤(2)(A)中收到命令v。此外,由于叛变的下属不能伪造任何v’:0形式的消息,因此一个忠诚的下属在步骤(2)(B)中也不会收到其他的命令。因此,对于每个忠诚的下属i,从步骤(2)得到的集合Vi只有一个值v,在步骤(3)他只会得到choice({v})。这就证明了IC2。

 

如果发令者是忠诚的,IC1可以从IC2导出。因此为了证明IC1,我们只需要考虑发令者是叛徒的情况。两个忠诚的下属如果在步骤(2)里得到的集合Vi和Vj相同,那么在步骤(3)里他们会遵守相同的命令。因此为了证明IC1,只需要证明如果i在步骤(2)将命令v加入了集合Vi,那么j也会将相同的命令v加入集合Vj。为了做到这一点,我们必须表明j也会收到一个包含了命令v的一个正确的签名消息。如果i在步骤(2)(A)中收到命令v,那么他会在步骤(2)(A)(ii)中将该命令传给j;根据A1,i一定会收到它。如果i在步骤(2)(B)将该命令加入Vi,那么他肯定收到了一个如下形式的消息:v:0:j1:…:jk。如果j是{ j1:…:jk }其中的一个,那么根据A4,他一定已经收到过命令v。如果j不在{ j1:…:jk }中,分两种情况考虑:

 

1.      k<m,这种情况下,i会发送消息v:0:j1:…:jk:i给j,因此j一定会收到命令v

2.      k=m。因为发令者是个叛徒,这样就最多有m-1个下属是叛徒。因此在{ j1:…:jm }中至少有一个是忠诚的。这个忠诚的下属一定已经把命令v发送给了j在他第一次收到命令v的时候,因此j也一定会收到命令v。

 

因此证明完成。{?在证明过程中,我们好像也没有发现签名所带来的威力。好像没有引入签名机制我们也可以完成证明。实际上并非如此,签名这一机制实际上是在上面过程中被很隐晦的使用了,比如在上面的证明中,在j是{ j1:…:jk }其中的一个时,说明他收到过该命令,那么如何保证他之前收到的那个信息后,现在i收到的这个v:0:j1:…:jk消息是没有被伪造过的呢,实际上正是签名提供了这一保证,因为I,j都是忠诚的,这样j收到消息后就会对它签名,这样该消息就是经过一个忠诚者签名的了,如果之后它被伪造过那么i就可以选择将它丢弃,而i选择了它说明它是没有被伪造过的,就保证了之前j收到的,与现在i收到的消息包含的是相同的v值。这就是签名的作用,否则我们无法得到该保证。}

 

5.   通信路径缺失

 

目前为止,我们一直假设每个将军可以直接向两一个将军发送消息。现在我们去掉这个假设。我们假设可能由于一些物理上的障碍使得他们相互直接的通信存在某些限制。我将将军们看成是一个简单的有限无向图的节点,两个节点之间有一个参数arc来标识者两个将军能否之间发送消息。现在我们将G是全互联的情况下的算法OM(m)和SM(m),扩展到更一般的图上。

 

为了扩展我们的口头消息算法OM(m),我们需要如下定义。在该定义中,如果两个将军是连通的,那么我们就称他们为neighbors。

 

定义1.

(a)   如果一组节点{i1,…,ip}满足如下条件,我们就称它们为节点i的一个正则邻居集合(a regular set of neighbors)。

(i)                 每个元素都是节点i的邻居

(ii)               对于图中任何一个非i的节点k,都存在一些从{i1,…,ip}中的节点j到k路径Pj,k,这些路径都不经过节点i,并且它们之间除了k之外没有其他共同经过的节点。{?也就是说当把节点i去掉后,{i1,…,ip}中的每个节点都存在一条到达其他某个节点k的路径,而且它们到k的路径都是不相交的。}

(b)   如果图G中的每个节点都有一个由p个不同节点组成的正则邻居集合,那么就说图G是p-regular的。

图6给出了一个3-regular图的实例。图7给出了一个不是3-regular图的实例,因为它的中央那个节点不存在一个3节点的正则邻居集合。

 

如果将军们之间的图是3m-regular的,我们就可以将解决m个叛徒的拜占庭将军问题的算法OM(m)进行扩展(显然一个3m-regular图至少有3m+1个节点)。对于任意的正整数m和p,当图G是一个p-regular图时我们定义如下的OM(m,p)算法(当图G不是p-regular图时,OM(m,p)未定义)。该定义使用了针对m的归纳法:

 

算法OM(m,p)

 

(0)   选择发令者的由p个下属组成的正则邻居集合N。

(1)   发令者将他的值发送给N中的每个下属

(2)   对于N中任意的i,让vi代表下属i从发令者处收到的命令,如果没有收到则令其等于RETREAT。下属i通过如下方法将值vi发送给其他的下属k:

(A)   如果m=1,那么沿着路径Pi,k发送,该路径的存在是由定义1的条件(ii)保证的

(B)   如果m>1,那么他就作为算法OM(m-1,p-1)中的发令者,同时此时的将军图是通过将原始的发令者从图G中删除得到的。

(3)   对于任意的k,及N(N={i1,…,ip})中的任意不等于k的i,让vi代表下属k在步骤(2)中从下属i处收到的值,如果没有收到值令其等于RETREAT。下属k使用值majority(vi1,…,vip)。

 

注意从p-regular图中删除一个节点后可以得到一个(p-1)-regular图。因此,可以在步骤(2)中应用算法OM(m-1,p-1)。

 

现在我们证明如果最多有m个叛徒,那么OM(m,3m)解决了拜占庭将军问题。该证明类似于算法OM(m)的证明,因此我们只是简单的描述下。首先从Lemma1的一个扩展开始:

 

LEMMA2.对于任意的m>0及任意的p>=2k+m,如果最多有k个叛徒,算法OM(m,p)满足条件IC2。

 

证明:对于m=1,可以看出每个下属会得到majority(v1,…,vp)的值,其中的每个值vi是发令者通过一条与发送给他的其他值的发送路径不相交的一条路径发送的{!此处的发令者是指步骤(2)中的N中的某个将军,并不是特指(1)中的那个原始的发令者}。由于最多有k个叛徒而且p>=2k+1,因此超过一半的路径都是完全由忠诚的下属组成的{!总共有p条路径,只有k个叛徒,p>=2k+1,即使一条路径上只有一个叛徒,那么最多有k条路径上有叛徒}。因此,如果发令者是诚实的,那么有一半以上的vi值都是他发送的那个值,这样就保证满足了IC2。

 

现在假设对于m-1,m>1 LEMMA2成立。如果发令者是忠诚的,那么N中的P个下属都会得到正确的值。因为p>2k,因此他们中大多数都是忠诚的,根据归纳假设,他们中的每个人都会给每个诚实的下属发送正确的值。因此,每个忠诚的下属,会收到半数以上的正确值,因此在步骤(3)他们会得到正确的值。

 

算法OM(m,3m)的正确性可以从如下结论中理解得到。

 

THEOREM3.对于任意的m>0及任意的p>=3m,如果最多有m个叛徒,那么算法OM(m,p)解决了拜占庭将军问题。

 

证明:根据LEMMA2.令k=m,我们可以得到OM(m,p)满足IC2。如果发令者是诚实的,那么IC1可以由IC2导出,因此我们只需要证明发令者是叛徒的情况下的IC1即可。为此,我们需要证明在步骤(3),每个忠诚的下属得到相同的vi值的集合。如果m=1,很明显成立{!此时只有一个叛徒,而且他是发令者}。因为所有的下属包括N中的那些,都是诚实的,并且路径Pi,k不经过发令者。如果m>1,可以使用一个归纳法证明,因为p>=3m,得出p-1>=3(m-1)。

 

我们关于算法OM(m)的扩展要求图G是一个3m-regular图,是一个相对比较强的联通性假设。实际上,如果仅有3m+1个将军,3m-regularity实际上就是全互联,而算法OM(m,3m)实际上也变成了OM(m)算法。与此相比,算法SM(m)很容易扩展到可能的最弱的连通性假设。首先,我们来看保证拜占庭将军可解需要何种程度的连通性。IC2要求一个忠诚的下属遵从忠诚的发令者,很明显如果发令者无法与该下属通信是不可能达到的。尤其是如果发令者发到该下属的消息都要经过一些叛徒转发,那么就无没有方法保证该下属可以得到发令者的命令。类似的,如果两个下属之间只能通过一些叛变的中间者进行通信,他们条件IC1也无法满足。

 

因此对于拜占庭将军问题可解的最弱的连通性假设就是:由忠诚的将军们组成的子图是连通的。可以证明,在该假设下,算法SM(n-2)是一个可行解,此处n代表将军的个数-无论有多少个叛徒。当然,我们必须要修改该算法,使得他只能向那些可以通信的对象发送消息。详细来说,就是在步骤(1),发令者只能向他的邻居下属发送消息,在步骤(2)(B),只能向那些不在jr中的邻居下属发送信息。

 

下面我们来证明一个更一般的结论,首先需要知道图的直径是指图中任意两节点间的最短路径的长度的最大值。

 

Theorem4.对于任意的m和d,如果最多有m个叛徒及忠诚的将军组成的子图的直径为d,那么算法SM(m+d-1)(加入了上面的改动后的算法)可以解决拜占庭将军问题。

 

证明:证明过程很类似于Theorem2。首先证明IC2,根据假设,从忠诚的发令者与一个下属i之间存在一条路径,该路径只是经过d-1个或者更少的忠诚下属。这些下属在命令到达i之前,可以正确的转发它,如前面所述,假设A4可以防止一个叛徒伪造一个不同的命令。

 

为了证明IC1,我们假设发令者是个叛徒,接下来需要说明,一个忠诚下属收到的任何命令,另一个忠诚的下属j也都能到收到。假设i收到了一个未被j签名的消息v:0:j1:…:jk。如果k<m,那么i会在接下来的d-1步内把该消息转发给j。如果k>=m,那么之前的m个签名者中至少有一个是忠诚的,而且他一定已经将给命令发送给了他所有的邻居,这样它会被忠诚的下属们继续转发,也会在接下来的d-1步内j就会收到该消息。

 

Corollary.如果忠诚的将军的图是连通的,那么SM(n-2)(同时是改写后的算法)解决了n个将军情况下的拜占庭将军问题。

 

证明:让d代表忠诚的将军的图的直径。由于一个连通图的直径肯定小于节点总数,同时忠诚将军的个数肯定大于d,反过来叛徒的个数肯定小于n-d。令m=n-d-1代入Theorem4,得到SM(n-d-1+d-1)即SM(n-2)。

 

Theorem4.假设忠诚的将军组成的图是连通的。即使该条件不成立,上面的证明可以很容易扩展而得到如下的结论:

当最多有m个叛徒的时候,算法SM(m+d-1)有如下属性:

 

1.      图中由最多d个忠诚下属连接的任意两个忠诚下属会遵守相同的命令

2.      如果发令者是忠诚的,那么与发令者之间存在一条由最多m+d个忠诚下属组成的路径的忠诚下属将会遵守发令者的命令。

 

6.可靠性系统

 

除了在内部使用可靠性电路组件外,我们所知的实现可靠计算机系统的唯一方式就是使用几个不同的处理器来计算相同的结果,然后在它们的输出结果上执行多数决的投票来确定一个值。(投票可能是在系统内部进行的,也可能是该输出的用户在外部进行的。)无论是在实现可靠计算机中通过冗余电路来避免独立芯片的失败,还是在弹道导弹防御系统中使用冗余计算站点来避免核攻击中的网点破坏,都是如此。唯一的区别就是被备份的处理单元的大小规模。

 

多数决的投票的使用基于这样的一个假设:所有的正常的处理单元应该产生相同的输出结果。当它们都使用相同的输入时,这是正确的。然而,一个输入数据来自一个独立的物理单元,比如来自可靠计算机系统的其他电路单元,或者来自于导弹防御系统中的一个雷达站,一个故障组件也可能会为不同的处理单元提供不同的值。更进一步的,从同一个输入单元获取输入的不同的处理单元也可能获得不同的输入,因为在他们读取时输入值可能是不断变化的。比如,两个处理器去读取一个在运行的时钟,一个可能读取到老的时间,一个可能读到新的,只能通过对该时钟的读取进行同步才能防止这种情况。

 

为了让基于多数决的投票可以构建可靠性的系统,需要满足如下两个条件:

 

1.      所有的正常处理单元必须使用相同的输入值(这样他们才会产生相同的输出)

2.      如果输入单元是正常的,那么每个正常的进程都应该使用它提供的值作为输入(这样他们才能产生正确的结果)。

 

这正是我们的交互一致性条件IC1和IC2,至少发令者变成了输入产生单元,下属变成了处理单元,忠诚意味着正常(nonfaulty)。

 

为这样的问题提供一个硬件级的解决方案看起来是很吸引人的。比如,有人认为可以通过让所有的处理单元从同一条线路上读取输入来保证它们可以获取相同的值。但是,一个出错的处理单元可能会在线路上发送边缘信号—这种信号某些处理器可能作为0处理,但是其他的可能作为1处理。因此不存在一种方法可以保证不同的处理器会从可能出错的输入单元上获取相同的值,除非让处理器相互之间可以通信来解决拜占庭将军问题。

 

当然一个出错的输入单元可能会提供无意义的输入值。拜占庭将军解决方案可以做的就是保证所有的处理单元可以使用相同的输入值。如果输入是一个很重要的部分,那么应该有多个独立的输入单元提供冗余值。比如在一个导弹防御体系中,除了有冗余的处理站点外,还应该具有冗余的雷达。然而,输入的冗余无法达到可靠性。仍然有必要保证正常的处理单元可以通过使用冗余数据产生相同的输出。

 

对于输入设备是正常的但是由于读取时它的值仍在变化的情况,我们仍然希望那些正常的处理单元可以获取合理的输入值。可以看到,如果函数majority和choice被设定为中位数函数,那么我们的算法会具有如下的属性:正常的处理单元得到的值得到的值将落在输入单元提供的值的边界之内。因此只要输入单元提供一个合理的值的边界,那么正常的处理单元将会得到一个合理的值。

 

前面我们已经给出了几个解{!指之前的几个OM,SM算法},但是他们都是从拜占庭将军问题的角度来描述,而不是采用计算机系统的用语。现在我们来看,这些解如何应用到可靠的计算机系统。毫无疑问,一个将军的算法可以在一个处理单元上实现。问题取决于实现一个满足假设A1-A3的消息传递系统(对于算法SM(m)来说,就是假设A1-A4)。下面,我们逐个分析这些假设:

 

A1。假设A1说明由一个正常处理单元发送的所有消息都可以正确的传输。在现实系统中,通信线路可能出错。对于算法OM(m)和OM(m,p),连接两个处理单元间的通信线路出错无法与其中的一个处理单元出错区分出来。因此,我们仅能保证这些算法在出现m个失败时可以工作,可能是处理器也可能是通信线路出错了(当然连接到相同处理器上的通信线路错误等价于当个处理器的失败)。如果我们假设通信线路错误不会导致签名信息的伪造(下面可以发现该假设十分合理),那么我们的签名信息算法SM(m)就不会受到通信线路错误的影响。更准确的说,即使出现通信线路错误,Theorem4依然合法。这样一个通信线路错误与简单的移除该通信线具有相同的影响—只是降低了图的连通性。

 

A2.假设A2一个处理单元可以确定它受到的任何消息的来源。这条实际上主要是要求一个出错的处理单元不能伪装成一个正常的。在实际中,这意味着进程间的通信必须是通过固定线路而不是通过某些消息传递交换网络。(如果使用的是交换网络,那么必须考虑网络节点的失效,拜占庭将军问题再次出现)。注意如果条件A4满足,同时所有的消息都是签名的,那么A2就不是必要的。因为进程的不可模仿性通过消息的签名就可以达到。

 

A3.假设A3要求信息的缺席可以被检测。消息的缺席只能通过在固定时长内没有到达来检测,换句话说,需要通过使用某些超时约定。使用超时机制来达到条件A3,需要如下2个假设:

 

1.      消息的产生和传输所需的时间有一个固定的最大时长

2.      发送者与接收者有一个固定误差的同步时钟

 

第一个假设的必要性是很明显的,因为接收者必须知道他需要花多长时间等待消息的到达。第二个假设的必要性很不明显。然而可以证明,如果要解决拜占庭将军问题,需要该假设或者是等价于它的某个假设。更准确的说,假设有一个算法,在该算法中,将军们只能在如下的情形下采取行动:

1.      在某个固定的初始时间(对于所有的将军来说该值相同)

2.      收到消息的时候

3.      当一个随机选择的时长过后。(比如一个将军可以将计时器设定为一个随机值,在时间到时才能继续行动)

(上面代表了我们能想象出来的不需要构建同步时钟的最通常的一类算法)。可以证明,如果消息可能以任意快的速率传输即使存在一个上界,那么不存在解决拜占庭将军问题的此类算法。甚至即使我们限制叛徒的错误行为只是无法发送消息,这种情况下依然是无解的。该结论的证明超过了本篇论文的内容。需要注意的是,如果对传输延时上除了上界限制之外,再添加一个下界限制就允许处理单元通过来回的传递消息来实现时钟。

 

上面的两个假设,使得检测未发送的消息变得很简单。令u代表最大的消息生成和传输延时,假设正常处理单元在任何时刻的时钟误差最大为t。这样如果一个正常处理单元在他的时钟时间T生成的任何消息,消息会在接收者的时钟时间T+u+t内到达。因此,如果接收者在那时还未收到该消息,那么它就认为发送者没有发送该消息。(如果它在之后到达,那么发送者一定出错了,因此算法的正确性不能依赖于正在发送的消息)。通过固定输入处理单元发送值的时间,处理单元就可以确定等待应该等待消息到何时。比如,在算法SM(m)中,一个处理单元对于任何具有k个签名的消息必须等待到时间T0+k(u+t),T0代表该处理单元在发令者开始执行算法时的它自己的时钟时间。

 

没有任何两个时钟具有相同的速率,因此无论处理单元间的时钟一开始无论同步的多么精确,最后他们都会相差很大,除非会周期性的进行重新的同步。因此现在我们需要解决让处理单元时钟同步在一定偏差之内,即使有的处理单元是出错的。该问题本身是一个与拜占庭将军问题难度相当的问题。时钟同步问题的解与拜占庭将军问题的解联系紧密,我们会在未来的论文中进行描述。{!实际上作者在他的论文<<>>中对该问题进行了解决。}

 

A4,假设A4需要处理单元的签名消息能够保证正常处理单元的签名不能被伪造。假设进程i从数据M生成的签名为Si(M)。那么一个经签名的信息就由一个(M, Si(M))对组成。为了满足A4的(a)(b)两个要求,函数Si必须具有如下两个属性:

 

(a)   如果处理单元i是正常的,那么任何出错单元都不能生成Si(M)

(b)   给定M和X,任何进程都可以确定X是否等于Si(M)

 

属性(a)不可能绝对满足,因为Si(M)仅仅是一个数据项,一个出错的处理单元可能生成任意的数据项{!这意味着它也可能刚好生成Si(M)}。但是我们可以让这种出错情况的概率尽可能的小,从而也可以让系统尽可能的稳定。如何做到这点依赖于我们期望碰到的出错类型。比如如下两种情况:

 

1.随机故障。令Si为一个合适的随机化函数,我们可以让一个出现随机故障的处理单元生成一个正确的签名的概率等价于通过随机选择函数来完成这件事的概率,即可能的签名的数目的倒数。下面介绍可以达到该目的一种方法。

假设消息被编码成小于P的正整数,P是2的幂{!实际上消息本质上也是二进制01码,因此只需要保证其长度小于P的长度即可}。令Si(M)=(M*Ki)mod Pi,Ki是一个随机选择的小于P的奇数。令Ki^-1为满足Ki* Ki^-1=1 mod P的唯一一个数,一个处理单元可以通过测试M是否等于(X* Ki^-1)mod P来测试X是否等于Si(M)。如果一个处理单元的内存中没有值Ki,那么它为一个消息M生成正确的签名M*Ki的概率是1/P:这也是通过随机选择来生成的概率。(如果处理单元能通过某种过程获得Ki,那么出错的处理器j在计算Sj(M)的时候就有更大的概率可能将Sj替换为Si来伪造i的签名)。{!所以这样看来其实该机制也类似于公钥签名机制,(Ki,P)可以看做私钥,而(Ki^-1,P)则可以看做公钥。可能还有一个问题是Ki可以很容易通过(Ki^-1,P)求出来,当然这也是与公钥机制的区别。但是这不影响对问题的解决,因为该假设是假设错误是随机的,如果利用(Ki^-1,P)计算Ki再去伪造应该算是恶意攻击了,就是下面这个假设的范畴了。}

 

2.恶意攻击。如果出错的处理单元是由恶意攻击导致—比如一个正常的处理单元可能正被一个企图破坏整个系统的人操纵。那么签名函数Si的构建就变成了一个密码学问题。推荐读者参考文献[1]和[4]来查看如何解决该问题。

 

需要注意的是如果处理单元已经看到过消息M的签名,那么下次它就很容易生成Si(M)。因此需要保证不能重复对相同的消息签名。这就意味着,使用SM(m)算法重复的发送一系列值的时候,需要给这些值增加一个序列号来保证它们的唯一性。{!之所以要加入序列号,是因为如果不加下属们就很容易伪造签名,比如他收到了一个(M,S1(M),S2(M)…Sk(M))消息,同时之前也收到过值为M’的消息,同时由于不断的发送,他可能已经收到过针对M’的所有签名,这样他就可以把(M,S1(M),S2(M)…Sk(M))修改成(M’,S1(M’),S2(M’)…Sk(M’)),这样就达到了伪造的目的:他修改了M的值,但是将军们的签名还都正确。所以需要加入序列号以提供保证,使得将军们不会再次发出相同的消息值,也就没法利用之前收到的消息进行伪造。}

 

 

{!最后看下如何通过上面的方法来保证A4假设呢?首先假设A4如何保证消息不被伪造,先看下属在伪造一个消息时需要做哪些事情:根据前面,我们知道每个下属收到的是形如(M,S1(M),S2(M)…Sk(M))的消息,他如果要修改该消息,首先要修改M的内容,然后再修改签名1到k。但是根据假设它实际上无法修改经过忠诚者签名的那些消息,根据上面的方法,每个下属接受到消息后只需要去验证M是否等于(Si(M)* (Ki^-1))mod P ,即可验证签名的真伪,所以只要保证忠诚的将军的Ki不被泄露即可。另一方面对于叛变的将军,并没有任何的限制,比如叛变的将军可能会告诉另一个将军自己的私钥(Ki,P)这样他的签名就可以被伪造了,但是忠诚的将军不会这么做,所以他的签名就能保证不可伪造,但该假设并没有对叛变的将军做出这种保证,也就是说这种签名存在的情况下,叛变的将军们依然可以相互勾结去伪造出发令者的命令。}

 

7.总结

 

我们已经提出了拜占庭将军问题在不同假设下的几个解,也说明了如何将它们用于实现可靠的计算机系统。这些解,都需要昂贵的时间和消息传递开销。算法OM(m)和SM(m)的消息的传递路径长度都达到了m+1。换句话说,每个下属都可能要等着消息从发令者处发出后经过m个其他个下属后才能到达它这。Fischer和Lynch对于任何能够处理m个叛徒的解都是这样的,这样看来我们的解已经是最优的了。对于一个不是全互联的图来说,在我们的算法中,消息传递路径的长度还会达到m+d,d代表忠诚的将军组成的子图的直径。我们觉得这可能也已经是最优的了。

 

算法OM(m)和SM(m)会发送多达(n-1)(n-2)…(n-m-1)个消息。可以通过将消息合并来减少需要传输的消息数。同时减少需要传输的信息数量也是有可能的,但是目前还没有深入的研究它。然而,我们认为不管怎样仍然有大量的消息需要传输。

 

达到任意出错可能的情况下的可靠性是一个很困难的问题,而解决方案本身看起来也会很昂贵。降低这种开销的唯一方法就是限定可能出现的错误类型。比如,经常假设计算机可能会没有响应,但是不会返回错误的响应。然而当需要高度的可靠性时,是不应该做出这样的假设的,此时拜占庭将军问题的所有开销就是不可避免的。

 

参考文献:

My writings 

You Might Also Like