#zero-knowledge-proofs #elgamal #encryption-key #encryption #zero-knowledge #shared-key #secret-sharing

no-std elastic-elgamal

使用可插拔加密后端的ElGamal加密和相关零知识证明的实现

5个不稳定版本

0.3.0 2023年10月8日
0.3.0-beta.12023年2月3日
0.2.1 2022年7月4日
0.2.0 2022年6月13日
0.1.0 2021年6月28日

#991 in 密码学

25每月下载量

MIT/Apache

305KB
5.5K SLoC

ElGamal加密和相关零知识证明

Build Status License: MIT OR Apache-2.0 rust 1.65+ required no_std supported

文档: Docs.rs crate docs (main)

实现了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(&params, &votes, &mut rng);
let encrypted = ballot.verify(&params).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.0MIT许可证

除非您明确声明,否则您提交给elastic-elgamal的任何贡献,根据Apache-2.0许可证定义,应双许可如上所述,不附加任何额外条款或条件。

依赖关系

~4-6MB
~127K SLoC