【问题标题】:Rabin-Miller in JavaJava中的拉宾-米勒
【发布时间】:2018-03-09 19:37:30
【问题描述】:

我得到了一个使用 BigInteger 类的函数 RSA 程序。 但是我使用内置函数生成了我的素数。相反,我要求通过 Rabin-Miller 测试生成两个素数 p 和 q

rabin-miller 将单独运行,我将生成两个素数,然后将它们作为静态数字输入到我的 RSA 程序中,因此它们将是 2 个独立的程序。

rabin-miller on wikipedia的伪代码:

import java.math.BigInteger;
import java.util.Random;

public class MillerRabin {

    private static final BigInteger ZERO = BigInteger.ZERO;
    private static final BigInteger ONE = BigInteger.ONE;
    private static final BigInteger TWO = new BigInteger("2");
    private static final BigInteger THREE = new BigInteger("3");

    public static boolean isProbablePrime(BigInteger n, int k) {
        if (n.compareTo(ONE) == 0)
            return false;
        if (n.compareTo(THREE) < 0)
            return true;
        int s = 0;
        BigInteger d = n.subtract(ONE);
        while (d.mod(TWO).equals(ZERO)) {
            s++;
            d = d.divide(TWO);
        }
        for (int i = 0; i < k; i++) {
            BigInteger a = uniformRandom(TWO, n.subtract(ONE));
            BigInteger x = a.modPow(d, n);
            if (x.equals(ONE) || x.equals(n.subtract(ONE)))
                continue;
            int r = 0;
            for (; r < s; r++) {
                x = x.modPow(TWO, n);
                if (x.equals(ONE))
                    return false;
                if (x.equals(n.subtract(ONE)))
                    break;
            }
            if (r == s) // None of the steps made x equal n-1.
                return false;
        }
        return true;
    }

    private static BigInteger uniformRandom(BigInteger bottom, BigInteger top) {
        Random rnd = new Random();
        BigInteger res;
        do {
            res = new BigInteger(top.bitLength(), rnd);
        } while (res.compareTo(bottom) < 0 || res.compareTo(top) > 0);
        return res;
    }

    public static void main(String[] args) {
        // run with -ea to enable assertions
        String[] primes = {"1", "3", "3613", "7297",
                "226673591177742970257407", "2932031007403"};
        String[] nonPrimes = {"3341", "2932021007403",
                "226673591177742970257405"};
        int k = 40;
        for (String p : primes)
            assert isProbablePrime(new BigInteger(p), k);
        for (String n : nonPrimes)
            assert !isProbablePrime(new BigInteger(n), k);


    }
}

现在我的问题:

除此之外,我将不得不从 x 个位长中生成 x 个素数。 所以可以说:从 512 位中生成 2 个素数。知道如何做到这一点吗?

我还应该生成 20 个随机 a。

我想我不需要程序的结尾或顶部底部的代码 只是代表 rabin-miller 的数学运算,然后以某种方式从 X 位长度中产生素数

我该怎么做?

【问题讨论】:

  • 我不明白你有什么困惑。你想要一个 512 位素数,所以选择随机的 512 位整数并用 Rabin-Miller 测试它们。
  • 是的,但是怎么做?首先,我不需要 uniformRandom 来让这段代码工作吗?我可以把数学放在主要方法中吗?我刚开始使用 BigInteger 类,以前从未见过。

标签: java encryption rsa


【解决方案1】:

好的,所以你想要一个在2 ^ 5112 ^ 512 - 1 范围内的大整数。这样您就可以确保将初始位设置为 1,使其成为 512 位随机数。可能有点奇怪,但一个 512 位的随机数只包含 511 个随机位;显然第一位不能为零,因为在这种情况下,数字的大小不是 512 位。

因此,您需要在02 ^ 511 - 1 之间生成一个数字,然后将2 ^ 511 添加到其中。当然你想使用SecureRandom 来生成安全密钥:

public static void main(String[] args) throws Exception {
    int bitsize = 512;
    SecureRandom rng = new SecureRandom();
    for (int i = 0; i < 1000; i++) {
        BigInteger randomForBitSize = createRandomForBitSize(bitsize, rng);
        System.out.printf("%d : %X%n", randomForBitSize.bitLength(), randomForBitSize);
    }
}

private static BigInteger createRandomForBitSize(int bitsize, Random rng) {
    BigInteger randomFromZero = new BigInteger(bitsize - 1, rng);
    BigInteger lowestNumberBitSize = BigInteger.valueOf(2).pow(bitsize - 1);
    BigInteger randomBitSize = lowestNumberBitSize.add(randomFromZero);
    return randomBitSize;
}

【讨论】:

  • 使用 64 字节的字节数组可能会更快,用随机位填充它,然后使用 OR 将(第一个字节的)最高有效位设置为 1:| 0x80,然后使用new BigInteger(1, byteArray) 创建整数。
  • 这样计算 2^n 也更快:BigInteger.ONE.shiftLeft(n)
  • @Henry 百万次运行确实显示出不同:pow 函数需要 137 毫秒,而优化的、可读性较差的移位操作需要 113 毫秒(总共百万次运行!)。就我个人而言,我并不在乎这些差异,但对可读性却有很多。尤其是如果您考虑到随机数生成无论如何都会慢得多这一事实;这就是我试图优化它的原因。
  • 我检查了BigInteger.pow() 的源代码,基数中的 2 的幂是特殊情况下使用左移!
  • @JamesKPolk 这并不奇怪,不是吗?让我不得不记住少一个黑客。与生成随机位相同,检查请求的最大值是否恰好是 2^n,因为那时您只需要生成位并将结果用作数字。无需拒绝抽样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
  • 2014-07-28
  • 2011-12-02
  • 2018-11-05
  • 2017-04-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多