1use polynomial_ring::Polynomial;
2use ring_lwe::utils::{polysub,nearest_int};
3use crate::utils::{Parameters,mul_vec_simple,decompress};
4
5pub fn decrypt(
25 sk: &Vec<Polynomial<i64>>, u: &Vec<Polynomial<i64>>, v: &Polynomial<i64> , params: &Parameters
29) -> Vec<i64> {
30 let (q, f, omega) = (params.q, ¶ms.f, params.omega); let scaled_pt = polysub(&v, &mul_vec_simple(&sk, &u, q, &f, omega), q, f); let half_q = nearest_int(q,2); let mut decrypted_coeffs = vec![];
34 let mut s;
35 for c in scaled_pt.coeffs().iter() {
36 s = nearest_int(*c,half_q).rem_euclid(2);
37 decrypted_coeffs.push(s);
38 }
39 decrypted_coeffs
40}
41
42pub fn decrypt_string(sk_string: &String, ciphertext_base64: &String, params: &Parameters) -> String {
50 let (n, k) = (params.n, params.k);
52
53 let sk_array: Vec<i64> = decompress(sk_string);
55
56 let sk: Vec<Polynomial<i64>> = sk_array.chunks(n)
58 .map(|chunk| Polynomial::new(chunk.to_vec()))
59 .collect();
60
61 let ciphertext_list: Vec<i64> = decompress(ciphertext_base64);
63
64 let block_size = (k + 1) * n;
65 let num_blocks = ciphertext_list.len() / block_size;
66
67 let mut message_binary = vec![];
68
69 for i in 0..num_blocks {
70 let u_array = &ciphertext_list[i * block_size..i * block_size + k * n];
72 let v_array = &ciphertext_list[i * block_size + k * n..(i + 1) * block_size];
73
74 let u: Vec<Polynomial<i64>> = u_array.chunks(n)
75 .map(|chunk| Polynomial::new(chunk.to_vec()))
76 .collect();
77 let v = Polynomial::new(v_array.to_vec());
78
79 let m_b = decode_block(&sk, &u, &v, params);
81
82 message_binary.extend(m_b);
83 }
84
85 let byte_chunks: Vec<String> = message_binary.chunks(8)
87 .map(|chunk| chunk.iter().map(|bit| bit.to_string()).collect())
88 .collect();
89
90 let message_string: String = byte_chunks.iter()
92 .map(|byte| char::from_u32(i64::from_str_radix(byte, 2).unwrap() as u32).unwrap())
93 .collect();
94
95 message_string.trim_end_matches('\0').to_string()
97}
98
99fn decode_block(sk: &Vec<Polynomial<i64>>, u: &Vec<Polynomial<i64>>, v: &Polynomial<i64>, params: &Parameters) -> Vec<i64> {
100 let mut m_b = decrypt(sk, u, v, params);
101 m_b.resize(params.n, 0);
102 m_b
103}