• 离散对数问题(DLP) && Diffie-Hellman问题(DHP)


    离散对数问题

    基于 Z p ∗ Z^*_p Zp的离散对数问题(DLP)

      给定一个阶为 p − 1 p-1 p1 的有限循环群 Z p ∗ Z^*_p Zp,一个本原元 α ∈ Z p ∗ α \in Z^*_p αZp和另一个元素 β ∈ Z p ∗ {\beta} \in Z^*_p βZp。DLP是确定满足以下条件的整数 x x x(其中 1 ≤ x ≤ p − 1 1≤x≤p-1 1xp1)的问题: α x = β m o d p α^x ={\beta}mod p αx=βmodp


      有群 Z p ∗ Z^*_p Zp的性质可知这样的整数 x x x肯定存在,因为 α α α是一个本原元,而每个群元素可以表示为任何本原元的幂值。这个整数 x x x也称为以 α α α为基的 β β β的离散对数,可以正式地写作: x = log ⁡ α β m o d p x = {\log}_{\alpha}{\beta} mod p x=logαβmodp
      如果参数足够大的话,计算离散对数模一个素数是一个非常难的问题。因为指数运算 α x = β m o d p α^x ={\beta}mod p αx=βmodp计算起来非常简单,这也形成了一个单向函数。


    示例1:考虑群 Z 47 ∗ Z^*_{47} Z47内的离散对数,其中本原元为 α = 5 α =5 α=5。对 β = 41 β=41 β=41的离散对数问题为:找到满足下面条件的正整数 x x x: 5 x = 41 m o d 47. 5^x = 41 mod 47. 5x=41mod47.  即使使用这么小的数字,确定 x x x也不是很容易。使用蛮力攻击,即系统地尝试所有可能的 x x x值,可得到解 x = 15 x= 15 x=15


    在这里插入图片描述


      在实际中,为了防止 Pohlig-Hellman攻击,群内DLP的基数最好是素数。由于群 Z p ∗ Z^*_p Zp(p为素数)的基为 p − 1 p-1 p1,而这个数显然不是素数,所以人们常会选择 Z p ∗ Z^*_p Zp子群中基为素数的子群内的 DLP,而非直接使用群 Z p ∗ Z^*_p Zp本身。下面将用示例2进行说明。

    示例2:群 Z 47 ∗ Z^*_{47} Z47阶为46,因此, Z 47 ∗ Z^*_{47} Z47中的子群对应的基有23、2和1。 α = 2 α = 2 α=2是拥有23个元素的子群的一个元素,因为23是一个素数,而 α α α是子群内的本原元。 β = 36 β=36 β=36(也在子群中)对应的一个可能的离散对数问题为:找到一个正整数 x ( 1 ≤ x ≤ 23 ) x(1≤x≤23 ) x(1x23),使得 2 x = 36 m o d 47. 2^x = 36 mod 47. 2x=36mod47.  利用蛮力攻击可以找到解 x = 17 x= 17 x=17


    在这里插入图片描述

    针对示例1、2中的暴力破解程序

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    /**
     * @Author Mr.Lu
     * @Date 2022/7/27 19:22
     * @ClassName DLPTest
     * @Version 1.0
     */
    public class DLPTest {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入群Z_n中的n: ");
            int Z_n = sc.nextInt();
            System.out.println("请输入群Z_n中的一个逆元(本原元): ");
            int a = sc.nextInt();
            System.out.println("请输入群Z_n中的一个元素: ");
            int b = sc.nextInt();
            int[]  nums = findNums(Z_n);
            int res = findX(nums, a, b, Z_n);
            System.out.println("利用蛮力攻击找到的解为:" + res);
        }
    
        /**
         * 针对离散对数问题进行暴力破解,查找符合条件的x
         * @param nums
         * @param a
         * @param b
         * @param Z
         * @return
         */
        private static int findX(int[] nums, int a, int b, int Z) {
            for (int i = 0; i < nums.length; i++) {
                if(((Math.pow(a, i) - b) % Z) == 0){
                    return i;
                }
            }
            return -1; // 不存在,返回-1作为结束的标志
        }
    
        /**
         * 求群Z内的元素
         * @param Z
         * @return
         */
        private static int[] findNums(int Z) {
            List<Integer> list = new ArrayList<>();
            for(int i = 1; i < Z; i++){
                if(gcd(i, Z) == 1){
                    list.add(i);
                }
            }
    
            int[] nums = new int[list.size()];
            for (int i = 0; i < list.size(); i++) {
                nums[i] = list.get(i);
            }
            return nums;
        }
    
        /**
         * 求两个数的最大公约数
         * @param num
         * @param Z
         * @return
         */
        private static int gcd(int num, int Z) {
          if(num == 1) return 1;
    
          int temp = num;
          num = Z % num;
          Z = temp;
    
          return gcd(num, Z);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    推广的离散对数问题
      DLP在密码学中有一个重要特征:它并没有限制在乘法群 Z p ∗ Z^*_{p} Zp(p是一个素数)内,而是可以定义在任何循环群中。这也称为推广的离散对数(GDLP)问题,可以描述为:

      给定一个基为 n n n的有限循环群 G G G,群操作为 o o o。考虑一个本原元 α ∈ G \alpha \in G αG和另一个元素 β ∈ G \beta \in G βG,则离散对数问题为:找到在 1 ≤ x ≤ n 1≤ x ≤ n 1xn内的整数 x x x,满足: β = α o α o . . . o α ⏟ x 次 = α x \beta = \underbrace{{\alpha} o {\alpha} o ...o {\alpha}}_{x次} = {\alpha}^x β=x αoαo...oα=αx

      与 Z p ∗ Z^*_{p} Zp内DLP的情况一样,这样的整数 x x x一定存在,因为 α α α是一个本原元,因此群 G G G内的每个元素都可以通过 α α α上重复使用群操作得到。

    注意:有些循环群中的DLP并不是很困难的。这样的群就不能用于公钥密码体制,因为这样的群内的DLP并不是一个单向函数。例如下面的示例:

    示例:将考虑整数模素数的加法群。例如,如果选择的素数为 p = 11 , G = ( Z 11 , + ) p = 11,G = (Z_{11}, +) p=11G=(Z11,+)是本原元为 α = 2 α =2 α=2的一个有限循环群。 α α α生成该群的过程如下:
    在这里插入图片描述  现在求解元素 β = 3 β=3 β=3的 DLP,即必须计算整数 1 ≤ x ≤ 11 1 ≤ x ≤ 11 1x11中,满足以下条件的 x x x: x ∗ 2 =   2 + 2 + . . . + 2 ⏟ x 次 ≡ 3 m o d 11 x*2 = \ \underbrace{2 + 2 + ... + 2}_{x次} \equiv 3 mod 11 x2= x 2+2+...+23mod11  针对此DLP 的攻击方式。尽管群操作为加法,但是 α \alpha α, β \beta β以及离散对数 x x x之间的关系可以用乘法来表示: x ∗ 2 ≡ 3 m o d 11 x*2 \equiv 3 mod 11 x23mod11  可以将本原元 α = 2 α=2 α=2求逆来求解 x x x的值: x ≡ 2 − 1 ∗ 3 m o d 11 x \equiv 2^{-1}*3 mod 11 x213mod11  根据根据扩展的欧几里得算法可知 2 − 1 ≡ 6 m o d 11 2^{-1}\equiv 6 mod 11 216mod11, 那么离散对数为: x ≡ 2 − 1 ∗ 3 ≡ 7 m o d 11 x \equiv 2^{-1}*3 \equiv 7mod 11 x2137mod11
      这个离散对数可以从上面给出的小表中验证。
      上面的技巧可以推广到 n n n为任意值,且元素 α , β ∈ Z n \alpha, \beta \in Z_n α,βZn的任何群 ( Z n , + ) (Z_n,+) (Zn,+)中。可以得到这样一个结论: 在 Z n Z_n Zn上计算推广的DLP会非常简单。这里能非常容易求解 DLP的原因在于,其中有些数学操作都不在加法群里,即乘法和逆元。

    Diffie-Hellman密钥交换的安全性

      我们可以注意到使用基本 DHKE 的协议在主动攻击(攻击者可以修改消息或者生成消息)面前并不是安全的。这意味着如果攻击者Oscar可以修改消息或生成假消息,则Oscar就可以破解这个协议。这称为中间人攻击
      目前我们只考虑消极攻击者的可能性**,即 Oscar只能监听消息但不能篡改消息**。Oscar的目的就是计算Alice与Bob之间共享的会话密钥 k A B k_{AB} kAB。通过观察协议Oscar可以获得什么信息?下面分析一下:

    1. Oscar知道 α α α p p p,因为这两个参数在握手协议阶段是公开参数。
    2. Oscar可以在密钥交换协议的执行阶段窃听信道,获得值 A = k p u b , A A = k_{pub, A} A=kpub,A B = k p u b , B B = k_{pub, B} B=kpub,B

      问题提出:Oscar能否从 α , p , A ≡ α a m o d p α, p ,A \equiv {\alpha}^a mod p α,p,Aαamodp B ≡ α b m o d p B \equiv {\alpha}^b mod p Bαbmodp中计算出 k = α k= α k=α。这个问题也称为Diffie-Hellman问题(DHP)。与离散对数问题一样,Diffie-Hellman问题也可推广到任意的有限循环群。

      下面是DHP的正式描述:

      给定一个阶为 n n n的有限循环群 G G G,一个本原元 α ∈ G α \in G αG及两个 G 内的元素 A = α a A = {\alpha}^a A=αa B = α b B = {\alpha}^b B=αb。Diffie-Hellman问题就是找到群元素 α a b {\alpha}^{ab} αab

      求解 Diffie-Hellman 问题的一个通用方法如下。为了便于理解我们以乘法群 Z p ∗ Z^*_p Zp 内的 DHP 作为例子。假设 Oscar 知道计算 Z p ∗ Z^*_p Zp 内离散对数的有效方法——当然,这是一个“很大”的假设。然后,Oscar就可以通过以下两步求解出 Diffie-Hellman问题,并得到密钥 k A B k_{AB} kAB:

    1. 通过求解离散对数问题: a ≡ l o g α A m o d p a \equiv log_{\alpha}Amod p alogαAmodp 计算出 Alice 的私钥 a = k p r , A a = k_{pr, A} a=kpr,A,
    2. 计算会话密钥 k A B ≡ B a m o d p 。 k_{AB} \equiv B^a mod p 。 kABBamodp

      尽管这些步骤看上去很简单,但如果p足够大,则计算离散对数问题仍然是不可行的, 即这个假设是以解决离散对数问题为前提的

      注意:我们并不知道求解DLP是否是求解DHP的唯一方法。理论上,不用计算离散对数就能求解DHP的方法也是可能的。这个情况与RSA类似———在RSA中,因式分解是否真的是破解RSA最好的方法是未知的。然而,尽管这个结论在数学书是不可证明的,但人们通常假设有效求解DLP是有效求解DHP的唯一方法(即解决DLP是解决DHP的前提)。因此,为了保证实际中DHKE的安全性,我们必须确保对应的 DLP不能被求解。而这一点是通过选择足够大的 p p p,使得 index-calculus方法不能计算 DLP而实现的。



    参考资料:

    一些代数知识(群、循环群和子群):
    https://blog.csdn.net/qq_43751200/article/details/125978990
    公钥算法的基本数论知识(欧几里得算法、扩展欧几里得算法、欧拉函数、费马小定理与欧拉定理):
    https://blog.csdn.net/qq_43751200/article/details/125460326
    《深入浅出密码学》–Christof Paar,Jan Pelzl著

  • 相关阅读:
    PAT 1097 Deduplication on a Linked List(25分)
    Django日志配置
    计算机视觉与深度学习-经典网络解析-AlexNet&ZFNet&VGG&GoogLeNet&ResNet[北邮鲁鹏]
    互联网摸鱼日报(2023-10-15)
    设计模式——行为型——责任链模式Chain Of Responsibility
    WebDAV之葫芦儿·派盘+墨阅
    Unity 之 安卓堆栈跟踪和日志工具 (Android Logcat | 符号表解析Bugly捕获)
    配置 iSCSI 服务并实现客户端自动挂载块设备
    【论文翻译】LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS
    BJT晶体管
  • 原文地址:https://blog.csdn.net/qq_43751200/article/details/126024931