5个不稳定版本
0.3.0 | 2023年10月8日 |
---|---|
0.3.0-beta.1 | 2023年2月3日 |
0.2.1 | 2022年7月4日 |
0.2.0 | 2022年6月13日 |
0.1.0 | 2021年6月28日 |
#991 in 密码学
25每月下载量
305KB
5.5K SLoC
ElGamal加密和相关零知识证明
实现了ElGamal加密和相关零知识证明,并带有可插拔的加密后端。
以下协议和高级应用包括
- 加法同态ElGamal加密
- 零加密和布尔值加密的零知识证明
- ElGamal密文零知识范围证明
- ElGamal密文与同组中Pedersen承诺等价的零知识证明
- 带有零知识正确性证明的加法同态m-of-n选择加密
- 带有零知识正确性证明的加法同态二次投票
- 通过Feldman的可验证秘密共享实现门限ElGamal加密,包括可验证分布式解密。
- 作为生成门限加密共享密钥的替代方法,存在参与者预先进行密钥承诺的Pedersen分布式密钥生成。(注意:这种方法在理论上可能导致公共密钥分布不均,如Gennaro等人所示。)
⚠警告
虽然这个包中的逻辑依赖于标准加密假设(包括某些特定群组中决策性Diffie-Hellman假设、计算性Diffie-Hellman问题和离散对数问题),但尚未经过独立验证以确保其正确性或不存在旁路攻击向量。请自行承担风险。
ElGamal加密不适合作为通用公钥加密的选择,因为它容易受到选择密文攻击的影响。为了安全起见,应限制应用层上的解密操作。
使用方法
将其添加到您的Crate.toml
中
[dependencies]
elastic-elgamal = "0.3.0"
单选投票
use elastic_elgamal::app::{ChoiceParams, EncryptedChoice};
use elastic_elgamal::{group::Ristretto, DiscreteLogTable, Keypair};
use rand::thread_rng;
let mut rng = thread_rng();
// Generate a keypair for encrypting ballots. In more realistic setup,
// this keypair would be distributed among multiple talliers.
let (pk, sk) = Keypair::<Ristretto>::generate(&mut rng).into_tuple();
let choice_params = ChoiceParams::single(pk, 5);
// ^ single-choice polling with 5 options encrypted for `pk`
let choice = 2; // voter's choice
let enc = EncryptedChoice::single(&choice_params, choice, &mut rng);
let choices = enc.verify(&choice_params).unwrap();
// ^ 5 Boolean value ciphertexts that can be homomorphically added
// across ballots
// Decrypt a separate ballot for demo purposes.
let lookup_table = DiscreteLogTable::new(0..=1);
for (idx, &v) in choices.iter().enumerate() {
assert_eq!(
sk.decrypt(v, &lookup_table),
Some((idx == choice) as u64)
);
}
二次投票
use elastic_elgamal::app::{QuadraticVotingParams, QuadraticVotingBallot};
use elastic_elgamal::{group::Ristretto, Keypair, DiscreteLogTable};
use rand::thread_rng;
let mut rng = thread_rng();
let (pk, sk) = Keypair::<Ristretto>::generate(&mut rng).into_tuple();
let params = QuadraticVotingParams::new(pk, 5, 20);
// ^ 5 options, 20 credits (= 4 max votes per option)
assert_eq!(params.max_votes(), 4);
let votes = [4, 0, 0, 1, 1]; // voter's votes
let ballot = QuadraticVotingBallot::new(¶ms, &votes, &mut rng);
let encrypted = ballot.verify(¶ms).unwrap();
// ^ 5 vote ciphertexts that can be homomorphically added across ballots
// Decrypt a separate ballot for demo purposes.
let lookup = DiscreteLogTable::new(0..=params.max_votes());
let decrypted: Vec<_> = encrypted
.map(|vote| sk.decrypt(vote, &lookup).unwrap())
.collect();
assert_eq!(decrypted, votes);
有关更多使用示例,请参阅包文档。
命名
"Elastic"指的是可插拔的后端、共享密钥的加密,以及零知识环证明的构建(一个证明由多个环组成,每个环由多个可接受值组成)。elastic_elgamal
也是自动生成的Docker容器名称之一。
替代方案和类似工具
有几个Rust包实现了基于椭圆曲线的ElGamal加密,例如elgamal_ristretto
(这个包具有正确的解密和密钥知识的零知识证明)。
如警告部分所述,ElGamal不适合作为通用公钥加密。可以使用RSA或ECIES方案(例如来自NaCl / libsodium的box
原语)作为替代。
另请参阅
- elasticpoll.app – 一个使用此库实现普遍可验证投票的开源网络应用程序。(与这个库一样,该网站未经审计,不应用于重要投票。)
贡献
欢迎所有贡献!请参阅贡献指南以了解如何参与。
许可证
根据您的选择,许可为Apache许可证,版本2.0或MIT许可证。
除非您明确声明,否则您提交给elastic-elgamal
的任何贡献,根据Apache-2.0许可证定义,应双许可如上所述,不附加任何额外条款或条件。
依赖关系
~4-6MB
~127K SLoC