为什么自定义密码学原语对在区块链上的开发至关重要

众所皆知,区块链是一个基于密码学、经济学和网络科学的新技术。对于一般的大众来说,其中的密码学并不是一门容易亲近的学科,甚至是上面提到的三个学科中,大家觉得最有距离感的学科。但身处区块链圈的朋友们一定会常常听到「区块链是一部 Trust Machine」这样的说法,或者有人会说在区块链的世界里是「In Math we Trust」,可见密码学对于区块链技术来说是根基一样的重要存在。

好了,那么问题来了:

区块链究竟在哪些地方用到密码学呢?
密码学为什么对区块链技术至关重要?

区块链的哪些地方用到了密码学?

首先,如果你是一个区块链用户,可能在你房间里的某个角落,会有一张纸条,上面抄着十二个不知道怎么来的单词,有的人还有很多张,甚至有些大 holder 会把这十二个英文单词刻在钢板上,然后锁进保险箱里。

是的,为什么这十二个助记词,或者像一长串乱码般的私钥能够代表你对资产的所有权呢?

这背后的原理其实就是密码学原理。

我们的密钥、地址和钱包都是通过密码学去实现,利用非对称加密技术——椭圆曲线算法(ECC)可以验证某人持有的私钥是否是吻合某个公钥,通过这个方式我们可以证明这个人是否是这笔加密资产的持有人,因为除了拥有私钥的人之外,其他没有该私钥的人是没有办法解锁这笔资产的。

我们在此用比特币举例私钥、公钥和地址生成的原理,一个比特币钱包中包含一系列的密钥对,每个密钥对包括一个私钥和一个公钥。私钥通常是一个随机选出的 256 位的数字。基于私钥,我们就可以使用 secp256k1 标准的椭圆曲线这个单向密码函数产生一个公钥。基于公钥,我们又可以使用一个单向哈希函数 SHA256 和 RIPEMD160 生成比特币地址,通过 Base58 check 编码将比特币地址变成现在这较为简洁的形式。而像我们比较常用的助记词,则是再通过基于 BIP 39 标准而生成的随机英文单词。如果没有私钥或助记词的人,是无法使用这笔加密资产的。


比特币的公钥和地址的生成过程(图取自精通比特币)

当我们有了可以配对的密钥对后,可以在各种类型的钱包或者客户端上做验证,确认资产的所有权,并且通过这个客户端来进行各种资产的使用。例如最简单 BTC 转账,或者再进阶一点的用某个钱包去签署智能合约的交易:比如用 Metamask、imToken 或者 Alphawallet 等钱包里的 ETH 去购买加密猫,或者在 DeFi 的平台上面进行借贷,以及用 Uniswap 交换某些 ERC20 Token 等。

除了转账等基本的验证外,现在甚至某些平台的身份验证都可以用公私钥来做登录验证,或者通过验证你是某笔资产的所有人来进行各种权益的证明。简单来说,公私钥验证系统背后的密码学就是用户想畅游区块链世界的通行证。

在区块链中,还有另外一个不可忽视的密码学使用场景,就是区块中的交易排序, 以及 Merkle Tree 等决定区块排序的过程。比特币就是将每笔交易用 SHA256 算法进行加密,在这里加密算法确保了区块链的安全性,以及几乎不可能被篡改的特性。光是在这两个比特币的基础使用场景中就都用到了密码学,于是乎甚至还有许多人在猜测,中本聪可能是个密码学大佬,才能够把密码学在这个点对点的现金系统中使用的淋漓尽致。

当然,除了在区块的生成和公私钥验证这两大区块链的核心功能上可以发挥用途之外,密码学在隐私保护甚至扩容等方面都可以派上用场。

现在的公链如何使用密码学?

「Wow,这是一条新的公链吗?」
「那它有没有钱包啊 ?」
「又要多一组新地址和抄一组新的助记词了。。。」

