Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
duyuefeng0708
GitHub Repository: duyuefeng0708/Cryptography-From-First-Principle
Path: blob/main/frontier/08-lattices-post-quantum/rust/src/lib.rs
483 views
unlisted
1
//! # Module 08: Lattices and Post-Quantum Cryptography — Exercises
2
//!
3
//! ## Progression
4
//! 1. `gram_schmidt_2d` — signature + doc
5
//! 2. `lll_reduce_2d` — signature + doc
6
//! 3. `lwe_keygen` — signature + doc
7
//! 4. `lwe_encrypt` — signature + doc
8
//! 5. `lwe_decrypt` — signature only
9
10
/// Compute the Gram-Schmidt orthogonalization of two 2D basis vectors.
11
///
12
/// Given basis vectors b1 and b2, compute the orthogonal basis b1*, b2*
13
/// where b2* = b2 - proj(b2, b1*).
14
///
15
/// Returns the orthogonalized basis as f64 vectors.
16
pub fn gram_schmidt_2d(b1: [i64; 2], b2: [i64; 2]) -> ([f64; 2], [f64; 2]) {
17
todo!("2D Gram-Schmidt orthogonalization")
18
}
19
20
/// Apply the LLL algorithm to a 2D lattice basis.
21
///
22
/// The LLL algorithm produces a "reduced" basis where the vectors are
23
/// nearly orthogonal and short. For 2D, this is equivalent to the
24
/// Gaussian lattice reduction algorithm.
25
///
26
/// Returns the reduced basis vectors.
27
pub fn lll_reduce_2d(b1: [i64; 2], b2: [i64; 2]) -> ([i64; 2], [i64; 2]) {
28
todo!("2D LLL (Gaussian) lattice reduction")
29
}
30
31
/// Generate an LWE key pair.
32
///
33
/// - Choose a random secret vector `s` of dimension `n` (mod `q`)
34
/// - Generate a random matrix `A` of size `m × n` (mod `q`)
35
/// - Compute `b = A*s + e` where `e` is a small noise vector
36
///
37
/// Returns `(A, b, s)` — public key is `(A, b)`, secret key is `s`.
38
pub fn lwe_keygen(n: usize, m: usize, q: i64) -> (Vec<Vec<i64>>, Vec<i64>, Vec<i64>) {
39
todo!("LWE key generation: A, b = As + e, s")
40
}
41
42
/// Encrypt a single bit using LWE.
43
///
44
/// To encrypt bit `msg` ∈ {0, 1}:
45
/// - Choose a random subset S of the rows of A
46
/// - Compute `u = Σ A[i] for i in S` (mod q)
47
/// - Compute `v = Σ b[i] for i in S + msg * ⌊q/2⌋` (mod q)
48
///
49
/// Returns ciphertext `(u, v)`.
50
pub fn lwe_encrypt(a: &[Vec<i64>], b: &[i64], msg: u8, q: i64) -> (Vec<i64>, i64) {
51
todo!("LWE encryption of a single bit")
52
}
53
54
/// Decrypt an LWE ciphertext.
55
///
56
/// Compute `v - <u, s>` mod q. If the result is closer to 0, the bit is 0.
57
/// If closer to q/2, the bit is 1.
58
pub fn lwe_decrypt(s: &[i64], u: &[i64], v: i64, q: i64) -> u8 {
59
todo!("LWE decryption: recover bit from noisy inner product")
60
}
61
62
#[cfg(test)]
63
mod tests {
64
use super::*;
65
66
#[test]
67
#[ignore]
68
fn test_gram_schmidt_2d() {
69
let (b1s, b2s) = gram_schmidt_2d([3, 1], [2, 2]);
70
// b1* should be unchanged
71
assert!((b1s[0] - 3.0).abs() < 1e-10);
72
assert!((b1s[1] - 1.0).abs() < 1e-10);
73
// b2* should be orthogonal to b1*
74
let dot = b1s[0] * b2s[0] + b1s[1] * b2s[1];
75
assert!(dot.abs() < 1e-10, "Should be orthogonal");
76
}
77
78
#[test]
79
#[ignore]
80
fn test_lll_reduce_2d() {
81
// A bad basis for the same lattice
82
let (r1, r2) = lll_reduce_2d([1, 0], [100, 1]);
83
// Reduced basis should have shorter vectors
84
let norm_sq = |v: [i64; 2]| (v[0] * v[0] + v[1] * v[1]) as f64;
85
assert!(norm_sq(r1) <= norm_sq([100, 1]) as f64);
86
assert!(norm_sq(r2) <= norm_sq([100, 1]) as f64);
87
}
88
89
#[test]
90
#[ignore]
91
fn test_lwe_roundtrip() {
92
let q = 97;
93
let (a, b, s) = lwe_keygen(4, 8, q);
94
for msg in [0u8, 1u8] {
95
let (u, v) = lwe_encrypt(&a, &b, msg, q);
96
let decrypted = lwe_decrypt(&s, &u, v, q);
97
assert_eq!(decrypted, msg, "LWE decrypt should recover the bit");
98
}
99
}
100
}
101
102