Diffie Hellman
1. Readme
迪菲-赫尔曼
迪菲-赫尔曼密钥交换
Alice 和 Bob 使用 迪菲-赫尔曼密钥来共享秘密。它们以素数开头,选择私钥,生成和共享公钥,然后生成共享密钥.
第 0 步
测试程序提供素数 p 和 g
.
步骤 1
Alice 选择一个大于 1 ,且小于 p 的私钥。鲍勃做同样的事情来选择私钥 b.
第 2 步
Alice 计算公钥 A.
A = g**a mod p
使用相同的 p 和 g, Bob 类似地从他的私钥 b 计算公钥 B.
第 3 步
Alice 和 Bob 交换公钥.Alice 计算密钥 s.
s = B**a mod p
鲍勃计算
s = A**b mod p
计算产生相同的结果! 爱丽丝和鲍勃现在分享秘密.
本练习的一种可能解决方案是实现您自己的模幂运算函数。要了解更多信息,请参阅following page.
资源
-
维基百科,来自 www.cryptopp.com/wiki 的 1024 位密钥.http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
2. 开始你的表演
pub fn private_key(p: u64) -> u64 { unimplemented!("Pick a private key greater than 1 and less than {}", p) } pub fn public_key(p: u64, g: u64, a: u64) -> u64 { unimplemented!( "Calculate public key using prime numbers {} and {}, and private key {}", p, g, a ) } pub fn secret(p: u64, b_pub: u64, a: u64) -> u64 { unimplemented!( "Calculate secret key using prime number {}, public key {}, and private key {}", p, b_pub, a ) }
3. 测试代码查看
# #![allow(unused_variables)] #fn main() { #[test] fn test_private_key_in_range_key() { let primes: Vec<u64> = vec![ 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 773, 967, 3461, 6131, ]; let private_keys: Vec<u64> = primes.iter().map(|x| private_key(*x)).collect(); for i in 0..primes.len() { assert!(1 < private_keys[i] && private_keys[i] < primes[i]); } } #[test] //#[ignore] fn test_public_key_correct() { let p: u64 = 23; let g: u64 = 5; let private_key: u64 = 6; let expected: u64 = 8; assert_eq!(public_key(p, g, private_key), expected); } #[test] //#[ignore] fn test_secret_key_correct() { let p: u64 = 11; let private_key_a = 7; let public_key_b = 8; let secret = secret(p, public_key_b, private_key_a); let expected = 2; assert_eq!(secret, expected); } #[test] //#[ignore] fn test_public_key_correct_big_numbers() { let p: u64 = 4_294_967_299; let g: u64 = 8; let private_key: u64 = 4_294_967_296; let expected: u64 = 4096; assert_eq!(public_key(p, g, private_key), expected); } #[test] //#[ignore] fn test_secret_key_correct_big_numbers() { let p: u64 = 4_294_967_927; let private_key_a = 4_294_967_300; let public_key_b = 843; let secret = secret(p, public_key_b, private_key_a); let expected = 1_389_354_282; assert_eq!(secret, expected); } #[test] //#[ignore] fn test_changed_secret_key() { let p: u64 = 13; let g: u64 = 11; let private_key_a = private_key(p); let private_key_b = private_key(p); let public_key_a = public_key(p, g, private_key_a); let public_key_b = public_key(p, g, private_key_b); // Key exchange let secret_a = secret(p, public_key_b, private_key_a); let secret_b = secret(p, public_key_a, private_key_b); assert_eq!(secret_a, secret_b); } #}
4. 答案
# #![allow(unused_variables)] #fn main() { extern crate rand; use rand::{thread_rng, Rng}; /// Right-to-left modular exponentiation implementation /// For more information see https://en.wikipedia.org/wiki/Modular_exponentiation fn modular_exponentiation(base: u64, exponent: u64, modulus: u64) -> u64 { let mut result = 1; let mut e = exponent; let mut b = base; while e > 0 { if (e & 1) == 1 { result = (result * b) % modulus; } e >>= 1; b = (b * b) % modulus; } result } pub fn private_key(p: u64) -> u64 { let mut rng = thread_rng(); rng.gen_range(2, p) } pub fn public_key(p: u64, g: u64, a: u64) -> u64 { modular_exponentiation(g, a, p) } pub fn secret(p: u64, b_pub: u64, a: u64) -> u64 { modular_exponentiation(b_pub, a, p) } #}