23 个版本

0.3.26 2024 年 7 月 30 日
0.3.22 2024 年 6 月 12 日
0.3.17 2024 年 3 月 26 日
0.3.10 2023 年 11 月 27 日
0.2.0 2022 年 12 月 16 日

#1284魔法豆

Download history 147/week @ 2024-04-15 16/week @ 2024-04-22 4/week @ 2024-04-29 351/week @ 2024-05-13 205/week @ 2024-05-20 279/week @ 2024-05-27 39/week @ 2024-06-03 178/week @ 2024-06-10 94/week @ 2024-06-17 38/week @ 2024-06-24 27/week @ 2024-07-01 3/week @ 2024-07-08 141/week @ 2024-07-15 1/week @ 2024-07-22 301/week @ 2024-07-29

每月 446 次下载
用于 2 个 crates(通过 mithril-common

Apache-2.0 和可能 LGPL-3.0+

155KB
3K SLoC

Mithril-stm CI 工作流程 crates.io Discord

这是一个正在进行中的项目 🛠

  • mithril-stm 是 Pyrros Chaidos 和 Aggelos Kiayias 撰写的论文 Mithril: Stake-based Threshold Multisignatures 中所描述方案的 Rust 实现。

  • 此实现使用 BLS12-381 签名库 blst 作为 STM 的后端。

  • 此实现支持 平凡的连接证明系统(第 4.3 节)。其他如 BulletproofsHalo2 等证明系统在此版本中不支持。

  • 我们实现了连接证明系统作为批量证明

    • 单个签名不包含证明 avk 成员的 Merkle 路径。相反,这是聚合器的职责生成此类证明。这允许更有效地实现批量成员证明(或批量 Merkle 路径)。
  • 协议文档请参考 Mithril 协议深入解析

  • API 还包括 核心验证 功能。此功能允许一个全节点验证器 (CoreVerifier) 验证生成的签名,而不需要注册信息,即 avk。假设 CoreVerifier 已知签名人身份,因此它不需要检查注册。

  • 本库提供以下功能

    • 基于权益的阈值多重签名的实现
    • CoreVerifier 的实现
    • STM 签名的关键注册流程
    • 库函数、STM 方案和 CoreVerifier 的测试
    • 基准测试

先决条件

安装 Rust

  • 安装一个正确配置的 Rust 工具链(最新稳定版本)。

  • 安装构建工具 build-essentialm4。例如,在 Ubuntu/Debian/Mint 上,运行 sudo apt install build-essential m4

下载源代码

# Download sources from github
git clone https://github.com/input-output-hk/mithril

# Go to sources directory
cd mithril-stm

编译库

cargo build --release

运行测试

要运行 rust 测试,只需运行(为了更快地运行测试,建议使用 --release 标志)

cargo test --release

运行基准测试

cargo bench

示例

以下是一个 STM 实现的简单示例

use mithril_stm::key_reg::KeyReg;
use mithril_stm::stm::{StmClerk, StmInitializer, StmParameters, StmSig, StmSigner};
use mithril_stm::AggregationError;

use blake2::{digest::consts::U32, Blake2b};
use rayon::prelude::*;
use rand_chacha::ChaCha20Rng;
use rand_core::{RngCore, SeedableRng};

type H = Blake2b<U32>;

fn main() {
    let nparties = 32;
    let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
    let mut msg = [0u8; 16];
    rng.fill_bytes(&mut msg);

    //////////////////////////
    // initialization phase //
    //////////////////////////

    let params = StmParameters {
        k: 357,
        m: 2642,
        phi_f: 0.2,
    };

    let parties = (0..nparties)
        .into_iter()
        .map(|_| 1 + (rng.next_u64() % 9999))
        .collect::<Vec<_>>();

    let mut key_reg = KeyReg::init();

    let mut ps: Vec<StmInitializer> = Vec::with_capacity(nparties as usize);
    for stake in parties {
        let p = StmInitializer::setup(params, stake, &mut rng);
        key_reg.register(stake, p.verification_key()).unwrap();
        ps.push(p);
    }

    let closed_reg = key_reg.close();

    let ps = ps
        .into_par_iter()
        .map(|p| p.new_signer(closed_reg.clone()).unwrap())
        .collect::<Vec<StmSigner<H>>>();

    /////////////////////
    // operation phase //
    /////////////////////

    let sigs = ps
        .par_iter()
        .filter_map(|p| p.sign(&msg))
        .collect::<Vec<StmSig>>();

    let clerk = StmClerk::from_signer(&ps[0]);
    let avk = clerk.compute_avk();

    // Check all parties can verify every sig
    for (s, p) in sigs.iter().zip(ps.iter()) {
        assert!(s.verify(&params, &p.verification_key(), &p.get_stake(), &avk, &msg).is_ok(), "Verification
        failed");
    }

    // Aggregate with random parties
    let msig = clerk.aggregate(&sigs, &msg);

    match msig {
        Ok(aggr) => {
            println!("Aggregate ok");
            assert!(aggr.verify(&msg, &clerk.compute_avk(), &params).is_ok());
        }
        Err(AggregationError::NotEnoughSignatures(n, k)) => {
            println!("Not enough signatures");
            assert!(n < params.k && k == params.k)
        }
        Err(AggregationError::UsizeConversionInvalid) => {
            println!("Invalid usize conversion");
        }
    }
}

基准测试

这里给出了 STM 在大小和时间上的基准测试结果。我们在 macOS 12.6 上运行基准测试,使用的是配备 16 GB RAM 的 Apple M1 Pro 机器。

注意,单个签名的大小(只有一个有效索引)为 72 字节(来自 sigma 的 48 字节,来自 party_index 的 8 字节,获胜索引长度的 8 字节以及至少 8 字节的单个获胜 index),随着有效索引长度的增加而线性增长(其中索引为 8 字节)。

+----------------------+
| Size of benchmarks   |
+----------------------+
| Results obtained by using the parameters suggested by the paper.
+----------------------+
+----------------------+
| Aggregate signatures |
+----------------------+
+----------------------+
| Hash: Blake2b 512    |
+----------------------+
k = 445 | m = 2728 | nr parties = 3000; 118760 bytes
+----------------------+
| Hash: Blake2b 256    |
+----------------------+
k = 445 | m = 2728 | nr parties = 3000; 99384 bytes
+----------------------+
+----------------------+
| Aggregate signatures |
+----------------------+
| Hash: Blake2b 512    |
+----------------------+
k = 554 | m = 3597 | nr parties = 3000; 133936 bytes
+----------------------+
| Hash: Blake2b 256    |
+----------------------+
k = 554 | m = 3597 | nr parties = 3000; 113728 bytes
STM/Blake2b/Key registration/k: 25, m: 150, nr_parties: 300
                        time:   [409.70 ms 426.81 ms 446.30 ms]
STM/Blake2b/Play all lotteries/k: 25, m: 150, nr_parties: 300
                        time:   [696.58 µs 697.62 µs 698.75 µs]
STM/Blake2b/Aggregation/k: 25, m: 150, nr_parties: 300
                        time:   [18.765 ms 18.775 ms 18.785 ms]
STM/Blake2b/Verification/k: 25, m: 150, nr_parties: 300
                        time:   [2.1577 ms 2.1715 ms 2.1915 ms]

STM/Blake2b/Key registration/k: 250, m: 1523, nr_parties: 2000
                        time:   [2.5807 s 2.5880 s 2.5961 s]
STM/Blake2b/Play all lotteries/k: 250, m: 1523, nr_parties: 2000
                        time:   [5.9318 ms 5.9447 ms 5.9582 ms]
STM/Blake2b/Aggregation/k: 250, m: 1523, nr_parties: 2000
                        time:   [190.81 ms 191.15 ms 191.54 ms]
STM/Blake2b/Verification/k: 250, m: 1523, nr_parties: 2000
                        time:   [13.944 ms 14.010 ms 14.077 ms]

依赖关系

~4.5–6MB
~188K SLoC