Rust : 用rust实现Diffe-Hellman算法

   2023-02-09 学习力0
核心提示:一、什么是D-H算法【参考了相关资料】迪菲-赫尔曼**交换(Diffie–Hellman key exchange,简称“D–H”) 是一种安全协议,不是加密协议。它可以让双方在完全没有对方任何预先信息的条件下通过不安全信道建立起一个**。这个**可以在后续的通讯中作为对称**来

一、什么是D-H算法【参考了相关资料】
迪菲-赫尔曼**交换(Diffie–Hellman key exchange,简称“D–H”) 是一种安全协议,不是加密协议。它可以让双方在完全没有对方任何预先信息的条件下通过不安全信道建立起一个**。这个**可以在后续的通讯中作为对称**来加密通讯内容。

迪菲-赫尔曼**交换是1976年在Whitfield Diffie和Martin Hellman的合作下发明的。它是第一个实用的在非保护信道中建立共享**方法。

这个方案首先由Whitfield Diffie和Martin Hellman于1976发布。后来发现这个方案已经在之前几年由英国信号情报部门发明(发明者为Malcolm J. Williamson),但是当时这被列为是机密。2002年,赫尔曼建议将该算法改名为Diffie–Hellman–Merkle**交换以表明 Ralph Merkle对于公钥加密算法的贡献(Hellman, 2002)。

2002年,Martin Hellman写到:

这个系统…从此被称为迪菲-赫尔曼**交换。 虽然这个系统首先是在我和迪菲的一篇论文中描述的,但是这却是一个公钥交换系统,是Merkle提出的概念,因此如果加上他的名字,这个系统实际上应该称为’Diffie–Hellman–Merkle**交换’。我希望这个小小的讲坛可以帮助我们认识到Merkle对公钥密码学的同等重要的贡献。

美国专利 4,200,770, 现在已经过期。它描述了这个算法,并且表明了Hellman、Diffie和Merkle是算法的发明者。

二、相关的算法重点:
模有关的公式:

a*b mod n ≡ ( (a mod n) * (b mod n ) ) mod n

1、什么是元根(primitive_root),为什么需要元根?

(1)定义:若p为一个质数,若存在1<a<=p-1,使得:
a mod p,
a^2 mod p,
a^3 mod p,

a^(p-1) mod p ,两两互不相同,且构成一个1~p-1的全体数的一个排列,则a为p的原根。(元根可能有多个)。

(2)为什么需要元根?,元根的意义是什么?

元根有一些特别的特性:比如
对于p=5,那么,2和3就是其元根。在这种情况下,对于元根2,存在这种关系
2^0 =1mod5
2^1= 2mod5
2^2 =4 mod5
2^3 =3 mod5
2^4 =1 mod5
3也是一样的。
(3)为什么需要的是质数?

当 a, p都为质数时,可以利用欧拉定理,来快速计算。具体可以参考相关数论书。密码学离开欧拉定理根本就玩不转。
欧拉函数φ的定义:对于正整数N,代表小于等于N的与N互质的数的个数,记作φ(N)。
特别地,对于N为质数时,φ(N)=N-1;
欧拉定理:
若N>2; a与N互质,则a^(φ(N)) ≡1modN .

如何应用:比如,对于 3^2018 mod 7,我们就可以:
φ(7) =6;
根据欧拉定理,则有:
3^(φ(7)) mod 7
=3^6 mod 7
=1 mod7;

那么
3 ^2018 mod7
= (3^6 ) ^336 * 3^2 mod7 =( ((3^6 ) ^336 mod7 )* (3^2 mod7) ) mod7
=( 1* (3^2 mod7) ) mod7
=1*2 mod7
=2

如果不是质数,那这个情况就不容易处理了。

实际操作中,元根也会选择是一个质数的元根。这样,元根和欧拉定理的性质都能用上了。

思考一下:假定元根为a =113,N =2^127 -1 即
 113^ 19 mod N,如何计算?

2、指数模的计算(x^y mod p),当x,y值较大时,直接计算是不可行了,需要借助算法。
Rust : 用rust实现Diffe-Hellman算法

3、为什么D-H算法会有效?

D-H算法的实质是,
(1)对于给定K,G,p 三个值,求K=(G^a ) % p,中a的值;
或者
(2)给定M,G,p 三个值,求M= (G^b) % p , 中b的值;
其中(1),K为A发给B的值;G,p是已知,G为元根,p为大质数。(2)同样。

可以看出,一方面,非常困难 。即上面的式子,在p为大质数时,G为元根的情况下,(1)或(2)的求解,目前没有快速的算法,只有暴力**,但耗时过长。【不信你可以试试,反正我是试过了,电脑一直不动】。
另一方面,却非常容易。即已知(G^a ) % p,中G,a, p;却很容易算出K; 【后面也有算法哈】

