5个版本
使用旧的Rust 2015
0.2.2 | 2017年1月23日 |
---|---|
0.2.1 | 2016年12月30日 |
0.2.0 | 2016年12月15日 |
0.1.1 | 2016年10月4日 |
0.1.0 | 2016年8月16日 |
#1083 在 密码学 中
50 每月下载次数
63KB
1K SLoC
阈值秘密共享
高效纯Rust库,用于秘密共享,为传统的Shamir共享和包共享提供高效的份额生成和重建。目前,秘密和份额被固定为以i64
值表示的素域元素。
安装
Cargo
[dependencies]
threshold-secret-sharing = "0.2"
GitHub
git clone https://github.com/snipsco/rust-threshold-secret-sharing
cd rust-threshold-secret-sharing
cargo build --release
示例
在examples/
目录中包含了几个示例。使用cargo
运行每个示例,例如:
cargo run --example shamir
下面的Shamir示例。
Shamir共享
使用Shamir方案相对简单。
在选择参数时,必须选择threshold
和share_count
以满足安全性要求,并且prime
必须足够大,以便正确编码要共享的值(并且满足prime >= share_count + 1
)。
在重建秘密时,必须显式提供索引以标识份额;这些索引对应于由share()
返回的向量中的份额索引。
extern crate threshold_secret_sharing as tss;
fn main() {
// create instance of the Shamir scheme
let ref tss = tss::shamir::ShamirSecretSharing {
threshold: 8, // privacy threshold
share_count: 20, // total number of shares to generate
prime: 41 // prime field to use
};
let secret = 5;
// generate shares for secret
let all_shares = tss.share(secret);
// artificially remove some of the shares
let number_of_recovered_shared = 10;
assert!(number_of_recovered_shared >= tss.reconstruct_limit());
let recovered_indices: Vec<usize> = (0..number_of_recovered_shared).collect();
let recovered_shares: &[i64] = &all_shares[0..number_of_recovered_shared];
// reconstruct using remaining subset of shares
let reconstructed_secret = tss.reconstruct(&recovered_indices, recovered_shares);
assert_eq!(reconstructed_secret, secret);
}
打包共享
如果许多秘密都需要进行秘密共享,则可能有益于使用打包方案,其中多个秘密打包到每个份额中。虽然仍然非常计算高效,但一个缺点是参数有一些限制。
具体来说,参数分为方案参数和实现参数
- 前者,如Shamir共享,确定方案的具体属性,但现在还有一个
secret_count
指定每个份额中要打包多少个秘密;重建限制隐式定义为secret_count + threshold + 1
- 后者与实现(目前基于快速傅里叶变换)相关,需要指定字段的
prime
,还需要该字段中的两个单位根,分别必须是2的幂和3的幂
由于这种复杂性增加,正在提供辅助函数以查找合适的参数。目前,以下示例中包含在 packed
模块中的几个固定字段:
PSS_4_8_3
、PSS_4_26_3
、PSS_155_728_100
、PSS_155_19682_100
以 PSS_T_N_D
格式,将 D
秘密分成 N
份,阈值为 T
。
extern crate threshold_secret_sharing as tss;
fn main() {
// use predefined parameters
let ref tss = tss::packed::PSS_4_26_3;
// generate shares for a vector of secrets
let secrets = [1, 2, 3];
let all_shares = tss.share(&secrets);
// artificially remove some of the shares; keep only the first 8
let indices: Vec<usize> = (0..8).collect();
let shares = &all_shares[0..8];
// reconstruct using remaining subset of shares
let recovered_secrets = tss.reconstruct(&indices, shares);
assert_eq!(recovered_secrets, vec![1, 2, 3]);
}
同态性质
Shamir 和打包方案都享有某些同态性质:共享秘密可以通过操作份额进行转换。加法和乘法都起作用,但请注意,在乘法的情况下,重建限制随着每次应用翻倍。
extern crate threshold_secret_sharing as tss;
fn main() {
// use predefined parameters
let ref tss = tss::PSS_4_26_3;
// generate shares for first vector of secrets
let secrets_1 = [1, 2, 3];
let shares_1 = tss.share(&secrets_1);
// generate shares for second vector of secrets
let secrets_2 = [4, 5, 6];
let shares_2 = tss.share(&secrets_2);
// combine shares pointwise to get shares of the sum of the secrets
let shares_sum: Vec<i64> = shares_1.iter().zip(&shares_2)
.map(|(a, b)| (a + b) % tss.prime).collect();
// artificially remove some of the shares; keep only the first 8
let indices: Vec<usize> = (0..8).collect();
let shares = &shares_sum[0..8];
// reconstruct using remaining subset of shares
let recovered_secrets = tss.reconstruct(&indices, shares);
assert_eq!(recovered_secrets, vec![5, 7, 9]);
}
参数生成
虽然实例化 Shamir 方案很简单,如上所述,打包方案更复杂,因此提供了一些辅助方法。由于某些应用程序只需要固定参数的选择,这些辅助方法是可选的,并且仅在编译时激活 paramgen
功能时才包含在内
cargo build --features paramgen
这也增加了几个额外的依赖项。
性能
迄今为止,大多数性能工作都集中在打包方案的份额生成上,在此过程中对重建进行了一些明显的改进。例如,使用打包方案将 100 个秘密分成约 20,000 份需要在大约 31ms 内完成,在 Raspberry Pi 3 上需要大约 590ms。
这些数字是通过运行
cargo bench
使用夜间工具链获得的。
许可证
根据您的选择,许可协议为以下之一:
- Apache License,版本 2.0 (LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
贡献
除非您明确表示,否则根据 Apache-2.0 许可证定义,您提交的任何有意包含在作品中的贡献都应双重许可,如上所述,不附加任何额外条款或条件。
依赖关系
~315–690KB