Skip to main content

simple_ring/
encoding.rs

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}