写点什么

一文详解门限签名的技术原理与落地实践

  • 2022-08-26
    北京
  • 本文字数:3944 字

    阅读完需:约 13 分钟

一文详解门限签名的技术原理与落地实践

什么是门限签名

 

区块链技术与签名算法缔结颇深,从安全、效率到流通,签名算法都在影响着区块链网络的特性及稳定。个人及机构对账户密钥管理的需求逐渐强烈,也催生出一批相关应用,对于用户而言,管理签名其实就是管理密钥。而在多链的情况下,多签或许不是密钥管理的最佳选择——用多签通过合约的方式来管理密钥,使用成本高,安全风险高。除了多签技术之外,在区块链世界中逐渐兴起的门限签名技术也是一种重要的共识工具。

 

门限签名(Threshold Signature Scheme,TSS)是数字签名的一个重要分支,它是一种基于安全多方计算(Secure Multi-Party Computation,MPC)的密码学技术,也是 MPC 密钥管理的重要研究方向。

 

门限签名特点是一个签名一定是由一个私钥产生,然而这个私钥不会被任何人完整掌握,而是会以某种方式分成很多碎片,这些碎片可以被多人同时持有,然后通过 MPC 协议,保证这些碎片不需要全部被拼起来就可以直接产生一个合法的签名。

 

图 1 区块链上的 MPC 门限签名技术


在与区块链的结合应用中,门限签名的优势在于签名的生成是通过链下的 MPC 协议产生的,其结果是更加安全,避免了合约被黑客攻击的风险。因为门限签名与合约模块是完全解耦的,合约不需要理解签名的协议,它只要确认签名的有效性,这与传统的合约验签模式完全一致的。此外,合约的设计策略可以更加灵活,因为除了验签外的大部分流程都搬到了链下,使用方可以根据场景制定自己的碎片管理策略。


另一个重要的应用场景是密钥管理。基于 MPC 的密钥管理,一方面可以安全地存储密钥,单一或者小批量碎片的丢失,不会对该密钥的安全性有任何影响;另一方面是让个人或者企业能够更方便、更安全、满足业务逻辑地使用密钥。

门限签名的算法原理与落地实践

 

目前针对门限签名的研究机构数量在递增,但已达到产品级标准的不多,本次我们以 Open TSS 为例详解门限签名。

 

Open TSS 由 LatticeX Foundation 发起和支持,理论依据来源于发表在顶级密码会议(Asiacrypt 2021)的论文 DMZ+21,目前 Open TSS 最新协议代码库正式开源上线,代码采用安全高效的 Rust 实现,支持一站式 ECDSA MPC 密钥生成(Keygen)、MPC 签名(Sign)。



可以看到当前版本(0.1.2)支持 ECDSA,其他算法如 EdDSA、BLS 等将很快被整合。下面我们介绍基于 [DMZ+21] 的多方 ECDSA。

多方 ECDSA

ECDSA 被广泛用于密码货币,如 BTC、Ethereum(secp256k1 曲线)等。


多方 ECDSA 协议({ t, n }-门限签名方案),它允许 n 个参与方联合生成一个共同的公共验证密钥,以及 n 份相应的秘密签名密钥,并允许任何至少由 t + 1 个参与方组成的子集安全地分布式签署一个给定的消息,而 t 个或更少的参与方组成的集合则不能进行签名。


本库中的多方 ECDSA 协议是基于类群实现的。它目前包括两个协议:

  • 密钥生成,用于创建秘密分片。

  • 签名,用于使用秘密分片来生成签名。这可以分为两个阶段,离线和在线。

  • 离线阶段与要签名的信息无关,可以提前计算。

  • 只需将信息(和离线阶段的输出)传递给在线阶段,就可以很快得到签名。

功能使用

目前,ECDSA 由两个功能模块组成,包括密钥生成、签名,签名功能分为离线阶段与在线阶段。

在使用上,对于上面的每个功能,只需要三个步骤。这里假设 (t, n) = (1, 3),参与方的 id 为 1, 2, 3,分别以 P1,P2,P3 表示。

密钥生成

第 1 步。新建一个 KeyGenPhase 对象。

let partyid = "1".to_string(); // P2, P3 are similar. let params = Parameters {threshold: 1,share_count: 3,};let party_ids = vec!["1".to_string(), "2".to_string(), "3".to_string()];let mut keygen = KeyGenPhase::new(partyid, params, &Some(party_ids)).unwrap();
复制代码

第 2 步。通过调用 process_begin 开始,它返回下一轮要发送的信息。

let sending_msg: SendingMessages = keygen.process_begin().unwrap();
复制代码

根据 SendingMessages 的类型(广播,P2P 等)和内容,我们可以将索引(from)和消息(msg)一起打包发送给其他参与者。