同一个公式的两边,形成了一个非常困难和一个非常容易(象不象RSA的结构?),形成一个严重不对称的结构(即单向陷门函数的特征),因此,可以用来进行密码处理。

三、相关的rust 代码

use std::{thread, time};
//D-H密码交换
fn is_prime(n: u128) -> bool {
    !(2..(n)).any(|x| n % x == 0)
}
fn max_prime(n: u128) -> u128 {
    let mut num = n;
    while !is_prime(num) {
        num = num - 1;
    }
    num
}
// x^y mod p 如何计算 13^15679 mod 458
fn pow_mod(x: u128, y: u128, p: u128) -> u128 {
    if y == 0 {
        return 1;
    } else {
        let z = pow_mod(x, y / 2, p); //如果y=5_u128, y/2=2
        if y % 2 == 0 {
            return ((z % p) * (z % p)) % p;
        } else {
            return ((((x % p) * (z % p)) % p) * (z % p)) % p;
        }
    }
}

//求p 原始根 的集合,最多产生元根的上限,从小至大
fn generator_primitive_root(p: u128, num: u128) -> Vec<u128> {
    if !is_prime(p) {
        panic!("p:{} is not prime!", p);
    }
    let mut values: Vec<u128> = Vec::new();
    let target = (1..p).map(|x| x).collect::<Vec<u128>>();
    for i in 1..p {
        if values.len() as u128 > num {
            return values;
        }
        let mut temp_value: Vec<u128> = (1..p).map(|y| pow_mod(i, y, p)).collect();
        temp_value.sort();
        if temp_value == target {
            values.push(i);
            //println!("value:{:?}=>{}",temp_value,x);
        }
    }
    println!("元根value:{:?}", values);
    values
}
//求 指数i, 即为b(任意数)的以a为基数的模p的离散对数。
fn dis_log(b: u128, a: u128, p: u128) -> u128 {
    //对于任意数b及素数p的原始根a,可以找到一个唯一的指数i,满足:b=( a ^ i) mod p,其中 0≤i≤p-1
    let data: Vec<u128> = (0..p - 1).filter(|&i| pow_mod(a, i, p) == b).collect();
    println!("dis_log=> i ={:?}", data);
    data[0]
}
fn main() {
    let sleep_seconds = time::Duration::from_secs(1000);
    let randnum = 1259_u128; //随机输入一个较大的值
    let max_prime = max_prime(randnum); //求出randnum中最大的质数
    let groups_primitive_root = generator_primitive_root(max_prime, 50); //50个原根
    let G_primitive_root = *&groups_primitive_root[10]; //10为随机取,指取第11个元根集合数据
    let P = max_prime;
    let A_private_key = 14_u128; // no open
    let B_private_key = 39_u128; // no open
    let A_send_to_B_num = pow_mod(G_primitive_root, A_private_key, P);
    let B_send_to_A_num = pow_mod(G_primitive_root, B_private_key, P);
    let A_compute_key_num = pow_mod(B_send_to_A_num, A_private_key, P);
    let B_compute_key_num = pow_mod(A_send_to_B_num, B_private_key, P);
    println!("测试中的参数:");
    println!("G_primitive_root : {:?}", G_primitive_root);
    println!("A_send_to_B_num  : {:?}", A_send_to_B_num);
    println!("B_send_to_A_num  : {:?}", B_send_to_A_num);
    println!("A_compute_key_num: {:?}", A_compute_key_num);
    println!("B_compute_key_num: {:?}", B_compute_key_num);

    println!("\n真实环境中的参数:");
    // 真实中的加密参数
    let g: u128 = 113;
    let p: u128 = 2_u128.pow(128) - 1; //巨大的质数
    let a_private_key = 19; //保密
    let b_private_key = 23; //保密
    let a_send_to_b_num = pow_mod(g, a_private_key, p);
    let b_send_to_a_num = pow_mod(g, b_private_key, p);
    println!("真实环境中的A发送的值:{}", a_send_to_b_num);
    println!("真实环境中的B发送的值:{}", b_send_to_a_num);
    let a_compute_key_num = pow_mod(b_send_to_a_num, a_private_key, p);
    let b_compute_key_num = pow_mod(a_send_to_b_num, b_private_key, p);
    println!("真实环境中a_compute_key_num:{:?}", a_compute_key_num);
    println!("真实环境中b_compute_key_num:{:?}", b_compute_key_num);

    println!("mod:{}", pow_mod(48_u128, 23_u128, 187));
    thread::sleep(sleep_seconds);
}

四、输出结果:

Rust : 用rust实现Diffe-Hellman算法

可见,在元根为32的情况下,A发送给B的数值为964;B发送给A的数值为145;但是,各自都拥有了共同的**822.可见算法经过了验证。

需要说明的是:上述算法,并没有得到与第三方验证。目前只是一种了解性的参考。

