paillier_zkproofs

Zero-Knowledge Proofs for Paillier Encryption (GG18/CGGMP21)

From: “Fast Multiparty Threshold ECDSA with Fast Trustless Setup” (GG18)
By: Rosario Gennaro, Steven Goldfeder
Published: CCS 2018 / ePrint 2019/114

And: “UC Non-Interactive, Proactive, Threshold ECDSA” (CGGMP21)
By: Ran Canetti, Rosario Gennaro, et al.
Published: ePrint 2021/060

This module implements ZK proofs for Paillier-based threshold ECDSA: - Range proofs: prove encrypted value is in a specified range - Π^{enc}: prove knowledge of plaintext for a ciphertext - Π^{log}: prove EC discrete log equals Paillier plaintext

  • type: zero-knowledge proofs

  • setting: Composite modulus (Paillier) + Elliptic Curve

  • assumption: DCR, DL

Authors:

Charm Developers

Date:

02/2026

class paillier_zkproofs.PaillierDLogProof(commitment_c: Any, commitment_Q: Any, challenge: bytes, response_x: int, response_r: int)[source]

Bases: object

Proof that EC discrete log equals Paillier plaintext (Π^{log}).

Proves: “c = Enc(x) and Q = g^x for the same x”

This links Paillier encryption to EC group operations, essential for GG18/CGGMP21 MtA correctness.

challenge: bytes
commitment_Q: Any
commitment_c: Any
response_r: int
response_x: int
class paillier_zkproofs.PaillierEncProof(commitment: Any, challenge: bytes, response_m: int, response_r: int)[source]

Bases: object

Proof of knowledge of plaintext for Paillier ciphertext.

Proves: “I know m such that c = Enc(m; r)”

Attributes:

commitment: First message (commitment) challenge: Fiat-Shamir challenge response_m: Response for message response_r: Response for randomness

challenge: bytes
commitment: Any
response_m: int
response_r: int
class paillier_zkproofs.PaillierRangeProof(bit_commitments: List[Any], bit_proofs: List[Dict], range_bound_bits: int)[source]

Bases: object

Range proof for Paillier ciphertext.

Proves: “c encrypts m where 0 <= m < B”

Uses bit decomposition approach for simplicity. Full implementation would use more efficient techniques.

bit_commitments: List[Any]
bit_proofs: List[Dict]
range_bound_bits: int
class paillier_zkproofs.PaillierZKProofs(rsa_group: RSAGroup, ec_group: Any = None)[source]

Bases: object

Zero-knowledge proofs for Paillier encryption.

Implements the ZK proofs needed for GG18 and CGGMP21 threshold ECDSA protocols.

prove_dlog_equality(x: int, ciphertext: Any, Q: Any, randomness: int, pk: Dict, generator: Any) PaillierDLogProof[source]

Prove Paillier plaintext equals EC discrete log (Π^{log}).

Proves: c = Enc(x) and Q = g^x for the same x

Args:

x: The secret value ciphertext: Paillier encryption of x Q: EC point Q = g^x randomness: Randomness used in Paillier encryption pk: Paillier public key generator: EC generator g

Returns:

PaillierDLogProof object

prove_encryption_knowledge(plaintext: int, ciphertext: Any, randomness: int, pk: Dict) PaillierEncProof[source]

Prove knowledge of plaintext for Paillier ciphertext.

Args:

plaintext: The plaintext m ciphertext: The ciphertext c = Enc(m; r) randomness: The randomness r used in encryption pk: Paillier public key

Returns:

PaillierEncProof object

verify_dlog_equality(ciphertext: Any, Q: Any, pk: Dict, generator: Any, proof: PaillierDLogProof) bool[source]

Verify Paillier-EC discrete log equality proof.

Args:

ciphertext: Paillier ciphertext Q: EC point pk: Paillier public key generator: EC generator proof: The proof to verify

Returns:

True if proof is valid

verify_encryption_knowledge(ciphertext: Any, pk: Dict, proof: PaillierEncProof) bool[source]

Verify proof of knowledge of plaintext.

Args:

ciphertext: The ciphertext being proven pk: Paillier public key proof: The proof to verify

Returns:

True if proof is valid