如果一个用户真的愿意自己好好地保管自己的资产,也勤于投资不同的公链,我相信他们一定也会有类似的经验和好几组不同的助记词或私钥。但到最后,他们能够保存好的,可能只剩下那些最主要的持仓资产,有些人甚至忘记备份某些资产的助记词。

长期下来,区块链资产管理的问题也导致区块链的门槛越来越高。所以一些钱包为了解决这个问题,已经提出了很多的优化方案。有些钱包甚至可以做到一个身份钱包的单一助记词,可以管理多种资产等功能,但仍然有许多组不同的地址必须要由用户来做管理。这样的问题对于很多新公链而言可能更为严重,因为如果用户要去通过他们的网页或手机钱包,去尝试链上的应用,用户就会增加许多管理公私钥的成本,更何况他们不像邮箱的密码一样可以任由用户自己定义,既不滑顺也不香。

但为什么区块链会有这样的限制?

这样的限制是因为目前许多的公链,都将很多密码学原语的使用场景写入了共识层, 因此在这些公链中,像公私钥签名、客户端验证,以及区块生成的哈希和常用的加密算法,基本上都是镶嵌在共识层中的。例如地址所使用的验证、交易使用的签名等,其实都写在底层协议中,因此会变得非常难以改动。另外,许多公链的虚拟机性能都不足以支持灵活的密码学原语部署,因此对于这样的公链而言,如果底层的虚拟机不预先支持某个密码学原语,那么基于该密码学原语的场景可能很难直接被开发者使用。

如果要更动,唯一的办法就是硬分叉!

拿以太坊为例,以太坊的共识层写入了哪些密码学的场景呢?

除了区块的加密签名和 Merkle Tree 的哈希外,还有交易签名和客户端的验证。如果有任何人想要在这些点上做改动,例如将以太坊公私钥的哈希算法 keccak-256 换成其他签名算法,那么唯一的办法就是提一个 EIP (Ethereum Improvement Proposal),然后等待、祈祷这个提案被排入硬分叉之中。因为写在协议层的内容,就是全网的所有用户都必须遵从的规则。

然而硬分叉往往需要非常长的时间,以 EIP 152 为例,这是一个 2016 年就提出的提案,希望将签名算法 BLAKE2 加入以太坊中,但直到 2019 年底的伊斯坦布尔提案中才被加入到升级的内容当中,整整历时 3 年之久

从刚才 EIP 152 的例子中我们还会发现另一个限制,那就是如果要在以太坊上使用虚拟机不支持的密码学原语,几乎是不可能的。因为对于以太坊虚拟机而言性能是一大限制,光是简单的运算,就能够消耗大量的 gas。

因此我们如果回顾以太坊上历次的分叉 ,就可以发现从家园(HomeStead)的硬分叉升级开始,以太坊就不断地把所有可能常用到的密码学原语,例如 sha256 hash、ripenmd160hash 等持续的通过预编译(precompiled)的方式,加入到底层的虚拟机中。这点在拜占庭(Byzantium) 或者伊斯坦布尔(Istanbul)的升级中也可以看到。以太坊通过硬分叉的形式,来预编译密码学原语以及这些密码学原语运算的 gas 定价。

如果不通过预编译合约在节点先进行实现,那么许多签名算法的智能合约部署将花费非常非常高的 gas 费,导致其根本无法部署。例如EIP 196EIP 197 之所以被采纳,就是预见了 zkSNARK 需要大量的 gas 进行链上的运算。因此预先将这些加密算法,如椭圆曲线加法、乘法和配对验证等编译进了底层的 EVM 中,好让这些计算成本可以节省下来。所以,我们可以说在以太坊上除了已经做了预编译的签名算法外,其余的加密算法基本上是没办法使用的。

上述这些固化的密码学使用方式,对于开发者而言是一个很大的限制。

**由于交易和客户端的签名验证都被写入共识层,因此验证工具和流程都必须按照规定的加密算法进行。**例如在比特币或以太坊中,如果我们要创建一个账户,那么我们依旧需要管理一组新的密钥对。

