作者:LORENZO

一个网络中的计算机依据协议跟彼此沟通。在这里,“协议” 指的是一套规矩体系,指定了音讯应该怎样传输和解读。闪电网络协议中的付出音讯传输部分由 BOLT#4 描绘,也叫 “洋葱路由协议(Onion Rounting Protocol)”。

洋葱路由是一种先于闪电网络 25 年诞生的技术。它也被用在 Tor 中,正是 “Tor” 这个名字(“The Onion Router”)的由来。闪电网络运用的是一个略微修正之后的版别,叫做 “基于来历的洋葱路由”,缩写是 “SPHINX”。在这篇文章中,咱们就要讲讲洋葱路由是怎样工作的。

为什么要运用洋葱路由?

世界上存在许多不同的通讯协议,但由于闪电网络是一个付出网络,挑选一个尽或许少提醒正被转发的付出的信息的协议,便是合理的。

假如闪电网络运用跟互联网相同的协议,每一个中心人都会知道谁是付出的发送者、谁是接纳者、整条途径上的其他中心人是谁。洋葱路由是一个好的挑选,由于其特性确保了中心节点:

  • 只知道自己的上一个节点(谁给自己发来了音讯)和下一个节点(要把音讯转发到哪里去)。

  • 不知道整条途径的长度;

  • 不知道自己在途径中的方位。

概述洋葱路由

咱们用包裹作为类比,解释一下洋葱路由是怎样工作的。

假设 Alice 要给 Dina 付出。首先,Alice 要为自己的付出找出一条可行的途径:

Alice → Bob → Chan → Dina

然后,她构造出一个 “洋葱”。她要从 Dina 开始(从途径的结尾开始)。她把一个隐秘音讯(付出内容)放在一个发送给 Dina 的包裹中,而且运用一个只要她和 Dina 知道的密钥来上锁。现在,她把这个包裹放到另一个预备发送给 Chan 的包裹中,而且运用只要她和 Chan 知道的密钥,给这个发送给 Chan 的包裹上锁。对以此类推。

闪电网络中的 “洋葱路由” 及其工作原理

Alice 把终究的洋葱(包裹)发给途径上的第一个中心人,Bob。Bob 运用自己的密钥解锁自己的包裹,然后看到下一个包裹是发送给 Chan 的。于是他把包裹转发给 Chan。Chan 也相同,解开包裹之后,把里面那个包裹转发给 Dina。终究,Dina 打开归于自己的包裹,发现其间的付出音讯。

在洋葱路由中,像 Bob 和 Chan 这样的中心人,并不知道给 Dina 的信息的内容,也不知道整条付出途径的长度。他们仅有知道的,便是给他们转发这个包裹的人,以及下一个接纳包裹的人。这确保了音讯的隐私性和途径的机密性。每一个中心人都只能触及专门为 TA 制作的那一层音讯。

在闪电网络的基于来历的洋葱路由中,发送者挑选付出途径,并为这条途径构造出完好的洋葱,这能够被视为隐私漏洞(译者注:接纳者的网络方位有必要向发送者曝光)。其他路由方案比方 “盲化路由”(中文译本),经过向发送者混杂部分付出途径来解决这个问题。不过,在这篇文章中,咱们专讲 SPHINX。

组装洋葱

现在,咱们来了解一下洋葱路由的规范。在一开始,咱们需求定义这些东西:

  • 发送者是 “最初节点”(Alice);

  • 接纳者是 “终究节点”(Dina);

  • 付出途径上的每一个中心节点都是一 “跳”(Bob 和 Chan);

  • 每一跳之间的通讯信息,叫做 “跳的负载”。

建构跳的负载

一旦 Alice 选出了一条付出途径,她就从 gossip 协议中取得每一条付出通道的信息,以创立每一跳的负载,本质上这便是在奉告每一跳,怎样为正在转发的付出创立 HTLC(哈希时刻锁合约)。

为了树立一个合适的 HTLC,每一跳都需求:

  • 需求转发的数额;

  • 付出的隐秘值;

  • 继续发送洋葱的付出通道的 ID;

  • 时刻锁的长度。

这些数据中的大部分,都来自 “通道更新” 音讯,这样的音讯包含了关于路由手续费、事情所要求、付出通道 ID 的信息。需求转发的总数额,是付出的数额加上后续每一跳所收取的手续费总和;而付出的隐秘值则是由 Dina 计算出来并嵌进付出发票中的(由洋葱音讯奉告途径上的每一跳)。

闪电网络中的 “洋葱路由” 及其工作原理

闪电网络中的 “洋葱路由” 及其工作原理

Alice 从终究节点 Dina 开始。她在包裹中包含转发数额、时刻锁时长数值、付出隐秘值以及付出数额。注意,她不需求再参加通道 ID,由于 Dina 便是终究节点,不需求再将付出转发给其他人。

乍看起来,供给转发数额是多余的,由于这个数额跟付出数额是相同的,可是,多途径(multipath)付出会将付出总额经过多条途径送达,那时候两个数值就会不一致。

