Skip to content

use polymul_fast #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ polynomial-ring = "0.5.0"
num-traits = "=0.2.19"
rand = "0.8.5"
rand_distr = "0.4.3"
ntt = "0.1.9"
ring-lwe = "0.1.5"
14 changes: 7 additions & 7 deletions src/decrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ use crate::utils::{Parameters,mul_vec_simple};
/// let mut m_b = vec![0,1,0,1,0,0,1,1,1,0,1];
/// m_b.resize(params.n, 0);
/// let (u, v) = module_lwe::encrypt::encrypt(&pk.0, &pk.1, &m_b, &params, None);
/// let decrypted_coeffs = module_lwe::decrypt::decrypt(&sk, params.q, &params.f, &u, &v);
/// let decrypted_coeffs = module_lwe::decrypt::decrypt(&sk, &u, &v, &params);
/// assert_eq!(m_b, decrypted_coeffs);
/// ```
pub fn decrypt(
sk: &Vec<Polynomial<i64>>, //secret key
q: i64, //ciphertext modulus
f: &Polynomial<i64>, //polynomial modulus
u: &Vec<Polynomial<i64>>, //ciphertext vector
v: &Polynomial<i64> //ciphertext polynomial
v: &Polynomial<i64> , //ciphertext polynomial
params: &Parameters
) -> Vec<i64> {
let scaled_pt = polysub(&v, &mul_vec_simple(&sk, &u, q, &f), q, f); //Compute v-sk*u mod q
let (q, f, omega) = (params.q, &params.f, params.omega); //get parameters
let scaled_pt = polysub(&v, &mul_vec_simple(&sk, &u, q, &f, omega), q, f); //Compute v-sk*u mod q
let half_q = nearest_int(q,2); // compute nearest integer to q/2
let mut decrypted_coeffs = vec![];
let mut s;
Expand All @@ -49,7 +49,7 @@ pub fn decrypt(
pub fn decrypt_string(sk_string: &String, ciphertext_string: &String, params: &Parameters) -> String {

//get parameters
let (n, q, k, f) = (params.n, params.q, params.k, &params.f);
let (n, k) = (params.n, params.k);

// Convert the secret key string into a Vec<Polynomial<i64>>
let sk_array: Vec<i64> = sk_string.split(',')
Expand Down Expand Up @@ -79,7 +79,7 @@ pub fn decrypt_string(sk_string: &String, ciphertext_string: &String, params: &P
let v = Polynomial::new(v_array.to_vec());

// Decrypt the ciphertext
let mut m_b = decrypt(&sk, q, &f, &u, &v);
let mut m_b = decrypt(&sk, &u, &v, &params);
m_b.resize(n,0);

message_binary.extend(m_b);
Expand Down
6 changes: 3 additions & 3 deletions src/encrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn encrypt(
) -> (Vec<Polynomial<i64>>, Polynomial<i64>) {

//get parameters
let (n, q, k, f) = (params.n, params.q, params.k, &params.f);
let (n, q, k, f, omega) = (params.n, params.q, params.k, &params.f, params.omega);

//generate random ephermal keys
let r = gen_small_vector(n, k, seed);
Expand All @@ -41,10 +41,10 @@ pub fn encrypt(
let m = Polynomial::new(vec![half_q])*Polynomial::new(m_b.to_vec());

// Compute u = a^T * r + e_1 mod q
let u = add_vec(&mul_mat_vec_simple(&transpose(a), &r, q, f), &e1, q, f);
let u = add_vec(&mul_mat_vec_simple(&transpose(a), &r, q, f, omega), &e1, q, f);

// Compute v = t * r + e_2 - m mod q
let v = polysub(&polyadd(&mul_vec_simple(t, &r, q, &f), &e2, q, f), &m, q, f);
let v = polysub(&polyadd(&mul_vec_simple(t, &r, q, &f, omega), &e2, q, f), &m, q, f);

(u, v)
}
Expand Down
4 changes: 2 additions & 2 deletions src/keygen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ pub fn keygen(
params: &Parameters,
seed: Option<u64> //random seed
) -> ((Vec<Vec<Polynomial<i64>>>, Vec<Polynomial<i64>>), Vec<Polynomial<i64>>) {
let (n,q,k,f) = (params.n, params.q, params.k, &params.f);
let (n,q,k,f,omega) = (params.n, params.q, params.k, &params.f, params.omega);
//Generate a public and secret key
let a = gen_uniform_matrix(n, k, q, seed);
let sk = gen_small_vector(n, k, seed);
let e = gen_small_vector(n, k, seed);
let t = add_vec(&mul_mat_vec_simple(&a, &sk, q, &f), &e, q, &f);
let t = add_vec(&mul_mat_vec_simple(&a, &sk, q, &f, omega), &e, q, &f);

//Return public key (a, t) and secret key (sk) as a 2-tuple
((a, t), sk)
Expand Down
2 changes: 1 addition & 1 deletion src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ mod tests {
let ciphertext_sum = (add_vec(&u.0,&v.0,q,f), polyadd(&u.1,&v.1,q,f));

// Decrypt ciphertext sum u+v
let mut decrypted_sum = decrypt(&sk, q, f, &ciphertext_sum.0, &ciphertext_sum.1);
let mut decrypted_sum = decrypt(&sk, &ciphertext_sum.0, &ciphertext_sum.1, &params);
decrypted_sum.resize(n, 0);

assert_eq!(decrypted_sum, plaintext_sum, "test failed: {:?} != {:?}", decrypted_sum, plaintext_sum);
Expand Down
26 changes: 16 additions & 10 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use polynomial_ring::Polynomial;
use rand_distr::{Uniform, Distribution};
use rand::SeedableRng;
use rand::rngs::StdRng;
use ring_lwe::utils::{polyadd, polymul, gen_uniform_poly};
use ring_lwe::utils::{polyadd, polymul_fast, gen_uniform_poly};
use ntt::omega;

#[derive(Debug)]
/// default parameters for module-LWE
Expand All @@ -11,23 +12,26 @@ pub struct Parameters {
pub n: usize,
/// Ciphertext modulus
pub q: i64,
/// Plaintext modulus
pub k: usize,
/// Module rank
pub k: usize,
/// 2n-th root of unity
pub omega: i64,
/// Polynomial modulus
pub f: Polynomial<i64>,
pub f: Polynomial<i64>,
}

/// default parameters for module-LWE
impl Default for Parameters {
fn default() -> Self {
let n = 32;
let q = 59049;
let q = 12289;
let k = 8;
let omega = omega(q, 2*n);
let mut poly_vec = vec![0i64;n+1];
poly_vec[0] = 1;
poly_vec[n] = 1;
let f = Polynomial::new(poly_vec);
Parameters { n, q, k, f }
Parameters { n, q, k, omega, f }
}
}

Expand All @@ -54,13 +58,14 @@ pub fn add_vec(v0: &Vec<Polynomial<i64>>, v1: &Vec<Polynomial<i64>>, modulus: i6
/// * `v1` - vector of polynomials
/// * `modulus` - modulus
/// * `poly_mod` - polynomial modulus
/// * `omega` - 2nth root of unity
/// # Returns
/// * `result` - polynomial
pub fn mul_vec_simple(v0: &Vec<Polynomial<i64>>, v1: &Vec<Polynomial<i64>>, modulus: i64, poly_mod: &Polynomial<i64>) -> Polynomial<i64> {
pub fn mul_vec_simple(v0: &Vec<Polynomial<i64>>, v1: &Vec<Polynomial<i64>>, modulus: i64, poly_mod: &Polynomial<i64>, omega: i64) -> Polynomial<i64> {
assert!(v0.len() == v1.len());
let mut result = Polynomial::new(vec![]);
for i in 0..v0.len() {
result = polyadd(&result, &polymul(&v0[i], &v1[i], modulus, &poly_mod), modulus, &poly_mod);
result = polyadd(&result, &polymul_fast(&v0[i], &v1[i], modulus, &poly_mod, omega), modulus, &poly_mod);
}
result
}
Expand All @@ -71,13 +76,14 @@ pub fn mul_vec_simple(v0: &Vec<Polynomial<i64>>, v1: &Vec<Polynomial<i64>>, modu
/// * `v` - vector of polynomials
/// * `modulus` - modulus
/// * `poly_mod` - polynomial modulus
/// * `omega` - 2nth root of unity
/// # Returns
/// * `result` - vector of polynomials
pub fn mul_mat_vec_simple(m: &Vec<Vec<Polynomial<i64>>>, v: &Vec<Polynomial<i64>>, modulus: i64, poly_mod: &Polynomial<i64>) -> Vec<Polynomial<i64>> {
pub fn mul_mat_vec_simple(m: &Vec<Vec<Polynomial<i64>>>, v: &Vec<Polynomial<i64>>, modulus: i64, poly_mod: &Polynomial<i64>, omega: i64) -> Vec<Polynomial<i64>> {

let mut result = vec![];
for i in 0..m.len() {
result.push(mul_vec_simple(&m[i], &v, modulus, &poly_mod));
result.push(mul_vec_simple(&m[i], &v, modulus, &poly_mod, omega));
}
result
}
Expand Down