对于想要带来良好用户体验的开发者而言,这样会产生很多的限制,并且需要通过其他方式,去弥补固化的底层设施带来的不友善的用户体验。比如在创建助记词之后,我们可以在某些钱包中使用 FaceID(如 imToken),比如在 ABC Wallet 中,用户起初只需要靠像手机里的六字验证码就能够登入,等你真的觉得你需要把私钥或助记词导出了,再进行导出和备份。

这些都是开发者试图提升用户体验所想出来的好办法,但对于每一条新的公链,密钥对管理的本质都是需要有一组新地址和密钥,这个问题是一直存在的。

上述的公私钥验证方式不够灵活的问题,在比特币、以太坊等较为先发的公链上或许还不明显,因为他们已经有既有的用户,这些用户也被折磨习惯了。但对于近期兴起的公链而言,如果还存在和先前公链同样的进入摩擦成本,那么就是给用户设置了障碍,也会影响开发者是否想要在这个公链上开发的意愿。

一个对用户有学习成本的公链,在获取用户上就存在着先天的壁垒,即使这些公链有其他的亮点,可能对于开发者而言,也不会那么有吸引力,因为他们知道很多的用户可能都被这些不友善的用户体验给吓走了。

另外,密码学原语不能够灵活使用的问题,影响的层面还不止于公私钥的保存。对于开发者而言,如果以后他们想用更先进的密码学原语来保证隐私及安全,一样会面临到底层的虚拟机能不能部署,以及支持签名验证的挑战。 当然还会影响目前大家讨论的很热的话题:跨链,因为不同的链使用的密码学原语也会有所不同,在虚拟机验证交易时就会遇到这个难题,这也是为什么目前许多同构跨链的解决方案(Cosmos / Polkadot )可行,但对于异构跨链的方案却停滞不前的原因。

Nervos 的设计有何不同

在 Nervos CKB 中,除了交易排序外,没有其他硬编码的密码学原语,资产所有权的验证是通过 cell 中的 lock script 来做验证,其中的验证规则和使用的密码学原语都是可以自定义的,因此几乎所有的密码学原语都可以被开发者灵活的使用。

套用一句 Nervos 研究员 Cipher 老师的话来说,就是:「在 CKB 上除了最基础的交易排序以外,其余都是应用层的内容。」 这让开发者拥有了非常大的开发弹性,去进行各式各样的开发,例如更自由的账户验证方法等。

因为在基于 RISC-V 的 CKB-VM 中,要求的就是一套能够符合 RISC-V 编码的验证规则而已,开发者有很多能够自由挥洒的空间。下图可以看出 Nervos 和其他可以支持智能合约的公链在灵活度上的差异,应用层的内容表示的是可以去做自定义的,协议层代表的是需要经过「分叉」才能改动的内容。


以目前 Nervos 的 Grnats 团队 Lay2 为例,为什么他们开发的 pw-sdk 能够用以太坊的地址,甚至是 ENS 来接收 CKB?是因为在 CKB 上,地址是开发者可以任意把玩的应用层内容。理论上只要链上有已经有验证规则的 cell 和非对称加密的加密算法库,这种地址生成规则就能够被验证。例如我们可以把以太坊的 Keccak-256 (SHA-3)的签名算法和验证规则和比特币的 SHA-256 都部署在链上,那么未来的其他开发者就可以用 cell deps 进行调用。

也因此,任何的开发者未来如果想在 CKB 上 ,为他的资产添加更先进的加密算法做为解锁的规则,是完全可行的,因为任何人都可以部署各种密码学原语库在 CKB 上,并且可以通过优化去节省存储空间以及减少验证所需的 cycle 去降低部署的成本,让任何先进的密码学原语不用等到硬分叉也能够被使用。

在 CKB 上可能看见的区块链未来:直逼互联网的用户体验

