1个不稳定版本
0.8.1 | 2023年6月20日 |
---|
#11 在 #ecdsa-signature
用于 redgold
1MB
8K SLoC
多党ECDSA
本项目是Rust语言实现的{t,n}门限ECDSA(椭圆曲线数字签名算法)。
门限ECDSA包括两个协议
- 密钥生成,用于创建秘密份额。
- 签名,用于使用秘密份额生成签名。
ECDSA被广泛用于比特币、以太坊(secp256k1曲线)、NEO(NIST P-256曲线)等加密货币。本库可用于创建多签名和多门限签名加密钱包。有关门限签名的完整背景,请阅读我们的Binance学院文章门限签名解释。
库介绍
本库在设计时考虑了四个核心设计原则
- 多协议支持
- 为密码工程师构建
- 无懈可击
- 密码原语的黑盒使用
要了解核心原则以及库的审计过程和安全,请阅读我们的多党ECDSA库介绍博客文章。
使用它
本库实现了四种不同的门限ECDSA协议。这些协议在参数、安全假设和效率方面具有不同的权衡。
协议 | 高级代码 |
---|---|
Lindell 17 [1] | Gotham-city(被CIW19接受)是一个包含基准测试的两方比特币钱包。KMS是一个Rust包装库,实现了通用两方密钥管理系统。thresh-sig-js是一个JavaScript SDK |
Gennaro, Goldfeder 19 [2](视频) | tss-ecdsa-cli 是一个针对完整阈值访问结构的包装命令行工具,包括网络和阈值HD密钥(BIP32)。参见该库中的演示以获得更好的底层理解。 |
Castagnos 等人 19 [3] | 当前作为该库的功能启用。要启用,使用 --features=cclst 构建。要测试,使用 cargo test --features=cclst -- --test-threads=1 |
Gennaro, Goldfeder 20 [4] | 一种支持识别恶意方的完整阈值协议。如果签名失败,则返回恶意方列表。该协议仅需一个广播频道(所有消息都广播出去)。 |
运行 GG20 演示
在以下步骤中,我们将生成 2-of-3 阈值签名密钥,并用 2 个当事人签名一个消息。
设置
-
- 运行
cargo build --release --examples
- 如果没有安装 GMP,请使用此命令代替
但请注意,这将效率较低。cargo build --release --examples --no-default-features --features curv-kzen/num-bigint
任意命令都会将二进制文件生成到
./target/release/examples/
文件夹。 - 运行
-
cd./target/release/examples/
启动 SM 服务器
./gg20_sm_manager
这将在一个 http://127.0.0.1:8000
的 HTTP 服务器上启动。其他当事人将使用该服务器相互通信。请注意,通信渠道既未加密也未进行身份验证。在生产中,您必须加密并验证当事人的消息。
运行密钥生成
为每个当事人打开 3 个终端标签。运行
./gg20_keygen -t 1 -n 3 -i 1 --输出local-share1.json
./gg20_keygen -t 1 -n 3 -i 2 --输出local-share2.json
./gg20_keygen -t 1 -n 3 -i 3 --输出local-share3.json
每个命令对应一个当事人。一旦密钥生成完成,您将拥有 3 个新文件:local-share1.json
、local-share2.json
、local-share3.json
,分别对应每个当事人的本地密钥份额。
运行签名
由于我们使用 2-of-3 方案(t=1 n=3
),任何两个当事人都可以签名一个消息。运行
./gg20_signing -p 1,2 -d "hello" -llocal-share1.json
./gg20_signing -p 1,2 -d "hello" -llocal-share2.json
每个当事人将产生一个结果签名。 -p 1,2
指定了参加签名的当事人的索引(每个当事人都有一个在密钥生成时给出的关联索引,见参数 -i
),--l file.json
设置了一个包含秘密本地份额的文件的路径,而 --d "hello"
是被签名的消息。
在不同的计算机上运行演示
虽然前面的步骤展示了如何在本地计算机上运行密钥生成和签名,但实际上您可以在专用机器上运行每一方。为此,您应确保各方可以访问SM服务器,并通过命令行参数指定其地址,例如
./gg20_keygen --地址http://10.0.1.9:8000/ ...
运行GG18演示
以下步骤用于设置,使用n
个参与方进行密钥生成和用t+1
个参与方进行签名。
设置
-
我们使用共享状态机架构(参见白城)。可以通过更改文件:
param
来配置参数parties
和threshold
。密钥生成将以parties
个参与方运行,签名将以threshold+1
个参与方的任意子集运行。param
文件应位于客户端软件相同的路径中。 -
安装Rust。运行
cargo build --release --examples
(它将构建到/target/release/examples/
) -
运行共享状态机:
./gg18_sm_manager
。默认情况下,它配置为在127.0.0.1:8000
,这可以在Rocket.toml
文件中更改。Rocket.toml
文件应位于您运行sm_manager
的同一文件夹中。
密钥生成
按照以下方式运行gg18_keygen_client
:./gg18_keygen_client http://127.0.0.1:8000 keys.store
。将IP和端口替换为设置中配置的值。一旦n
个参与方加入,应用程序将运行到完成。最后,每个参与方将获得一个本地密钥文件keys.store
(在命令行中更改文件名)。该文件包含密钥生成后各方的秘密和公开数据。因此,该文件应保持私密。
签名
运行./gg18_sign_client
。应用程序应位于与keys.store
文件(或在密钥生成中生成的自定义文件名)相同的文件夹中。应用程序接受三个参数:IP:port
,如密钥生成所示,filename
和要签名的消息:./gg18_sign_client http://127.0.0.1:8001 keys.store "KZen Networks"
。所有签名者应使用相同的消息。一旦t+1
个参与方加入,协议将运行,并将签名(R,s)输出到屏幕。
./gg18_sign_client
可执行文件最初会尝试将其输入消息(第三个参数)反十六进制化。在运行之前,请确保以下两点:
- 如果您要传递要签名的二进制消息,请将其十六进制化。
- 如果您想以非十六进制形式传递文本消息,请确保它不能被反汇编。简单来说,使用签名二进制文件最安全的方法是在将消息传递给
./gg18_sign_client
可执行文件之前始终将其转换为十六进制。
示例
要签名消息 hello world
,首先计算其十六进制表示形式。这将产生 68656c6c6f20776f726c64
。然后,运行
./gg18_sign_client http://127.0.0.1:8000 keys.store "68656c6c6f20776f726c64"
GG18 演示
在主目录中运行 ./run.sh
(位于 /demo
文件夹中)。将 params
文件移动到与可执行文件相同的文件夹(通常为 /target/release/examples
)。脚本将启动一个共享状态机,客户端数量以及为 threshold + 1
的第一个参与者进行签名请求。
gg18_sm_manager
火箭服务器默认以 生产 模式运行。您可以通过修改 ./run.sh
来配置它在不同环境中运行。例如,要运行火箭服务器在 开发
ROCKET_ENV=development ./target/release/examples/sm_manager
贡献与发展流程
贡献工作流程在 CONTRIBUTING.md 中描述,此外,Rust 工具 wiki 包含有关工作流程和环境设置的更多信息。
许可证
Multi-party ECDSA 在 GPL-3.0 许可证的条款下发布。有关更多信息,请参阅 LICENSE。
联系方式
请随时 联系 或加入 ZenGo X Telegram 讨论代码和研究。
参考文献
[1] https://eprint.iacr.org/2017/552.pdf
[2] https://eprint.iacr.org/2019/114.pdf
依赖关系
~18MB
~323K SLoC