Pack polynomial with coefficients in (-gamma1, gamma1] into bytes. For gamma1_bits=17: packs 18 bits per coefficient (4 coefficients into 9 bytes) For gamma1_bits=19: packs 20 bits per coefficient (2 coefficients into 5 bytes) Assumes coefficients are normalized.
fn polyPackLeGamma1(p: Poly, comptime gamma1_bits: u8, buf: []u8) void
fn polyPackLeGamma1(p: Poly, comptime gamma1_bits: u8, buf: []u8) void {
const gamma1: u32 = @as(u32, 1) << gamma1_bits;
if (gamma1_bits == 17) {
// Pack 4 coefficients into 9 bytes (18 bits each)
var j: usize = 0;
var i: usize = 0;
while (i < buf.len) : (i += 9) {
// Convert from [0,γ₁] ∪ (Q-γ₁, Q) to [0, 2γ₁)
const p0 = centeredToPositive(p.cs[j], gamma1);
const p1 = centeredToPositive(p.cs[j + 1], gamma1);
const p2 = centeredToPositive(p.cs[j + 2], gamma1);
const p3 = centeredToPositive(p.cs[j + 3], gamma1);
buf[i] = @truncate(p0);
buf[i + 1] = @truncate(p0 >> 8);
buf[i + 2] = @truncate((p0 >> 16) | (p1 << 2));
buf[i + 3] = @truncate(p1 >> 6);
buf[i + 4] = @truncate((p1 >> 14) | (p2 << 4));
buf[i + 5] = @truncate(p2 >> 4);
buf[i + 6] = @truncate((p2 >> 12) | (p3 << 6));
buf[i + 7] = @truncate(p3 >> 2);
buf[i + 8] = @truncate(p3 >> 10);
j += 4;
}
} else if (gamma1_bits == 19) {
// Pack 2 coefficients into 5 bytes (20 bits each)
var j: usize = 0;
var i: usize = 0;
while (i < buf.len) : (i += 5) {
const p0 = centeredToPositive(p.cs[j], gamma1);
const p1 = centeredToPositive(p.cs[j + 1], gamma1);
buf[i] = @truncate(p0);
buf[i + 1] = @truncate(p0 >> 8);
buf[i + 2] = @truncate((p0 >> 16) | (p1 << 4));
buf[i + 3] = @truncate(p1 >> 4);
buf[i + 4] = @truncate(p1 >> 12);
j += 2;
}
} else {
@compileError("gamma1_bits must be 17 or 19");
}
}