写点什么

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

  • 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:5211436

评论

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

【SimpleFunction系列二.3】Redisson分布式锁8种锁模式剖析

莫逸风

分布式锁 redisson 分布式锁

SRv6在SFC中的应用

穿过生命散发芬芳

8月月更 SRv6

使用 Google Breakpad 来助力解决程序崩溃

HelloWorld杰少

ios 游戏开发 崩溃分析 google_breakpad 8月月更

Linux实用命令lsof命令

flow

8月月更

GitLab 自动删除项目?仅需四步,丝滑迁移至极狐GitLab

极狐GitLab

git DevOps gitlab 敏捷开发 极狐GitLab

架构师第一课,一文带你玩转ruoyi架构

小鲍侃java

框架 Java web 构架 spring-boot 签约计划第三季

动手实操,让你的 Kubernetes 集群弹起来!

以尘

弹性 ACK Kubernetes 集群 ClusterAutoscaler Erda

为什么我们需要关注基于 EIP-3664 标准的可拆分,可组合的NFT?

股市老人

RocketMQ顺序消息之消息消费

急需上岸的小谢

8月月更

离线渲染与实时渲染杂谈——从发布会上的产品展示说起

3DCAT实时渲染

企业为何要实行知识管理?

Baklib

开源一夏 | AngularJS对于SQL的操作心得以及DOM的研究

恒山其若陋兮

开源 8月月更

一篇文章让你重学HTTP!

Albert Edison

https 计算机网络 HTTP 8月月更

Mysql命令大全

跳楼梯企鹅

MySQL #数据库

Redis 基础

武师叔

8月月更

每日一R「05」生命周期

Samson

学习笔记 8月月更 ​Rust

大数据技术生态,不懂你捶我

大数据指北

大数据 大数据开发

ASP.NET Core SignalR概述

辣么大

.net SignalR 8月月更

高效能团队的Java研发规范(进阶版)

木小风

编程规范 Java core

王熙凤穿越到 2022 年,一定会采购的单点登录服务

Authing

企业中的知识管理价值是怎样体现的

Baklib

开源一夏 | 腾讯云对象存储cos获取图片像素信息

六月的雨在InfoQ

腾讯云 开源 COS 8月月更

Spring Cloud Stream简介

阿泽🧸

spring cloud stream 8月月更

鸿蒙设备开发之从0到1联网上云-概述篇

愚公搬代码

签约计划第三季

纳瓦尔宝典:财富与幸福指南

石云升

读书笔记 财务自由 幸福 8月月更

(WebFlux)002、如何打印日志与链路ID

编号94530

spring 日志 aop SpringWebflux Reactor3

私有化输出的服务网格我们是这样做的

阿里巴巴云原生

阿里云 Kubernetes 云原生 服务网格

MobTech ShareSDK 使用简介

MobTech袤博科技

开发者 sdk MobTech袤博科技

企业与团队怎样建立一个有效的、切实可行的知识管理系统

Baklib

《Effective Java》第9条:try-with-resources优先于try-finally

okokabcd

Java

数据结构——队列

工程师日月

8月月更

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