1use crate::{Polynomial, RingParams, bitwriting::BitWriter};
2
3fn log2_ceil(q: u64) -> u32 {
4 if q <= 1 {
5 0
6 } else {
7 64 - (q - 1).leading_zeros()
8 }
9}
10
11impl RingParams {
12 pub fn encode_a(&self, seed: &[u8; 32], b: &Polynomial) -> Vec<u8> {
13 let mut writer = BitWriter::new(1792 + 32);
14
15 for &byte in seed {
16 writer.write_bits(byte as u64, 8);
17 }
18
19 for coeff in b.coeffs.clone() {
20 writer.write_bits(coeff, log2_ceil(self.q) as usize);
21 }
22
23 writer.finish()
24 }
25
26 pub fn decode_a(&self, msg: &[u8]) -> ([u8; 32], Polynomial) {
27 let mut seed = [0u8; 32];
28
29 let mut bit_index = 0;
30
31 let mut read_bits = |bits: usize| -> u64 {
32 let mut val = 0u64;
33 for i in 0..bits {
34 let byte = msg[(bit_index + i) / 8];
35 let bit = (byte >> ((bit_index + i) % 8)) & 1;
36 val |= (bit as u64) << i;
37 }
38 bit_index += bits;
39 val
40 };
41
42 for i in 0..32 {
43 seed[i] = read_bits(8) as u8;
44 }
45
46 let mut b = Vec::with_capacity(self.n);
47 for _ in 0..self.n {
48 b.push(read_bits(log2_ceil(self.q) as usize));
49 }
50
51 (seed, Polynomial::new(b))
52 }
53
54
55 pub fn encode_b(&self, u: &Polynomial, r: &Vec<u8>) -> Vec<u8> {
56 let mut writer = BitWriter::new(2048);
57
58 for coeff in u.coeffs.clone() {
59 writer.write_bits(coeff, log2_ceil(self.q) as usize);
60 }
61
62 for &bit in r {
63 writer.write_bit(bit);
64 }
65
66 writer.finish()
67 }
68
69 pub fn decode_b(&self, msg: &[u8]) -> (Polynomial, Vec<u8>) {
70 let mut bit_index = 0;
71
72 let mut read_bits = |bits: usize| -> u64 {
73 let mut val = 0u64;
74 for i in 0..bits {
75 let byte = msg[(bit_index + i) / 8];
76 let bit = (byte >> ((bit_index + i) % 8)) & 1;
77 val |= (bit as u64) << i;
78 }
79 bit_index += bits;
80 val
81 };
82
83 let mut u = Vec::with_capacity(self.n);
84 for _ in 0..self.n {
85 u.push(read_bits(log2_ceil(self.q) as usize));
86 }
87
88 let mut r = Vec::with_capacity(self.n);
89 for _ in 0..self.n {
90 r.push(read_bits(1) as u8);
91 }
92
93 (Polynomial::new(u), r)
94 }
95}