Pack polynomial with coefficients in [Q-eta, Q+eta] into bytes. For eta=2: packs coefficients into 3 bits each (96 bytes total) For eta=4: packs coefficients into 4 bits each (128 bytes total) Assumes coefficients are not normalized, but in [q-η, q+η].
fn polyPackLeqEta(p: Poly, comptime eta: u8, buf: []u8) void
fn polyPackLeqEta(p: Poly, comptime eta: u8, buf: []u8) void {
comptime {
if (eta != 2 and eta != 4) {
@compileError("eta must be 2 or 4");
}
}
if (eta == 2) {
// 3 bits per coefficient: pack 8 coefficients into 3 bytes
var j: usize = 0;
var i: usize = 0;
while (i < buf.len) : (i += 3) {
const c0 = Q + eta - p.cs[j];
const c1 = Q + eta - p.cs[j + 1];
const c2 = Q + eta - p.cs[j + 2];
const c3 = Q + eta - p.cs[j + 3];
const c4 = Q + eta - p.cs[j + 4];
const c5 = Q + eta - p.cs[j + 5];
const c6 = Q + eta - p.cs[j + 6];
const c7 = Q + eta - p.cs[j + 7];
buf[i] = @truncate(c0 | (c1 << 3) | (c2 << 6));
buf[i + 1] = @truncate((c2 >> 2) | (c3 << 1) | (c4 << 4) | (c5 << 7));
buf[i + 2] = @truncate((c5 >> 1) | (c6 << 2) | (c7 << 5));
j += 8;
}
} else { // eta == 4
// 4 bits per coefficient: pack 2 coefficients into 1 byte
var j: usize = 0;
for (0..buf.len) |i| {
const c0 = Q + eta - p.cs[j];
const c1 = Q + eta - p.cs[j + 1];
buf[i] = @truncate(c0 | (c1 << 4));
j += 2;
}
}
}