10个版本

0.2.7 2022年12月4日
0.2.6 2022年3月4日
0.2.5 2021年7月14日
0.2.4 2021年3月25日
0.0.4 2021年1月16日

#748 in 密码学

MIT/Apache

77KB
1.5K SLoC

MPVSS - 一个简单的公开可验证的秘密共享库

CI crates.io Crates.io

该库在Rust中实现了一个简单的PVSS方案。

什么是PVSS?

秘密共享意味着经销商可以将一个秘密分解成一组参与者的秘密份额,只有通过合作地加入他们的秘密部分才能重建秘密。该库还实现了阈值密码学,以便经销商可以决定是否所有接收参与者都需要合作,或者是否只需要一小部分参与者就足以重建秘密。

除了普通的秘密共享方案PVSS外,还通过以下方式增加了可验证性:将秘密分割成的每一部分分别用接收者的公钥加密。经销商发布所有加密份额以及一个非交互式零知识证明,允许每个人(而不仅仅是接收参与者)验证解密后的份额确实可以用于重建秘密。然后,参与者解密他们的所有份额,并交换它们,以及另一个非交互式零知识证明,允许接收者验证份额实际上是解密的结果。

因此,PVSS可以用于在参与者组中共享秘密,这样,秘密要么可以被所有公平参与的参与者重建,要么收到伪造份额的参与者可以识别恶意方。

构建

cargo build --release

测试

cargo test --release

示例

cargo run --release --example mpvss_all
cargo run --release --example mpvss_sub

使用方法

初始化

首先,如果需要,我们将我们的秘密消息转换为数值。当创建经销商时,还会创建一个PVSS实例,它包含所有参与者需要知道的全球参数。

let secret_message = String::from("Hello MPVSS.");

let mut dealer = Participant::new();
dealer.initialize();

let mut p1 = Participant::new();
let mut p2 = Participant::new();
let mut p3 = Participant::new();

p1.initialize();
p2.initialize();
p3.initialize();

分发与验证

经销商将秘密分割成份额,加密它们并创建一个证明,以便每个人都可以验证这些份额(一旦解密)可以用于重建秘密。阈值决定了重建所需的份额数量。然后,将加密份额和证明捆绑在一起。

// Dealer that shares the secret among p1, p2 and p3.
let distribute_shares_box = dealer.distribute_secret(
        &string_to_secret(&secret_message),
        &vec![p1.publickey, p2.publickey, p3.publickey],
        3,
    );

// p1 verifies distribution shares box containing encryted shares and proof of zero-knowlege. [p2 and p3 do this as well.]
assert_eq!(
    p1.verify_distribution_shares(&distribute_shares_box),
    true
);
assert_eq!(
    p2.verify_distribution_shares(&distribute_shares_box),
    true
);
assert_eq!(
    p3.verify_distribution_shares(&distribute_shares_box),
    true
);

交换与验证

参与者从分发份额框中提取他们的份额并解密它们。他们将这些份额与一个证明捆绑在一起,该证明允许接收者验证份额确实是解密的结果。

// p1 extracts the share. [p2 and p3 do this as well.]
let s1 = p1
    .extract_secret_share(&distribute_shares_box, &p1.privatekey)
    .unwrap();

// p1, p2 and p3 exchange their descrypted shares.
// ...
let s2 = p2
    .extract_secret_share(&distribute_shares_box, &p2.privatekey)
    .unwrap();
let s3 = p3
    .extract_secret_share(&distribute_shares_box, &p3.privatekey)
    .unwrap();

// p1 verifies the share received from p2. [Actually everybody verifies every received share.]
assert_eq!(
    p1.verify_share(&s2, &distribute_shares_box, &p2.publickey),
    true
);
assert_eq!(
    p2.verify_share(&s3, &distribute_shares_box, &p3.publickey),
    true
);
assert_eq!(
    p3.verify_share(&s1, &distribute_shares_box, &s1.publickey),
    true
);

重建

一旦参与者收集了至少 threshold 个份额,就可以重建秘密。

let share_boxs = [s1, s2, s3];
let r1 = p1
    .reconstruct(&share_boxs, &distribute_shares_box)
    .unwrap();
let r2 = p2
    .reconstruct(&share_boxs, &distribute_shares_box)
    .unwrap();
let r3 = p3
    .reconstruct(&share_boxs, &distribute_shares_box)
    .unwrap();

let r1_str = string_from_secret(&r1);
assert_eq!(secret_message.clone(), r1_str);
let r2_str = string_from_secret(&r2);
assert_eq!(secret_message.clone(), r2_str);
let r3_str = string_from_secret(&r3);
assert_eq!(secret_message.clone(), r3_str);

未来计划

添加更多椭圆曲线组。

因为在这个项目中,多项式承诺并不等于Pedersen承诺,DLEQ仅是计算安全的,而不是信息论安全的。

许可证

双许可以兼容Rust项目。

根据您的选择,许可协议为Apache许可证第2.0版 http://www.apache.org/licenses/LICENSE-2.0 或MIT许可证 http://opensource.org/licenses/MIT。此文件不得复制、修改或分发,除非根据这些条款。

依赖关系

~3MB
~61K SLoC