From 5e3f12beb511fe0a4ecca129efc350c4bbe0b507 Mon Sep 17 00:00:00 2001 From: Sam Hadow Date: Wed, 2 Apr 2025 15:12:55 +0200 Subject: [PATCH] create lattice --- src/matrix.rs | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/matrix.rs b/src/matrix.rs index b0f36e1..6558e6e 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -16,8 +16,26 @@ impl Matrix { None } } -} + pub fn new_lattice(noise_bits: usize, ciphertexts: Vec) -> Option { + let n = ciphertexts.len(); + let mut values = Vec::with_capacity(n * n); + + // First row: [2^noise_bits, ciphertexts[0], ciphertexts[1], ..., ciphertexts[t]] + values.push((2.0f64).powi(noise_bits as i32)); + values.extend_from_slice(&ciphertexts[1..]); + + // -x0 on diagonal, 0 everywhere else + let x0 = ciphertexts[0]; + for i in 0..n - 1 { + let mut row = vec![0.0; n]; + row[i] = -x0; + values.extend(row); + } + + Matrix::new(n, values) + } +} impl Index<(usize, usize)> for Matrix { type Output = f64; @@ -32,7 +50,6 @@ impl IndexMut<(usize, usize)> for Matrix { } } - #[cfg(test)] mod tests { use super::*; @@ -56,4 +73,19 @@ mod tests { m[(1, 0)] = 5.0; assert_eq!(m[(1, 0)], 5.0); } + #[test] + fn test_new_lattice() { + let ciphertexts = vec![5.0, 8.0, 12.0]; // x0=5.0, x1=8.0, x2=12.0 + let noise_bits = 2; + + // Expected matrix (3x3): + // [ 2^2, x1, x2 ] = [4.0, 8.0, 12.0] + // [ -x0, 0, 0 ] = [-5.0, 0.0, 0.0] + // [ 0, -x0, 0 ] = [0.0, -5.0, 0.0] + let expected_values = vec![4.0, 8.0, 12.0, -5.0, 0.0, 0.0, 0.0, -5.0, 0.0]; + + let lattice = Matrix::new_lattice(noise_bits, ciphertexts).unwrap(); + assert_eq!(lattice.n, 3); + assert_eq!(lattice.values, expected_values); + } }