基于灵活的密码学原语,我们可以说在未来,很多互联网上用户非常习惯的验证规则,也完全可能被写成 RISC-V 可以读取的形式,并且被部署到链上,例如 PGP Key 验证或者指纹解锁等功能。如果在链上有一个能够对应他们所使用的验证标准的脚本,并且有可以支援这种验证的可信环境,那么如此方便的使用方式在未来是真的可能实现的。

再更深入一点地看,未来的应用层,会有更多的场景会使用到密码学的各种算法。

近两年在分层扩容的领域(Layer 2),除了原先的闪电网络、状态通道以及其他的侧链解决方案之外,又出现了一种新兴的密码学扩容应用:Rollup,也就是利用签名算法来压缩交易。

目前在 Rollup 上最主流的压缩交易的方式是零知识证明 (zkp),也就是所谓的 zkRollup。未来如果在 Rollup 上有其他更先进的零知识证明解决方案,或者利用其他去签名算法(如 BLS 等),对于 CKB 而言,只要开发者可以想到低成本的实现方法,都可以直接让 CKB-VM 验证,而不需要通过硬分叉。因为这并不涉共识层的内容,而且 CKB-VM 相较于 EVM 而言也更加地高效。目前安比实验室也在开发在 CKB 上可使用的零知识证明库,未来可供开发者任意使用。

另外,CKB 因为可以支持灵活的密码学原语,也在区块链跨链资产转移方面,比其它的公链有更大的先天优势进行来自不同链的交易验证,让 CKB 更有机会完成异构跨链的资产流通与转移。

打从中本聪的比特币白皮书问世开始,区块链就是一个可以在中心化的环境下用密码学去证明共识的新技术,这是在互联网上无法完成的事情。但要大规模的使用区块链,我们要做的不是让用户在体验上委曲求全,而是像 Lay2 团队的 Frank 说的那样:「 我们需要一个能够有能力去支持开发者‘开门迎客’的基础设施」,让区块链不会因为底层设施的不灵活,而成为少数极客或圈内人的玩物。

公链如果能够灵活的支持各种密码学原语,让开发者可以有更高的弹性,那么就更可以跳过「教育用户」的这个傲慢的过程。因为就和互联网一样,虽然现在大家都是无网不欢的人,但对于纯粹的 C 端用户而言,他们依旧不需要知道互联网到底分了几层,或者 P2P 网络是怎么回事。

同样的,区块链的纯 C 端用户在使用区块链技术时也不需要知道区块链的底层知识,我们要做的是打造一个可以拥有互联网体验,又有区块链的凭证,以及安全和去中心化等加成效果的基础设施,而具有高度编程灵活性的 Nervos CKB 正在这条道路上奋勇向前。

注:谢谢 Lay2 的知县,SECBIT 的志鹏,史迪仔等人对本篇文章的意见和启发

source:

  1. https://eips.ethereum.org/EIPS/eip-152

  2. https://github.com/ethereum/go-ethereum/blob/a5eee8d1dc61352c29b9800eaf96609ba4184fd6/core/vm/contracts.go#L39-L78

  3. https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/

  4. https://blog.ethereum.org/2019/11/20/ethereum-istanbul-upgrade-announcement/

  5. https://eips.ethereum.org/EIPS/eip-196

  6. https://eips.ethereum.org/EIPS/eip-197

  7. https://ethresear.ch/t/when-do-we-need-cryptography-in-blockchain-space/7450

  8. https://github.com/ethereum/go-ethereum/blob/a5eee8d1dc61352c29b9800eaf96609ba4184fd6/core/vm/contracts.go#L39-L78

  9. https://medium.com/cryptocow/以太坊-istanbul-硬分叉內容介紹-4e0a37fa420c

  10. Lay2 - pw-sdk - Build DApps on CKB and Run Them Everywhere

  11. SECBIT Labs - zkp-toolkit-ckb - a Zero-Knowledge Proof toolkit for CKB

5 Likes