【密码学】数学基础-离散对数

简介: 本文来聊一聊有关离散对数的相关知识,接下来在讲DH的秘钥交换协议等算法之前,有必要先来说一下离散对数的相关知识,如果读者对于离散对数这一块非常熟悉的话,可以跳过这一部分,本文只是简单介绍了一下离散对数的相关概念,对于深入的了解可以自行查阅相关书籍(我个人理解也不是非常的透彻,如有描述错误的地方还请读者海涵)。

数学基础-离散对数


IX`}SLXL~BEZ`D$9YUBP~_T.jpg离散对数

本文来聊一聊有关离散对数的相关知识,接下来在讲DH的秘钥交换协议等算法之前,有必要先来说一下离散对数的相关知识,如果读者对于离散对数这一块非常熟悉的话,可以跳过这一部分,本文只是简单介绍了一下离散对数的相关概念,对于深入的了解可以自行查阅相关书籍(我个人理解也不是非常的透彻,如有描述错误的地方还请读者海涵)。


原根

根据欧拉定理,对于任意的互素的两个数字a和n, 有:

image.png

那么,根据欧拉定理可知,至少有一个数使得下面的式子成立:

image.png

我们把使得上式成立的最小的整数m称之为的阶,举一个例子,来看一下G(7)的模运算表。







1 1 1 1 1 1
2 4 1 2 4 1
3 2 6 4 5 1
4 2 1 4 2 1
5 4 6 2 3 1
6 1 6 1 6 1

我们可以发现,这个模运算实际上是呈现周期性的,比如上表当中的第二行,可以看到一旦出现1之后,后面就会呈现周期形式的运算。更一般的,如果一个数的阶是, 那么我们称这个数为n的「原根(primitive root)」, 可以发现如果a是n的本原根,那么通过a做幂运算可以得到G(n)的一个置换,也就是说a是G(n)的生成元。通过上表可以看出,对于7的原根有3和5,事实上,只有2, 3, , 有本原根,其中p是大于2的素数,a是正整数。


模对数运算

对于正实数来说,相信读者应该学过对数函数这个运算,它实际上是指数函数的逆函数,我们从上面可以发现,如果a是n的一个本原根,那么通过指数运算即可生成一个群,因此同样的可以定义模幂运算的逆函数,下面先来回顾一下中学学过的对数的有关性质:

image.png

对于任意素数p(这里只考虑素数, 虽然对于对数运算非素数也可以,但是在密码学当中用到的都是素数)的原根a, a的从1到p-1次幂可以产生从1到p-1的一个置换,因此对于任意整数b, b满足:

image.png

因此对于任意整数b和素数p的原根a, 可以找到唯一的i使得

image.png

这里,我们称i为以a为底的b的离散对数, 记做,和普通实数上面的对数运算类似,离散对数也有如下的性质:

image.png

离散对数的计算

考虑方程, 我们可以很容易的通过给定的x计算得到y, 但是反过来,如果给定y去计算x是困难的,这个和RSA当中的大整数分解的困难性类似,通常来说计算两个数的乘积运算是非常快的,但是计算一个数的分解是困难的。想DH的密钥交换算法,elgamal算法,DSA算法等都是基于离散对数求解困难性而产生的。


如何找到原根

和素性检验一样,如何去找到一个大素数的原根依然采用的是概率算法,具体算法如下:

  • 生成一个随机的非0的整数在2~p-1之间
  • 计算, 如果等于1,重复步骤1
  • 计算, 如果等于1,重复步骤1, 否则g即为一个原根

上面这个算法只针对「安全素数」, 也就是p是素数(p-1)/2也是素数的素数, 正常来说,一个密码体系当中, 应采用安全素数做运算。


代码实现

下面是rust实现的寻找原根的算法,

pub fn find_primitive_root(p: BigUint) -> BigUint {
    let one = BigUint::from(1u8);
    let two = BigUint::from(2u8);
    if p == two {
        return one;
    }
    let p2 = (p.clone() - &one) / &two;
    loop {
        let mut rng = thread_rng();
        let g = rng.gen_biguint_range(&two, &(p.clone() - one.clone()));
        if !(g.modpow(&((&p - &one) / &two), &p) == one) {
            if !(g.modpow(&((&p - &one) / &p2), &p) == one) {
                return g;
            }
        }
    }
}


