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};
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 {
27 fn default() -> Self {
28 let n = 512;
29 let q = 12289;
30 let k = 8;
31 let omega = omega(q, 2*n);
32 let mut poly_vec = vec![0i64;n+1];
33 poly_vec[0] = 1;
34 poly_vec[n] = 1;
35 let f = Polynomial::new(poly_vec);
36 Parameters { n, q, k, omega, f }
37 }
38}
39
40pub fn add_vec(v0: &Vec<Polynomial<i64>>, v1: &Vec<Polynomial<i64>>, modulus: i64, poly_mod: &Polynomial<i64>) -> Vec<Polynomial<i64>> {
49 assert!(v0.len() == v1.len());
50 let mut result = vec![];
51 for i in 0..v0.len() {
52 result.push(polyadd(&v0[i], &v1[i], modulus, &poly_mod));
53 }
54 result
55}
56
57pub fn mul_vec_simple(v0: &Vec<Polynomial<i64>>, v1: &Vec<Polynomial<i64>>, modulus: i64, poly_mod: &Polynomial<i64>, omega: i64) -> Polynomial<i64> {
67 assert!(v0.len() == v1.len());
68 let mut result = Polynomial::new(vec![]);
69 for i in 0..v0.len() {
70 result = polyadd(&result, &polymul_fast(&v0[i], &v1[i], modulus, &poly_mod, omega), modulus, &poly_mod);
71 }
72 result
73}
74
75pub 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>> {
85
86 let mut result = vec![];
87 for i in 0..m.len() {
88 result.push(mul_vec_simple(&m[i], &v, modulus, &poly_mod, omega));
89 }
90 result
91}
92
93pub fn transpose(m: &Vec<Vec<Polynomial<i64>>>) -> Vec<Vec<Polynomial<i64>>> {
99 let mut result = vec![vec![Polynomial::new(vec![]); m.len()]; m[0].len()];
100 for i in 0..m.len() {
101 for j in 0..m[0].len() {
102 result[j][i] = m[i][j].clone();
103 }
104 }
105 result
106}
107
108pub fn gen_small_vector(size : usize, rank: usize, seed: Option<u64>) -> Vec<Polynomial<i64>> {
116 let mut v = vec![];
117 let between = Uniform::new(0,3);
118 let mut rng = match seed {
119 Some(seed) => StdRng::seed_from_u64(seed),
120 None => StdRng::from_entropy(),
121 };
122 let mut coeffs = vec![0i64;size];
123 for _i in 0..rank {
124 for j in 0.. size {
125 coeffs[j] = between.sample(&mut rng)-1;
126 }
127 v.push(Polynomial::new(coeffs.clone()));
128 }
129 v
130}
131
132pub fn gen_uniform_matrix(size : usize, rank: usize, modulus: i64, seed: Option<u64>) -> Vec<Vec<Polynomial<i64>>> {
141 let mut m = vec![vec![Polynomial::new(vec![]); rank]; rank];
142 for i in 0..rank {
143 for j in 0..rank {
144 m[i][j] = gen_uniform_poly(size, modulus, seed);
145 }
146 }
147 m
148}
149
150pub fn compress(data: &Vec<i64>) -> String {
156 let serialized_data = bincode::serialize(data).expect("Failed to serialize data");
157 general_purpose::STANDARD.encode(&serialized_data)
158}
159
160pub fn decompress(base64_str: &str) -> Vec<i64> {
166 let decoded_bytes = general_purpose::STANDARD.decode(base64_str).expect("Failed to decode base64 string");
167 bincode::deserialize(&decoded_bytes).expect("Failed to deserialize data")
168}