1use polynomial_ring::Polynomial;
2use rand_distr::{Uniform, Distribution};
3use rand::SeedableRng;
4use rand::rngs::StdRng;
5use ring_lwe::utils::{polyadd, polymul_fast, gen_uniform_poly,nearest_int};
6use ntt::omega;
7use base64::{engine::general_purpose, Engine as _};
8use bincode;
9
10#[derive(Debug)]
11pub struct Parameters {
13 pub n: usize,
15 pub q: i64,
17 pub k: usize,
19 pub omega: i64,
21 pub f: Polynomial<i64>,
23}
24
25impl Default for Parameters {
26 fn default() -> Self {
27 let n = 512;
28 let q = 12289;
29 let k = 8;
30 let omega = omega(q, 2 * n);
31 let mut poly_vec = vec![0i64; n + 1];
32 poly_vec[0] = 1;
33 poly_vec[n] = 1;
34 let f = Polynomial::new(poly_vec);
35 Parameters { n, q, k, omega, f }
36 }
37}
38
39pub fn add_vec(v0: &Vec<Polynomial<i64>>, v1: &Vec<Polynomial<i64>>, modulus: i64, poly_mod: &Polynomial<i64>) -> Vec<Polynomial<i64>> {
40 assert_eq!(v0.len(), v1.len());
41 v0.iter()
42 .zip(v1.iter())
43 .map(|(a, b)| polyadd(a, b, modulus, poly_mod))
44 .collect()
45}
46
47pub fn mul_vec_simple(v0: &Vec<Polynomial<i64>>, v1: &Vec<Polynomial<i64>>, modulus: i64, poly_mod: &Polynomial<i64>, omega: i64) -> Polynomial<i64> {
48 assert_eq!(v0.len(), v1.len());
49 v0.iter()
50 .zip(v1.iter())
51 .map(|(a, b)| polymul_fast(a, b, modulus, poly_mod, omega))
52 .fold(Polynomial::new(vec![]), |acc, p| polyadd(&acc, &p, modulus, poly_mod))
53}
54
55pub 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>> {
56 m.iter()
57 .map(|row| mul_vec_simple(row, v, modulus, poly_mod, omega))
58 .collect()
59}
60
61pub fn transpose(m: &Vec<Vec<Polynomial<i64>>>) -> Vec<Vec<Polynomial<i64>>> {
62 let rows = m.len();
63 let cols = m[0].len();
64 let mut result = vec![vec![Polynomial::new(vec![]); rows]; cols];
65 for i in 0..rows {
66 for j in 0..cols {
67 result[j][i] = m[i][j].clone();
68 }
69 }
70 result
71}
72
73pub fn gen_small_vector(size: usize, rank: usize, seed: Option<u64>) -> Vec<Polynomial<i64>> {
74 let between = Uniform::new(0, 3);
75 let mut rng = match seed {
76 Some(s) => StdRng::seed_from_u64(s),
77 None => StdRng::from_entropy(),
78 };
79
80 (0..rank)
81 .map(|_| {
82 let coeffs: Vec<i64> = (0..size).map(|_| between.sample(&mut rng) - 1).collect();
83 Polynomial::new(coeffs)
84 })
85 .collect()
86}
87
88pub fn gen_uniform_matrix(size: usize, rank: usize, modulus: i64, seed: Option<u64>) -> Vec<Vec<Polynomial<i64>>> {
89 (0..rank)
90 .map(|_| {
91 (0..rank)
92 .map(|_| gen_uniform_poly(size, modulus, seed))
93 .collect::<Vec<_>>()
94 })
95 .collect::<Vec<_>>()
96}
97
98pub fn compress(data: &Vec<i64>) -> String {
99 let serialized = bincode::serialize(data).expect("Failed to serialize data");
100 general_purpose::STANDARD.encode(&serialized)
101}
102
103pub fn decompress(base64_str: &str) -> Vec<i64> {
104 let decoded = general_purpose::STANDARD.decode(base64_str).expect("Failed to decode base64 string");
105 bincode::deserialize(&decoded).expect("Failed to deserialize data")
106}
107
108pub fn encode_message(m_b: &Vec<i64>, q: i64) -> Polynomial<i64> {
109
110 let half_q = nearest_int(q,2);
112
113 Polynomial::new(vec![half_q])*Polynomial::new(m_b.to_vec())
115
116}