SDA lattice attack, need to fix LLL part
This commit is contained in:
		
							
								
								
									
										22
									
								
								src/lll.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/lll.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| use lll_rs::{matrix::Matrix as LLLMatrix, vector::BigVector}; | ||||
|  | ||||
| use crate::matrix::Matrix; | ||||
|  | ||||
| impl Matrix { | ||||
|     pub fn to_lll_matrix(&self) -> LLLMatrix<BigVector> { | ||||
|         let n = self.n; | ||||
|         let mut lll_mat = LLLMatrix::init(n, n); | ||||
|  | ||||
|         for row_idx in 0..n { | ||||
|             let mut elements = Vec::with_capacity(n); | ||||
|  | ||||
|             for col_idx in 0..n { | ||||
|                 let val = self[(row_idx, col_idx)].clone(); | ||||
|                 elements.push(val); | ||||
|             } | ||||
|  | ||||
|             lll_mat[row_idx] = BigVector::from_vector(elements); | ||||
|         } | ||||
|         lll_mat | ||||
|     } | ||||
| } | ||||
							
								
								
									
										39
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -1,5 +1,42 @@ | ||||
| use rug::Integer; | ||||
| use crate::matrix::Matrix; | ||||
| use lll_rs::lll::biglll; | ||||
| mod lll; | ||||
| mod matrix; | ||||
|  | ||||
| fn main() { | ||||
|     println!(""); | ||||
|     // 1. Build lattice matrix basis | ||||
|     let ciphertexts = vec![ | ||||
| Integer::from(37459), | ||||
| Integer::from(8227), | ||||
| Integer::from(44119), | ||||
| Integer::from(22575), | ||||
| Integer::from(9249), | ||||
| Integer::from(38483), | ||||
| Integer::from(26181), | ||||
|     ]; | ||||
|     let noise_bits = 2; | ||||
|     let basis_matrix = Matrix::new_lattice(noise_bits, ciphertexts.clone()).unwrap(); | ||||
|  | ||||
|     println!("matrix: {:?}", basis_matrix); | ||||
|  | ||||
|     // 2. reduce with LLL | ||||
|     let mut lll_matrix = basis_matrix.to_lll_matrix(); | ||||
|     biglll::lattice_reduce(&mut lll_matrix); | ||||
|  | ||||
|     // 3. Extract shortest vector | ||||
|     let shortest_vector = &lll_matrix[0]; | ||||
|     println!("Shortest vector: {:?}", shortest_vector); | ||||
|  | ||||
|     // 4. q0 candidate | ||||
|     let q0 = &shortest_vector[0] / (Integer::from(1) << (noise_bits + 1)); | ||||
|  | ||||
|     // 5. Find p | ||||
|     // compute r0 = x0 (mod q0) | ||||
|     // and p = (x0 − r0)/q0. | ||||
|     let x0 = &ciphertexts[0]; | ||||
|     let r0 = x0 % q0.clone(); | ||||
|     let p_guess = (x0 - r0) / q0; | ||||
|  | ||||
|     println!("Recovered p: {}", p_guess); | ||||
| } | ||||
|   | ||||
| @@ -11,14 +11,14 @@ macro_rules! int { | ||||
|  | ||||
| #[derive(Debug, PartialEq)] | ||||
| pub struct Matrix { | ||||
|     pub n: usize, //rows | ||||
|     pub n: usize, // rows | ||||
|     pub m: usize, // columns | ||||
|     values: Vec<Element>, | ||||
| } | ||||
|  | ||||
| impl Matrix { | ||||
|     pub fn new(n: usize, m: usize, values: Vec<Element>) -> Option<Self> { | ||||
|         if n*m == values.len() { | ||||
|         if n * m == values.len() { | ||||
|             Some(Matrix { n, m, values }) | ||||
|         } else { | ||||
|             None | ||||
| @@ -29,8 +29,8 @@ impl Matrix { | ||||
|         let n = ciphertexts.len(); | ||||
|         let mut values = Vec::with_capacity(n * n); | ||||
|  | ||||
|         // First row: [2^noise_bits, ciphertexts[1], ..., ciphertexts[t]] | ||||
|         values.push(int!(2u64).pow(noise_bits as u32)); | ||||
|         // First row: [2^(noise_bits+1), ciphertexts[1], ..., ciphertexts[t]] | ||||
|         values.push(int!(2u64).pow(noise_bits as u32 + 1)); | ||||
|         values.extend_from_slice(&ciphertexts[1..]); | ||||
|  | ||||
|         // -x0 on diagonal, 0 everywhere else | ||||
| @@ -48,7 +48,7 @@ impl Matrix { | ||||
| impl Index<(usize, usize)> for Matrix { | ||||
|     type Output = Element; | ||||
|     fn index(&self, index: (usize, usize)) -> &Self::Output { | ||||
|         if index.0>=self.m || index.1 >= self.n { | ||||
|         if index.0 >= self.m || index.1 >= self.n { | ||||
|             panic!(); | ||||
|         } | ||||
|         &self.values[(self.n * index.0) + index.1] | ||||
| @@ -57,7 +57,7 @@ impl Index<(usize, usize)> for Matrix { | ||||
|  | ||||
| impl IndexMut<(usize, usize)> for Matrix { | ||||
|     fn index_mut(&mut self, index: (usize, usize)) -> &mut Self::Output { | ||||
|         if index.0>=self.m || index.1 >= self.n { | ||||
|         if index.0 >= self.m || index.1 >= self.n { | ||||
|             panic!(); | ||||
|         } | ||||
|         &mut self.values[(self.n * index.0) + index.1] | ||||
| @@ -91,7 +91,12 @@ mod tests { | ||||
|         m[(1, 0)] = int!(5); | ||||
|         assert_eq!(m[(1, 0)], int!(5)); | ||||
|  | ||||
|         let m2 = Matrix::new(3, 2, vec![int!(1), int!(2), int!(3), int!(4), int!(5), int!(6)]).unwrap(); | ||||
|         let m2 = Matrix::new( | ||||
|             3, | ||||
|             2, | ||||
|             vec![int!(1), int!(2), int!(3), int!(4), int!(5), int!(6)], | ||||
|         ) | ||||
|         .unwrap(); | ||||
|         assert_eq!(m2[(0, 2)], int!(3)); | ||||
|         assert_eq!(m2[(1, 0)], int!(4)); | ||||
|         let result = panic::catch_unwind(|| { | ||||
| @@ -111,7 +116,7 @@ mod tests { | ||||
|         let noise_bits = 2; | ||||
|  | ||||
|         let expected_values = vec![ | ||||
|             int!(4), | ||||
|             int!(8), | ||||
|             int!(8), | ||||
|             int!(12), | ||||
|             int!(0), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user