Path: blob/main/frontier/11-homomorphic-encryption/rust/src/lib.rs
483 views
unlisted
//! # Module 11: Homomorphic Encryption — Exercises1//!2//! We implement Paillier (additive HE) as a concrete, tractable scheme.3//!4//! ## Progression5//! 1. `paillier_keygen` — signature + doc6//! 2. `paillier_encrypt` — signature + doc7//! 3. `paillier_add` — signature + doc8//! 4. `paillier_decrypt` — signature only9//! 5. `paillier_scalar_mul` — signature only1011/// Paillier public key: (n, g) where n = p*q.12#[derive(Debug, Clone)]13pub struct PaillierPk {14pub n: u128,15pub g: u128,16pub n_sq: u128,17}1819/// Paillier secret key: (lambda, mu).20#[derive(Debug, Clone)]21pub struct PaillierSk {22pub lambda: u128,23pub mu: u128,24pub n: u128,25pub n_sq: u128,26}2728/// Generate Paillier keys from two primes p and q.29///30/// - n = p * q31/// - λ = lcm(p-1, q-1)32/// - g = n + 1 (simple choice)33/// - μ = L(g^λ mod n²)^(-1) mod n, where L(x) = (x-1)/n34pub fn paillier_keygen(p: u128, q: u128) -> (PaillierPk, PaillierSk) {35todo!("Paillier key generation")36}3738/// Encrypt a plaintext m ∈ [0, n) using Paillier.39///40/// c = g^m * r^n mod n²41/// where r is a random value coprime to n.42pub fn paillier_encrypt(pk: &PaillierPk, m: u128, r: u128) -> u128 {43todo!("Paillier encryption: g^m * r^n mod n^2")44}4546/// Homomorphic addition: add two ciphertexts.47///48/// Enc(m1) * Enc(m2) mod n² = Enc(m1 + m2 mod n)49pub fn paillier_add(pk: &PaillierPk, c1: u128, c2: u128) -> u128 {50todo!("Multiply ciphertexts for additive homomorphism")51}5253/// Decrypt a Paillier ciphertext.54///55/// m = L(c^λ mod n²) * μ mod n56pub fn paillier_decrypt(sk: &PaillierSk, c: u128) -> u128 {57todo!("Paillier decryption")58}5960/// Homomorphic scalar multiplication: multiply plaintext by a constant.61///62/// c^scalar mod n² = Enc(m * scalar mod n)63pub fn paillier_scalar_mul(pk: &PaillierPk, c: u128, scalar: u128) -> u128 {64todo!("Exponentiate ciphertext for scalar multiplication")65}6667#[cfg(test)]68mod tests {69use super::*;7071#[test]72#[ignore]73fn test_paillier_roundtrip() {74let (pk, sk) = paillier_keygen(13, 17);75let m = 42_u128;76let r = 77_u128; // random, coprime to n77let c = paillier_encrypt(&pk, m, r);78let decrypted = paillier_decrypt(&sk, c);79assert_eq!(decrypted, m);80}8182#[test]83#[ignore]84fn test_paillier_additive_homomorphism() {85let (pk, sk) = paillier_keygen(13, 17);86let m1 = 20_u128;87let m2 = 30_u128;88let c1 = paillier_encrypt(&pk, m1, 53);89let c2 = paillier_encrypt(&pk, m2, 79);90let c_sum = paillier_add(&pk, c1, c2);91let decrypted = paillier_decrypt(&sk, c_sum);92assert_eq!(decrypted, (m1 + m2) % pk.n);93}94}959697