Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
duyuefeng0708
GitHub Repository: duyuefeng0708/Cryptography-From-First-Principle
Path: blob/main/foundations/05-discrete-log-diffie-hellman/rust/src/lib.rs
483 views
unlisted
1
//! # Module 05: Discrete Logarithm and Diffie-Hellman — Exercises
2
//!
3
//! ## Progression
4
//! 1. `discrete_log_brute` — Scaffolded (simple loop)
5
//! 2. `baby_step_giant_step` — Scaffolded (HashMap hint)
6
//! 3. `diffie_hellman` — Independent
7
//! 4. `pohlig_hellman` — Independent
8
//! 5. `is_safe_prime` — Independent
9
10
use std::collections::HashMap;
11
12
/// Compute discrete log by brute force: find `x` such that `g^x ≡ h (mod p)`.
13
///
14
/// Returns `None` if no solution exists within `p - 1` steps.
15
pub fn discrete_log_brute(g: u64, h: u64, p: u64) -> Option<u64> {
16
// Try x = 0, 1, 2, ... computing g^x mod p each time.
17
// Hint: keep a running product instead of recomputing from scratch.
18
todo!("Brute-force discrete log search")
19
}
20
21
/// Baby-step giant-step algorithm for discrete log.
22
///
23
/// Finds `x` such that `g^x ≡ h (mod p)`, where the group order is `n`.
24
/// Runs in O(√n) time and space.
25
///
26
/// Algorithm:
27
/// m = ceil(√n)
28
/// Baby steps: store g^j -> j for j = 0..m
29
/// Giant steps: for i = 0..m, check if h * (g^(-m))^i is in the table
30
pub fn baby_step_giant_step(g: u64, h: u64, p: u64, n: u64) -> Option<u64> {
31
// Hint: use HashMap<u64, u64> for the baby step table.
32
// You'll need mod_inverse of g^m to compute giant steps.
33
todo!("BSGS discrete log in O(sqrt(n))")
34
}
35
36
/// Simulate a Diffie-Hellman key exchange.
37
///
38
/// Given generator `g` and prime `p`, and two secret keys `a` and `b`:
39
/// Returns `(A, B, shared)` where A = g^a mod p, B = g^b mod p,
40
/// and shared = g^(ab) mod p.
41
pub fn diffie_hellman(g: u64, p: u64, a: u64, b: u64) -> (u64, u64, u64) {
42
todo!("DH key exchange: compute public keys and shared secret")
43
}
44
45
/// Pohlig-Hellman algorithm: solve DLP when the group order factors into small primes.
46
///
47
/// Given `g^x ≡ h (mod p)` and the factorization of the group order `n = p-1`,
48
/// solve the DLP in each prime-power subgroup and combine with CRT.
49
///
50
/// `factors` is a list of (prime, exponent) pairs such that n = ∏ p_i^e_i.
51
pub fn pohlig_hellman(
52
g: u64,
53
h: u64,
54
p: u64,
55
factors: &[(u64, u32)],
56
) -> u64 {
57
todo!("Pohlig-Hellman: solve DLP via subgroup decomposition + CRT")
58
}
59
60
/// Check if `p` is a safe prime: `p` is prime and `(p-1)/2` is also prime.
61
///
62
/// Safe primes resist Pohlig-Hellman because (p-1) = 2 * q where q is a large prime.
63
pub fn is_safe_prime(p: u64) -> bool {
64
todo!("Check if p and (p-1)/2 are both prime")
65
}
66
67
#[cfg(test)]
68
mod tests {
69
use super::*;
70
71
#[test]
72
#[ignore]
73
fn test_discrete_log_brute() {
74
// 3^x ≡ 6 (mod 7). Answer: x = 3 (3^3 = 27 ≡ 6)
75
assert_eq!(discrete_log_brute(3, 6, 7), Some(3));
76
}
77
78
#[test]
79
#[ignore]
80
fn test_discrete_log_brute_identity() {
81
// g^0 = 1 for any g
82
assert_eq!(discrete_log_brute(5, 1, 13), Some(0));
83
}
84
85
#[test]
86
#[ignore]
87
fn test_bsgs() {
88
// 2^x ≡ 3 (mod 5), order 4. Answer: x = 3
89
assert_eq!(baby_step_giant_step(2, 3, 5, 4), Some(3));
90
}
91
92
#[test]
93
#[ignore]
94
fn test_diffie_hellman() {
95
let (big_a, big_b, shared) = diffie_hellman(5, 23, 6, 15);
96
assert_eq!(big_a, 8); // 5^6 mod 23
97
assert_eq!(big_b, 19); // 5^15 mod 23
98
// Both sides compute the same shared secret
99
// A^b = 8^15 mod 23 = B^a = 19^6 mod 23
100
assert_eq!(shared, 2);
101
}
102
103
#[test]
104
#[ignore]
105
fn test_is_safe_prime() {
106
assert!(is_safe_prime(23)); // (23-1)/2 = 11, both prime
107
assert!(!is_safe_prime(37)); // (37-1)/2 = 18, not prime
108
}
109
}
110
111