match sending_msg { SendingMessages::BroadcastMessage(msg) => {// broadcast the msg to all(including self).}SendingMessages::P2pMessage(msg) => {// send according to the k,v in the msg. k is the index which v will to be sent to.}SendingMessages::SubsetMessage(msg) => {// send according to the k in the party_ids or subset(used in sign phase). k is the in}_ => {}}
复制代码

第 3 步: 通过 msg_handler 处理消息。

当收到消息后,会得到 recv_from 和 recv_msg,然后把它们传给 msg_handler,它返回一个结果或下一轮要发送的消息。

loop {// let (recv_from, recv_msg) = According to the last round of SendingMessages let recv_from = "".to_string();let recv_msg = vec![0u8];let sending_msg = keygen.msg_handler(recv_from, &recv_msg).unwrap(); match sending_msg {SendingMessages::KeyGenSuccessWithResult(msg) => {// got the keygen result break;}_ => {// other sending messages, ref Step 2.}}}
复制代码

一旦收到 SendingMessages::KeyGenSuccessWithResult ,就表示此阶段完成。这里是一个密钥生成的样例:

{"index": "1", "participants": ["1","2","3"],"pubkey": {"pk": [ "10ec64d0a73c134c53ed764e86743397bab3bb06bdbbd638321b87eda9c6614e", "6b7df1b8b41c41fc69fef0d87fc8ee9d01c021936d3b44cd62883894cd60de14"],"share_pks": {"1": ["7a39ace81396d9c65dfb8f4c8ebdf3d5850447e129edbac052558b483b01ba52", "d942c292f40e65715f722b1db87d0ceaa122f9d6457eacffbd021653b0a6f65"], "2": ["6b31a24d2705971d18fffbdc2edbf4e97d01c2b4aea75df2a01566f03c269804", "5f94b59a0a97d604e356ca21c27b64c0f5dfc4e8315e4be8179c5292a8b6d015"], "3": ["79a7c9632cbfd98f890d9d4670ac301fda42db178b9b8ec2a2860e44488130da", "af7d69f73529d8235ae6dc9f896bd81830777ff9667d9ab1fc5b37599c712378"]}},"privkey": {"cl_sk": "1b557b69c49c0715403f618907a051c012adc57e9ea6b17aa912d68b6056b1d24b5c10a36269ac03 "ec_sk": "a23ae304a46c36bbf52e1373daa4446dda3f3b1b721a77c84a2ec86f54e6970c","share_sk": "f869bd11e46d036cdd81ad9940c9d510d24114bba12edfa626a966677058ff5a"}}
复制代码

签名-离线阶段

第 1 步。与密钥生成类似,新建一个 SignPhase 对象。

let partyid = "1".to_string(); // P2, P3 are similar. let params = Parameters {threshold: 1,share_count: 3,};let subset = vec!["1".to_string(), "2".to_string()]; // The set of parties that involved in si let keygen_result = "".to_string(); // The output of KeyGenlet mut signoffline = SignPhase::new(partyid, params, &subset, &keygen_result).unwrap();
复制代码

这里的 subset 就是参与签名的各方集合,是所有参与密钥生成的一个子集。

第 2 步、第 3 步:与密钥生成一样。当收到 SendingMessages::SignOfflineSuccessWithResult ,就表示此阶段完成。

签名-在线阶段

第 1 步。类似的,新建一个 SignPhaseOnline 对象。

let offline_result = "".to_string(); // The output of SignOfflinelet message_bytes = vec![0u8; 32]; // The hash value of the message to be signed, 32 bytes. let mut signonline = SignPhaseOnline::new(&offline_result, message_bytes).unwrap();
复制代码

第 2 步、第 3 步:与密钥生成、签名离线阶段一样。当收到 SendingMessages::SignOnlineSuccessWithResult ,就表示此阶段完成。

  • 从安全角度考虑,离线阶段的结果只能使用一次。

  • 整个在线阶段只需要几毫秒即可完成。


这里是一个签名的样例:

{"s": "14af6f72d8bd26faccd75ff092544d15a3dce5d97e897773b515cd70ab0453e7", "r": "3687024517eb44de2cfaa6166866c9bd2587090317a4d12521b571c7509319b4","recid": 0}
复制代码

一份本地代码显示了如何使用这些功能。参考这里了解更详细的使用说明。

性能表现

我们来看看 OpenTSS 的性能如何,与最先进的协议进行比较。为了进行公平的比较,我们用 Rust 实现了两个多方 ECDSA,包括我们的协议和 [CCL+20] 中的协议。椭圆曲线是 secp256k1,类群的判别式的位长选择为 1827,这确保了我们的协议具有 128 位的安全性。运行时间是在 Intel(R) Core(TM) i7-9700K @ 3.6GHz 的单核上测量的。



如上表(来自论文第 7 节)所示,进行了具体比较。与基本上基于 [GG18] 的 [CCL+20] 相比,可以看到 OpenTSS 的多方 ECDSA 协议的改进是非常明显的。它主要体现在密钥生成阶段。


在计算复杂度方面,OpenTSS 的多方 ECDSA 协议比 [CCL+20] 中的协议在 κ = 40(κ = 128) 时的密钥生成阶段快 4 倍(12 倍),这在理论(详见论文)和具体方面都可以看到。OpenTSS 构造的签名阶段比 [CCL+20] 中的略好,在具体方面大约快 10%。


在通信方面,由于 OpenTSS 消除了昂贵的交互式设置阶段的需要,OpenTSS 的协议在密钥生成阶段优于 [CCL+20] 中的协议,其差异根据参与方的数量 n 和门限 t 而变化。虽然在签名阶段通信开销稍大,但 OpenTSS 的解决方案仍然是同一数量级的。

总结

可以看出,门限签名协议将成为众多机构持续投入研究的方向、为开源社区做贡献、在不远的将来,相信以 Open TSS 为代表的产品将向区块链安全技术服务商的方向发展,为区块链钱包、托管企业提供底层架构服务。


Open TSS 项目地址:https://github.com/LatticeX-Foundation/opentss


参考文献

1. Promise Σ-protocol: How to Construct Efficient Threshold ECDSTSSA from Encryptions Based on Class Groups.


相关课程:

ZK 训练营第一课:ZKP 密码学基础知识

ZK 训练营第二课:ZKP 经典协议

ZK 训练营第三课:ZKP 电路应用导论

ZK 训练营第四课:基于 ZK 协议的机器学习隐私保护设计

2022-08-26 14:5211674

评论

发布
暂无评论
发现更多内容

真香!霸榜掘金首页第一,阿里内部Java性能调优笔记终于开源了

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

由于太全被各大厂要求Github连夜下架

Java架构师迁哥

网络协议之NAT穿透原理

Linux服务器开发

网络协议 p2p NAT Linux服务器开发 网络穿透

实时数据引擎系列(五): 关于 SQL Server 与 SQL Server CDC

tapdata

发布60分钟!霸榜Github的阿里面试参考指南,啃透涨薪10k

Java架构师迁哥

The Data Way Vol.4|开源是创造软件诸多方法中最好的一种形式

SphereEx

数据库 开源

openGauss X ShardingSphere,分布式方案的另一种最佳实践

SphereEx

数据库 开源

Filecoin算力矿池挖矿系统开发案例

薇電13242772558

区块链 IPFS

2021全球高性能云计算创新大赛,9月15日重磅启动!

亚马逊云科技 (Amazon Web Services)

云计算

JavaScript进阶(二)上

Augus

JavaScript 9月日更

云备份和恢复的优缺点

云计算

北鲲云超算平台为何能够被高性能计算行业认可?

北鲲云

阿里P8手抄本惨遭泄露,并出现病毒式传播,致28人斩获大厂offer

Java架构师迁哥

一位年薪 180 万的字节大佬扔给我的四份学习笔记

Java架构师迁哥

足足541页!费了大力气才从GitHub上扒下的阿里Java优化“圣经”

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

开源即巅峰!阿里首次分享:Java架构师全栈“成长笔记”

Java架构师迁哥

探秘 JavaScript 世界的神秘数字 1.7976931348623157e+308

清秋

JavaScript 大前端 浮点数 引航计划 IEEE754

中原银行分布式批处理调度平台介绍

中原银行

分布式 批处理 中原银行

GitHub获120w+star的JDK源码剖析手册,竟出自Alibaba高管之手?

Java 程序员 架构 面试 Alibaba

32岁的我裸辞了,八年Java老鸟,只因薪水被应届生倒挂,在闭关三个月后拿到阿里Offer,定级P7!

Java架构师迁哥

Flutter IM跨端架构设计和实现

OpenIM

GitHub星标70K阿里大佬手写的Spring Boot实战手册

Java架构师迁哥

诧异!GitHub上竟有阿里专家用800页笔记,只讲MySQL调优而且火了

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

牛客网论坛最具争议的Java面试成神笔记,看过的人都已经成功进入大厂

Java 编程 程序员 架构 面试

网络攻防学习笔记 Day137

穿过生命散发芬芳

网络基础 9月日更

如何获取系统错误报告--Bug Report

Changing Lin

9月日更

一文揭示,DevOps与企业数字化究竟有何联系?

SoFlu-JavaAI开发助手

DevOps 自动化 软件工程

“京东商城”亿级高并发秒杀系统到底是怎么设计的?自己做该如何下手?

Java架构师迁哥

炸了!阿里又一力作上传GitHub,Spring Cloud Alibaba差距不止一点

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

Vue进阶(幺幺贰):package-lock.json 文件解析

No Silver Bullet

Vue 9月日更

如何高效学习 Kubernetes 知识图谱?

阿里巴巴云原生

Kubernetes 容器 云原生

一文详解门限签名的技术原理与落地实践_区块链_LatticeX基金会_InfoQ精选文章