相关文章
|
Web App开发 Rust 应用服务中间件
在Nginx当中支持QUIC协议
Quick UDP Internet Connection(QUIC)协议是Google公司提出的基于UDP的高效可靠协议。有关协议的主要内容就不在本文过多描述了,本文主要是来讲一下,在Nginx当中如何去支持QUIC协议。 由于个人水平有限,如果哪里写的不对的地方,还请各位大佬们指正。
2675 0
在Nginx当中支持QUIC协议
|
Rust 算法 安全
【密码学】一文读懂HMAC
本文将来聊一聊基于哈希函数的消息认证码,在此之前,先来科普一下什么是 「消息认证码」 (MAC), 先来看一个简单的栗子
2516 0
【密码学】一文读懂HMAC
|
2月前
|
监控 Java 测试技术
JMeterPlugins-Standard-1.4.0使用步骤详解(附JMeter插件安装与监控图表配置)
JMeterPlugins-Standard-1.4.0.zip是JMeter官方推荐的标准插件包,安装后可增强监控能力:提供响应时间趋势、TPS曲线、服务器性能(CPU/内存等)实时采集等功能,助你快速定位压测瓶颈。操作简单——解压→复制jar至lib/ext→重启即可生效。(239字)
|
7月前
|
人工智能 移动开发 数据可视化
魔笔 AI Chat Builder:让 AI 对话秒变可交互界面
在 AI 应用高速发展的今天,开发者不仅要懂模型和接口,还要解决交互设计、功能集成、发布运维等“最后一公里”问题。 魔笔 AI Chat Builder 的使命,就是以 低门槛 + 高效率 帮助 开发者与非技术人员 在极短时间内构建、发布并运行专业 AI 应用,让 AI 真正快速落地业务。
魔笔 AI Chat Builder:让 AI 对话秒变可交互界面
|
缓存 Prometheus 监控
Java面试题:如何监控和优化JVM的内存使用?详细讲解内存调优的几种方法
Java面试题:如何监控和优化JVM的内存使用?详细讲解内存调优的几种方法
421 3
|
分布式计算 Hadoop Java
Hbase2.2.2在线安装配置(对应Hadoop 3.1.3)
Hbase2.2.2在线安装配置(对应Hadoop 3.1.3)
562 2
|
Linux iOS开发 MacOS
CMake调用第三方库的两种方法
这两种方法都可以用来在 CMake 中调用第三方库,选择哪种方法取决于你的具体需求和第三方库的提供情况。
1362 0
|
运维 安全 Ubuntu
`/var/log/syslog` 和 `/var/log/messages` 日志详解
`/var/log/syslog` 和 `/var/log/messages` 是Linux系统的日志文件,分别在Debian和Red Hat系发行版中记录系统事件和错误。它们包含时间戳、日志级别、PID及消息内容,由`rsyslog`等守护进程管理。常用命令如`tail`和`grep`用于查看和搜索日志。日志级别从低到高包括`debug`到`emerg`,表示不同严重程度的信息。注意保护日志文件的安全,防止未授权访问,并定期使用`logrotate`进行文件轮转以管理磁盘空间。
5951 1
|
Rust 算法
【密码学】数学基础-素数
素数,之前在rsa算法当中简单提到过,但是对于素数是如何产生的,如何判断一个大整数是不是素数并没有进行展开,素数作为密码学当中比较重要的一个元素,本文来梳理一下素数的有关知识。
【密码学】数学基础-素数
|
算法 数据安全/隐私保护
【密码学】数学基础之有限域
本文填一个之前留下的坑, 在将AES算法的时候, 里面用到了GF(256)的一个有限域, 那一篇文章中, 我并没有对相关运算进行展开描述, 本文将聊一聊有限域相关的知识。 由于个人水平有限, 如果那里说的不对的地方, 还请各位读者指出。
2277 0
【密码学】数学基础之有限域