五、为什么D-H算法会有效?

问题在,当p较大时,计算元根将非常耗时,所有本文采用选用前多少个元根。尽管如何,当p较大时,计算3-5个元根集,就是巨大的运算量。因此,暴力**花的时间将非常长。

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • bloom-server 基于 rust 编写的 rest api cache 中间件
    bloom-server 基于 rust 编写的 rest api cache
    bloom-server 基于 rust 编写的 rest api cache 中间件,他位于lb 与api worker 之间,使用redis 作为缓存内容存储, 我们需要做的就是配置proxy,同时他使用基于share 的概念,进行cache 的分布存储,包含了请求端口(proxy,访问数据) 以及cache 控制端口(
    03-08
  • #新闻拍一拍# Oracle 调研如何避免让 Java 开发者投奔 Rust 和 Kotlin | Linux 中国
    #新闻拍一拍# Oracle 调研如何避免让 Java 开发
     导读:• 英特尔对迟迟不被 Linux 主线接受的 SGX Enclave 进行了第 38 次修订 • ARM 支持开源的 Panfrost Gallium3D 驱动本文字数:977,阅读时长大约:1分钟作者:硬核老王Oracle 调研如何避免让 Java 开发者投奔 Rust 和 KotlinOracle 委托分析公司 Omd
    03-08
  • Linux系统下Rust快速安装:国内镜像加速
    Linux系统下Rust快速安装:国内镜像加速
    官方网址和方法Install Rust - Rust Programming Language然而速度慢得让人难以置信。利用国内镜像进行windows的Linux子系统的Rust安装。rust 使用国内镜像,快速安装方法参考:RUST安装慢怎么办,使用镜像方式安装_网络_为中华之崛起而编程-CSDN博客我的操作
    03-08
  • Rust到底值不值得学--Rust对比、特色和理念
    前言其实我一直弄不明白一点,那就是计算机技术的发展,是让这个世界变得简单了,还是变得更复杂了。当然这只是一个玩笑,可别把这个问题当真。然而对于IT从业者来说,这可不是一个玩笑。几乎每一次的技术发展,都让这个生态变得更为复杂。“英年早秃”已经成
    03-08
  • 超33000行新代码,为Linux内核添加Rust支持的补丁已准备就绪
    超33000行新代码,为Linux内核添加Rust支持的补
    https://mp.weixin.qq.com/s/oKw9aBJSdmRoO6-rbLAkNw7 月 4 日,一套修订后的补丁被提交至 Linux 内核的邮件列表中,该补丁为在 Linux 内核中以 Rust 作为辅助编程语言提供了支持,借助 Rust 可以提高 Linux 内核和内存的安全。整套补丁包含 17 个子项,不光
    03-08
  • 【译】Rust 的 Result 类型入门
    【译】Rust 的 Result 类型入门
    A Primer on Rust’s Result Type 译文原文链接:https://medium.com/@JoeKreydt/a-primer-on-rusts-result-type-66363cf18e6a原文作者:Joe Kreydt译文出处:https://github.com/suhanyujie/article-transfer-rs译者:suhanyujietips:水平有限,翻译不当之
    03-08
  • Rust实战系列-基本语法
    Rust实战系列-基本语法
    主要介绍 Rust 的语法、基本类型和数据结构,通过实现一个简单版 grep 命令行工具,来理解 Rust 独有的特性。本文是《Rust in action》学习总结系列的第二部分,更多内容请看已发布文章:一、Rust实战系列-Rust介绍“主要介绍 Rust 的语法、基本类型和数据结
    03-08
  • 全栈程序员的新玩具Rust(三)板条箱
    上次用到了stdout,这次我们来写一个更复杂一点的游戏rust的标准库叫做std,默认就会引入。这次我们要用到一个随机数函数,而随机数比较尴尬的一点是这玩意不在标准库中,我们要额外依赖一个库。很多编程方案都有自己的模块化库系统,rust也不例外,不过rust
    02-10
  • 全栈程序员的新玩具Rust(六)第一个WASM程序
    全栈程序员的新玩具Rust(六)第一个WASM程序
    先上代码https://gitee.com/lightsever/rust_study/tree/master/wasm_hello01webassembly就不用再赘述了,耳朵里面快磨出茧子来了。rustwasm是火狐自家的玩具,让我们来继续做实验,让rust飞起来吧。环境安装安装好rust环境之后仍然需要 一个 wasm 工具包carg
    02-10
  • 【Rust】标准库-Result rust数据库
    环境Rust 1.56.1VSCode 1.61.2概念参考:https://doc.rust-lang.org/stable/rust-by-example/std/result.html示例main.rsmod checked {#[derive(Debug)]pub enum MathError {DivisionByZero,NonPositiveLogarithm,NegativeSquareRoot,}pub type MathResult =
    02-09
点击排行