java中大素數生成算法

目前的公開密鑰 算法大部分基於大整數分解、有限域上的離散對數問題和橢 圓曲線上的離散對數問題,這些數學難題的構建大部分都需 要生成一種超大的素數,尤其在經典的RSA算法中,生成的素數的質量對系統的安全性有很大的影響。

1.原理

費馬小定理:假如p是質數,且gcd(a,p)=1,那麼 a^(p-1)≡1(mod p)。即:假如a是整數,p是質數,且a,p互質(即兩者只有一個公約數1),那麼a的(p-1)次方除以p的餘數恆等於1。
基於此可以快速判斷一個大整數是否爲素數。

Miller-Rabin算法:Fermat算法的一個變形改進。
在這裏插入圖片描述

2. BigInteger中的API

public static BigInteger probablePrime(int bitLength, Random rnd)

結果是素數的概率爲1-2^(-100),貌似內部使用了Miller-Rabin算法。
先不論這個概率問題,生成100個2048位的素數耗時141475ms
調用DHCryptUtils.randomPrime(2048)10次的時間已經達到了143614ms。
再來看這個概率問題,1-2^(-100)已經很接近於1。
如果還想提高這個概率,可以調用

public boolean isProbablePrime(int certainty)

certainty表示判斷的準確率爲1-2^(-certainty)

            Random r = new Random();
            BigInteger bigInteger = BigInteger.probablePrime(2048, r);
            while(!bigInteger.isProbablePrime(256)){
                bigInteger = BigInteger.probablePrime(2048, r);
            }

3. DH的KeyPairGenerator如何生成P和Q

一步一步進斷點之後,發現了DSAParameterGenerator中的方法generatePandQ
certainty的取值和生成素數的長度有關係

       byte var11 = -1;
        if (var1 <= 1024) {
            var11 = 80;
        } else if (var1 == 2048) {
            var11 = 112;
        }

我這裏需要的2048位,因此certainty爲112。

內部生成素數的方法:

            BigInteger var14 = null;

            while(true) {
                BigInteger var13;
                BigInteger var16;
                do {
                    var0.nextBytes(var9);
                    var14 = new BigInteger(1, var9);
                    var16 = (new BigInteger(1, var5.digest(var9))).mod(TWO.pow(var2 - 1));
                    var13 = TWO.pow(var2 - 1).add(var16).add(ONE).subtract(var16.mod(TWO));
                } while(!var13.isProbablePrime(var11));

                var16 = ONE;

                for(int var15 = 0; var15 < 4 * var1; ++var15) {
                    BigInteger[] var17 = new BigInteger[var7 + 1];

                    BigInteger var19;
                    BigInteger var20;
                    for(int var18 = 0; var18 <= var7; ++var18) {
                        var19 = BigInteger.valueOf((long)var18);
                        var20 = var14.add(var16).add(var19).mod(var10);
                        byte[] var21 = var5.digest(toByteArray(var20));
                        var17[var18] = new BigInteger(1, var21);
                    }

                    BigInteger var24 = var17[0];

                    for(int var25 = 1; var25 < var7; ++var25) {
                        var24 = var24.add(var17[var25].multiply(TWO.pow(var25 * var6)));
                    }

                    var24 = var24.add(var17[var7].mod(TWO.pow(var8)).multiply(TWO.pow(var7 * var6)));
                    var19 = TWO.pow(var1 - 1);
                    var20 = var24.add(var19);
                    BigInteger var26 = var20.mod(var13.multiply(TWO));
                    BigInteger var12 = var20.subtract(var26.subtract(ONE));
                    if (var12.compareTo(var19) > -1 && var12.isProbablePrime(var11)) {
                        BigInteger[] var22 = new BigInteger[]{var12, var13, var14, BigInteger.valueOf((long)var15)};
                        return var22;
                    }

                    var16 = var16.add(BigInteger.valueOf((long)var7)).add(ONE);
                }
            }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章