Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
duyuefeng0708
GitHub Repository: duyuefeng0708/Cryptography-From-First-Principle
Path: blob/main/frontier/11-homomorphic-encryption/rust/src/lib.rs
483 views
unlisted
1
//! # Module 11: Homomorphic Encryption — Exercises
2
//!
3
//! We implement Paillier (additive HE) as a concrete, tractable scheme.
4
//!
5
//! ## Progression
6
//! 1. `paillier_keygen` — signature + doc
7
//! 2. `paillier_encrypt` — signature + doc
8
//! 3. `paillier_add` — signature + doc
9
//! 4. `paillier_decrypt` — signature only
10
//! 5. `paillier_scalar_mul` — signature only
11
12
/// Paillier public key: (n, g) where n = p*q.
13
#[derive(Debug, Clone)]
14
pub struct PaillierPk {
15
pub n: u128,
16
pub g: u128,
17
pub n_sq: u128,
18
}
19
20
/// Paillier secret key: (lambda, mu).
21
#[derive(Debug, Clone)]
22
pub struct PaillierSk {
23
pub lambda: u128,
24
pub mu: u128,
25
pub n: u128,
26
pub n_sq: u128,
27
}
28
29
/// Generate Paillier keys from two primes p and q.
30
///
31
/// - n = p * q
32
/// - λ = lcm(p-1, q-1)
33
/// - g = n + 1 (simple choice)
34
/// - μ = L(g^λ mod n²)^(-1) mod n, where L(x) = (x-1)/n
35
pub fn paillier_keygen(p: u128, q: u128) -> (PaillierPk, PaillierSk) {
36
todo!("Paillier key generation")
37
}
38
39
/// Encrypt a plaintext m ∈ [0, n) using Paillier.
40
///
41
/// c = g^m * r^n mod n²
42
/// where r is a random value coprime to n.
43
pub fn paillier_encrypt(pk: &PaillierPk, m: u128, r: u128) -> u128 {
44
todo!("Paillier encryption: g^m * r^n mod n^2")
45
}
46
47
/// Homomorphic addition: add two ciphertexts.
48
///
49
/// Enc(m1) * Enc(m2) mod n² = Enc(m1 + m2 mod n)
50
pub fn paillier_add(pk: &PaillierPk, c1: u128, c2: u128) -> u128 {
51
todo!("Multiply ciphertexts for additive homomorphism")
52
}
53
54
/// Decrypt a Paillier ciphertext.
55
///
56
/// m = L(c^λ mod n²) * μ mod n
57
pub fn paillier_decrypt(sk: &PaillierSk, c: u128) -> u128 {
58
todo!("Paillier decryption")
59
}
60
61
/// Homomorphic scalar multiplication: multiply plaintext by a constant.
62
///
63
/// c^scalar mod n² = Enc(m * scalar mod n)
64
pub fn paillier_scalar_mul(pk: &PaillierPk, c: u128, scalar: u128) -> u128 {
65
todo!("Exponentiate ciphertext for scalar multiplication")
66
}
67
68
#[cfg(test)]
69
mod tests {
70
use super::*;
71
72
#[test]
73
#[ignore]
74
fn test_paillier_roundtrip() {
75
let (pk, sk) = paillier_keygen(13, 17);
76
let m = 42_u128;
77
let r = 77_u128; // random, coprime to n
78
let c = paillier_encrypt(&pk, m, r);
79
let decrypted = paillier_decrypt(&sk, c);
80
assert_eq!(decrypted, m);
81
}
82
83
#[test]
84
#[ignore]
85
fn test_paillier_additive_homomorphism() {
86
let (pk, sk) = paillier_keygen(13, 17);
87
let m1 = 20_u128;
88
let m2 = 30_u128;
89
let c1 = paillier_encrypt(&pk, m1, 53);
90
let c2 = paillier_encrypt(&pk, m2, 79);
91
let c_sum = paillier_add(&pk, c1, c2);
92
let decrypted = paillier_decrypt(&sk, c_sum);
93
assert_eq!(decrypted, (m1 + m2) % pk.n);
94
}
95
}
96
97