在 Chan 的负载中,Alice 参加 Chan 跟 Dina 的通道 ID。她还增加了转发数额以及时刻锁数值。终究,Alice 创立给 Bob 的负载。Chan 为经过自己跟 Dina 的通道的付出收取 100 聪,因而,Alice 需求奉告 Bob 的转发数额是付出额加上手续费。依据 Chan 的通道更新音讯,时刻锁的数值也提高了 20(以区块为单位)。终究,Alice 也要考虑 Bob 的手续费和时刻锁要求,给他一个时刻锁长度为 700040、价值为 100200 聪的 HTLC。

同享隐秘值与密钥生成

下一笔,Alice 经过为每一跳(包含终究节点)生成一个同享隐秘值(shared secret),预备好洋葱。这个同享隐秘值能够由 Alice 和方针那一跳各自生成出来,方法便是用自己的私钥与对方的公钥相乘。

闪电网络中的 “洋葱路由” 及其工作原理

同享隐秘值对洋葱路由来说是必要的,这让 Alice 和每一跳能够推导出相同的密钥。然后,Alice 运用这些密钥来混杂洋葱的每一层,而那一跳则运用密钥来解开混杂。

为了维护 Alice 的隐私,她会为一个洋葱创立一个一次性的会话密钥,而不是运用自己的节点公钥,以推导同享隐秘值。她给第一跳运用这个会话密钥,然后,对后续的每一跳,Alice 都将最新的密钥乘以一个盲化因子,然后确认性地随机化密钥。这些用来创立同享隐秘值密钥,咱们叫做 “暂时密钥” 。

闪电网络中的 “洋葱路由” 及其工作原理

Bob、Chan 和 Dina,都需求跟 Alice 得到相同的隐秘值,因而,他们需求知晓用在自己的会话中的暂时密钥。Alice 只将第一个密钥放到洋葱中,以节约音讯的体积。每一跳都计算下一个暂时密钥,并将它嵌在给下一个节点的洋葱中。各跳能够运用自己的公钥和同享隐秘值计算出 Alice 所用的盲化因子,然后确认下一个暂时密钥。

如前所述,同享隐秘值会被用来生成一些密钥,Alice 和对应跳能够用这些密钥对洋葱做一些操作。咱们来看看每一个密钥的用途。

Rho key

Rho key 被 Alice 用来加密一层洋葱;这样会混杂负载的内容,使外人无法解读。只要 rho key 的主人能够解密负载。这便是收到洋葱的节点要做的事:运用跟 Alice 的同享隐秘值推导出 rho key,然后解密洋葱、阅览内容。

Mu key

Alice 运用 mu key 来为每一个负载创立一个校验和。她也会把校验和交给接纳洋葱的那一跳。反过来,这一跳会运用 mu key 生成所收到的负载的校验和,查看是否与 Alice 给出的相匹配。这是为了查看负载的完好性,验证它没有被篡改正。

Pad key

这个密钥仅为 Alice 所用,用来生成随机的 “废物” 数据。这些数据也是洋葱的一部分,而且它跟付出途径的长度、洋葱现已经过多少跳无关,它让洋葱总是坚持相同的体积,即使其某些内容需是无关紧要的。这便是洋葱路由怎样躲藏途径长度的,实际上便是在维护发送者和接纳者的隐私。

Um key

这个密钥也用来查看洋葱内包含的数据的完好性,但仅在回传过错时运用。没错,它叫做 “um” 是由于这是 “mu” 的倒写。在付出犯错的景象中,发现过错的那一跳将运用 um key 创立一个校验和,当时一个节点收到这个报错时,也运用 um key 来验证音讯的完好性。

封装洋葱层

终究的洋葱包裹看起来是这样的:

闪电网络中的 “洋葱路由” 及其工作原理

现在,Alice 具有了给每一跳的负载,以及给每一跳的同享隐秘值。咱们来看看 Alice 怎样将这些信息转化为终究的洋葱。她先从终究节点开始,然后一步一步往回推。

她先创立一个空的、长为 1300 字节的域,这也是一切洋葱负载的总长。然后,她运用 pad key创立一段长为 1300 字节的随机串,这便是对任何一跳都没用的废物。做这一步,是为了确保每一层洋葱看起来都是相同的,所以既无法看出途径的总长(有多少跳),也看不出谁是发送者、谁是接纳者。

然后,她给需求运用的负载创立一个校验和,并放在负载的结尾。在给终究节点的音讯中,校验和悉数为 0,以奉告 Dina,她便是这个洋葱的终究接纳者。把校验和增加到负载的结尾之后,Alice 就把负载(以及校验和)放到废物的开头,并删去整条音讯超越 1300 字节的部分,以确保整个音讯的长度便是 1300 字节。

然后,Alice 运用 rho key 创立一个随机字节串,并对上一步得到的洋葱负载运用异或(XOR)运算,得到混杂后的负载。负载的原文能够经过对混杂文运用这个随机字节串的 XOR 运算得到(译者注:换言之,这里的 XOR 便是对称加密的算法,而随机字节串便是密钥)。XOR 操作会逐比特对比洋葱负载和(由 rho key 生成的)随机字节串,仅当其间一个数据的比特是 1 时,才会输出 1;这就得出了一个混杂后的负载。XOR 操作巧妙的当地在于,只要你得到了对的那个随机字节串以及混杂后的负载,只需用两者再次运行 XOR 操作,就能够得到混杂之前的负载。

