【问题标题】:DSA (Digital Signature Alghoritm) implementation - key generationDSA(数字签名算法)实现 - 密钥生成
【发布时间】:2019-05-15 18:25:23
【问题描述】:

我必须为大学实施 DSA,但我无法找到数字 q,它是 p - 1 的素数,其中 p 是素数。我试图编写一些奇怪的循环,但它只适用于小的 p 值。我猜使用 512 位长的素数需要很长时间。 我使用 Java 和 BigInteger 库来实现。

编辑:

   public BigInteger[] generatePAndQ(){

    BigInteger q = BigInteger.probablePrime(160, new Random());
    BigInteger k = BigInteger.valueOf(2); // k = 2

    BigInteger probablyPrime = q.multiply(k).add(BigInteger.ONE); // probablyPrime = q * k + 1
    while(!isPrime(probablyPrime)){
        q = BigInteger.probablePrime(160, new Random());
        probablyPrime = q.multiply(k).add(BigInteger.ONE);
    }

    BigInteger[] qAndP = new BigInteger[2];
    qAndP[0] = q;
    qAndP[1] = probablyPrime;

    return  qAndP;
}

【问题讨论】:

  • 一种方法是从 q 开始。首先找到一个大小合适的素数 q,然后检查值 p = 2*q + 1 是否为素数。我相信预期的运行时间是 O(log^2 p)。如果你需要调试帮助,你真的需要展示你的代码。
  • 我编辑了帖子。 @JamesKPolk 你提到过这样的事情吗?
  • 嗯,它可以工作,但仍然很慢。对于 30 位 q 它搜索大约 5 分钟,我遇到了 160 位 1
  • 不要在循环内创建新的 Random 实例。而是在循环外部创建单个 SecureRandom 实例,并将该单个实例用于所有随机数。

标签: java cryptography dsa


【解决方案1】:

我不确定你在做什么,但这段代码说明了我的 cmets。它通常在我的笔记本电脑上运行不到 0.5 秒。

import java.math.BigInteger;
import java.security.SecureRandom;

public class Main {

    public static BigInteger[] generatePAndQ() {
        SecureRandom random = new SecureRandom();

        final int pSizeInBits = 512;
        final int qSizeInBits = 160;
        BigInteger q = BigInteger.probablePrime(qSizeInBits, random);
        BigInteger k = BigInteger.ONE.shiftLeft(pSizeInBits - qSizeInBits); // k = 2**(pSizeInBits - qSizeInBits);

        BigInteger probablyPrime = q.multiply(k).add(BigInteger.ONE); // probablyPrime = q * k + 1
        while (!probablyPrime.isProbablePrime(50)) {
            q = BigInteger.probablePrime(qSizeInBits, random);
            probablyPrime = q.multiply(k).add(BigInteger.ONE);
        }

        BigInteger[] qAndP = new BigInteger[2];
        qAndP[0] = q;
        qAndP[1] = probablyPrime;

        return qAndP;
    }

    public static void main(String[] args) {
        long start = System.nanoTime();
        final BigInteger[] pAndQ = generatePAndQ();
        double elapsed = (System.nanoTime() - start) / 1e9;
        System.out.printf("q=%d%np=%d%nTime: %f (seconds)%n", pAndQ[0], pAndQ[1], elapsed);
    }
}

q、p 和 k 的边界既快又脏,应该清理干净。

【讨论】:

  • 天哪,我知道它为什么这么慢了......这是因为函数'isPrime(probablyPrime)'......无论如何,非常感谢。我一直在寻找如何计算 q 和 p 两天。再次感谢您的帮助!
猜你喜欢
  • 2011-11-24
  • 2013-12-02
  • 2022-01-20
  • 2017-05-16
  • 1970-01-01
  • 2019-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多