PBFT共识协议下的双重支付攻击

发布时间:2019年03月15日 价值:20000.00 / 共识:43

引子

maxdeath 老师(就是知乎的那位 maxdeath)给大家出了一道题:“基于PBFT共识协议的联盟链,什么条件下会发生双重支付攻击”,这道题其实是在考大家对 PBFT 协议达成共识的过程以及协议边界条件的理解。之前只思考过基于 PoW 共识的 Bitcoin 双重支付的问题,对于 PBFT 共识的双重支付还是比较新颖的提法(也非常有意思),整理到这里提供给同样感兴趣的同学。

PBFT 共识简介

模型假设

PBFT 共识是基于 state machine replication 的模型,有两个基本假设(前提):
1、所有的节点基于一个给定的 state 执行 一个 operation 的结果是确定的(结果本身)而且也是一致的(节点之间);
2、所有节点是从相同的 state 开始的。

所以共识协议要解决的核心问题是:尽管在有恶意节点(包括失败)的情况下,诚实节点之间依然可以对交易执行的全局 order 达成一致

共识过程

基于上述建模,PBFT 是一个三阶段协议,相信下面这幅图大家经常会看到,这里 Replica 0 是 primary。

1、client 发送 request(可以理解为交易)给 primary(client 可以根据 view number 算出当前 view 轮到那个 Replica 当 primary,所以 primary 在 PBFT 网络里面是预知的,这在公链场景会引起安全风险,比如针对 primary 做 DDoS 攻击,让系统瘫痪)。

2、primary 在 pre-prepare 阶段的主要职责就是给每个交易分配一个 sequence number,其实就是给交易做 order;然后会广播给网络中的其他 Replica。

3、prepare 阶段的主要作用就是针对 pre-prepare 阶段 primary 提议的交易 sequence number 达成一致;每个 Replica 都会向其他节点发送 prepare 消息并根据接收到的其他 Replica 发送过来的相同 message(是指view number,sequence number等都能对的上)的数量来决定 prepare 阶段是否为 true。那这个消息的数量是多少呢(包括 Replica自己),你一定知道是 2f + 1,其中 f 是网络中最大恶意节点数量。这个证明我们放到下面的部分。

4、Replica 在 prepare 阶段为 true 就会进入 commit 阶段,同时会向其他 Replica 发送 commit 消息;当这个消息被 2f + 1 个 Replica 接受之后(包括自己),就会进入 committed-local 状态,同时向 client 返回一个 reply。

5、当 client 收到 f + 1 个 reply 之后就可以接受结果了。

安全性证明

让我们来看一下每个 view 中核心的 prepare 阶段的安全性证明,其实是反证法。

论证过程: 如果 Replica i 针对消息 mi 收到 2f + 1 个相同的,就不可能有另外一个 Replica j 针对消息 mj 也收到 2f + 1 个相同的;因为这样就超出最大恶意节点为 f 的安全边界。

更详细的论述:Replica i 2f + 1 个相同的消息里面,即使有 f 个 消息是恶意节点发的,但剩下的 (2f+1) - f = f + 1 个节点一定是诚实的,这 f + 1 个节点既然已经接受了 mi就不会接受mj,否则就违法了最大恶意节点为 f 的限制了;那让我们回头算一下对于mj最多能达成一致的消息数:(3f+1) - (2f+1) + f = 2f,所以Replica j 针对消息 mj 不会收到 2f + 1 个相同的,证明完毕。

双重支付的场景

有了上面的安全边界证明,是不是马上就能想到针对 PBFT 共识的双重支付场景呢。其实只要我们突破了安全边界,让最大恶意节点变为 f + 1,马上就可以想到一种双重支付的场景。

f + 1 个恶意节点里面任何一个轮值到 primary,都可以和剩下的 f 个恶意节点合谋,把网络分化为3个区:f 个 诚实节点(左)f 个恶意节点f个诚实节点(右)。然后:

1、恶意 primary 给 f 个诚实节点(左)f 个恶意节点 发送 mi,加上 primary 自己刚好满足 2f + 1
2、恶意 primary 给 f 个诚实节点(右)f 个恶意节点 发送 mj,加上 primary 自己也刚好满足 2f + 1
3、这里在一个 view 的 prepare 阶段针对同一个 sequence number 产生了两个交易,也就是所谓的双重支付。

备注:PBFT 的双重支付攻击,其实并不是说 PBFT 算法本身不安全;而是反向证明了 PBFT 的边界是 3f+1个节点中最大恶意节点只能是 f

  • 分享 收藏
0 条评论
  • 这篇文章暂无评论,赶紧评论一下吧~