闪电网络中的 “洋葱路由” 及其工作原理

由于收到洋葱的节点能够推导出相同的 rho key,能够他们能够生成跟 Alice 相同的随机字节串。这便是沿路的各个节点能够解开混杂、读到内容的方法。

预备好一跳的混杂洋葱后,Alice 就给下一个节点重复相同的进程。关键差异在于,完结 Dina 的洋葱之后,她就不再需求生成废物了。她只需在有用的负载和校验和之后接上上一步所生成的混杂洋葱,再剪去超越 1300 字节的部分。

终究,Alice 拿到终究的混杂洋葱并增加一个校验和,这样 Bob 就能够验证这个洋葱的完好性。然后,Alice 参加会话公钥,这样 Bob 就能够运用这个公钥来计算同享隐秘值。终究,她还要加上一个表明版别的字节,奉告其它节点怎样解读其间的数据。对 BOLT#4 所描绘的版别来说,版别字节应为 0。

闪电网络中的 “洋葱路由” 及其工作原理

转发洋葱

为了发送这个洋葱包裹,发送者创立一条 update_add_htlc 音讯,包含下列字段:

  • 通道 ID:这个音讯所关乎的具体通道。

  • ID:这个 HTLC 的标识符。

  • 数额:这个 HTLC 的价值。

  • 付出哈希值:由付出的接纳方创立。

  • 过期时刻:这个 HTLC 将在一定区块之后过期。

  • 洋葱包裹:为这笔付出创立的洋葱,也便是上面讲到的东西。

  • 额定的数据:用来指定额定的数据。

预备好音讯后,Alice 就把音讯发送个 Bob。收到音讯后,Bob 就能够开始解码归于自己的洋葱了。他先从洋葱包裹中取得会话密钥,然后运用它推导出跟 Alice 的同享隐秘值。

闪电网络中的 “洋葱路由” 及其工作原理

有了同享隐秘值,Bob 生成 mu key,以验证嵌在洋葱包裹中、负载的校验和。假如负载没有被篡改正,校验和应该能匹配上。

为了防止途径中的其他节点知道途径有多长,Bob 会在洋葱包裹内增加一个 1300 字节长、充满了 0 的字段。然后,Bob 从 rho key 中生成一个 2600 字节长的随机字节串。Bob 运用这个随机字节串,对填充了 0 的洋葱负载作 “异或” 运算。

还记得我怎样跟你说混杂洋葱负载的吗?运用混杂后的洋葱负载作为输入,跟相同的字节串运行 “异或” 操作,就能得到混杂前的洋葱负载。由于 Alice 和 Bob 运用相同的同享隐秘值,生成了相同的 rho key,Bob 能够解开混杂。这样做的额定优点是,它又将 1300 字节长的填充字符变成了随机字节。

Bob 解开混杂的负载中包含了他这一跳的负载数据以及一个指纹。Bob 保存这个指纹,以便将它增加到发送给 Chan 的洋葱包裹中。在 Bob 将归于自己的负载从洋葱音讯中分离出来后,他将洋葱包裹转回 1300 字节的原始巨细,并跟 Alice 相同随机化自己的会话密钥。终究,Bob 加上版别字节、会话密钥以及他预备放在洋葱负载中的指纹,就经过 update_add_htlc 音讯将洋葱包裹转发给 Chan。

这个进程会一向继续,直至音讯送到终究节点,Dina。当 Dina 收到 update_add_htlc 音讯时,她能够揣进到自己所生成的隐秘值的哈希值,这说明这个 HTLC 便是要发给她的。因而,Dina 只需查看指纹、解开洋葱音讯、揭晓归于自己的负载。

故障处理

咱们介绍的是一个成功事例,也便是一切都按部就班的事例,但假如这个进程发生了一些过错,那就有必要一路回传一条音讯,以告诉一切节点出了问题。这个进程跟惯例的洋葱路由类似。发现一个过错的故节点需求从同享隐秘值中推导出 um key,并运用它生成一个随机字节串,然后运用异或运算来混杂回来的洋葱包裹。

发现过错的节点将给付出途径的上一个节点回传一条音讯。每一跳都运用 um key 和 ammag key 作相同的操作,直到发送者收到这个包裹。终究,发送者别离运用 ammag key 和 um key 解开包裹的混杂并验证。

过错或许由洋葱包裹、节点或通道引起。假如你常常运用闪电网络,你或许遇到过这样的过错,比方 “通道不可用” 或 “手续费缺乏”。

此时快讯

【Blur:昨日平台锁仓量达1.475亿美元,创历史新高】金色财经报道,NFT 聚合市场 Blur 在社交媒体公布数据,称昨日 5 月 24 日平台锁仓量达到 1.475 亿美元,创下历史新高,目前旗下 NFT 借贷平台 Blend 中的 NFT 锁仓量占到其总锁仓量的 17%。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注