简体   繁体   English

查找主要对象需要很长时间JAVA

[英]Finding primary takes long time JAVA

I don't know if I am using this code properly -> main. 我不知道我是否在正确使用此代码-> main。 It is extremely slow. 它非常慢。 It is DDS algorithm. 这是DDS算法。 It is implementation of DSA: http://en.wikipedia.org/wiki/Digital_Signature_Algorithm 它是DSA的实现: http//en.wikipedia.org/wiki/Digital_Signature_Algorithm

THIS LOOP TAKES MUCH TIME 此循环耗时

do {
            pTemp = new BigInteger(l, primeCenterie, rand);
            pTemp2 = pTemp.subtract(BigInteger.ONE);
            pTemp = pTemp.subtract(pTemp2.remainder(q));
            System.out.println("1 " + i++);
        } while (!pTemp.isProbablePrime(primeCenterie)
                || pTemp.bitLength() != l);

I added some printlns and even them are slow. 我添加了一些printlns,甚至它们都很慢。

 import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Key {
    int primeCenterie = 20;
    BigInteger q;
    BigInteger p;
    BigInteger g;
    BigInteger y;
    BigInteger x;
    BigInteger k;
    Random rand = new Random();

    Key() {
    }

    public void generateKey() {
        q = new BigInteger(160, primeCenterie, rand);
        p = generateP(q, 512);
        g = generateG(p, q);
        do {
            x = new BigInteger(q.bitCount(), rand);
        } while (x.compareTo(BigInteger.ZERO) != 1 && x.compareTo(q) != -1);
        y = g.modPow(x, p);
    }

    private BigInteger generateP(BigInteger q, int l) {
        if (l % 64 != 0) {
            throw new IllegalArgumentException("L value is wrong");
        }
        BigInteger pTemp;
        BigInteger pTemp2;
        int i = 0;
        do {
            pTemp = new BigInteger(l, primeCenterie, rand);
            pTemp2 = pTemp.subtract(BigInteger.ONE);
            pTemp = pTemp.subtract(pTemp2.remainder(q));
            System.out.println("1 " + i++);
        } while (!pTemp.isProbablePrime(primeCenterie)
                || pTemp.bitLength() != l);
        return pTemp;
    }

    private BigInteger generateG(BigInteger p, BigInteger q) {
        BigInteger aux = p.subtract(BigInteger.ONE);
        BigInteger pow = aux.divide(q);
        BigInteger gTemp;
        int i = 0;
        do {
            gTemp = new BigInteger(aux.bitLength(), rand);
            System.out.println("2 " + i++);
        } while (gTemp.compareTo(aux) != -1
                && gTemp.compareTo(BigInteger.ONE) != 1);
        return gTemp.modPow(pow, p);
    }

    public BigInteger generateK(BigInteger q) {
        BigInteger tempK;
        int i = 0;
        do {
            tempK = new BigInteger(q.bitLength(), rand);
            System.out.println("3 " + i++);
        } while (tempK.compareTo(q) != -1
                && tempK.compareTo(BigInteger.ZERO) != 1);
        return tempK;
    }

    public BigInteger generateR() {
        k = generateK(q);
        BigInteger r = g.modPow(k, p).mod(q);
        return r;
    }

    public BigInteger generateS(BigInteger r, byte[] data) {
        MessageDigest md;
        BigInteger s = BigInteger.ONE;
        try {
            md = MessageDigest.getInstance("SHA-1");
            md.update(data);
            BigInteger hash = new BigInteger(md.digest());
            s = (k.modInverse(q).multiply(hash.add(x.multiply(r)))).mod(q);
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(DSA.class.getName()).log(Level.SEVERE, null, ex);
        }
        return s;
    }

    boolean verify(byte[] data, BigInteger r, BigInteger s) {
        if (r.compareTo(BigInteger.ZERO) <= 0 || r.compareTo(q) >= 0) {
            return false;
        }
        if (s.compareTo(BigInteger.ZERO) <= 0 || s.compareTo(q) >= 0) {
            return false;
        }
        MessageDigest md;
        BigInteger v = BigInteger.ZERO;
        try {
            md = MessageDigest.getInstance("SHA-1");
            md.update(data);
            BigInteger hash = new BigInteger(md.digest());
            BigInteger w = s.modInverse(q);
            BigInteger u1 = hash.multiply(w).mod(q);
            BigInteger u2 = r.multiply(w).mod(q);
            v = ((g.modPow(u1, p).multiply(y.modPow(u2, p))).mod(p)).mod(q);
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(DSA.class.getName()).log(Level.SEVERE, null, ex);
        }
        return v.compareTo(r) == 0;
    }

    public static void main(String[] args) {
        Key key = new Key();
        key.generateKey();
        byte[] data = "a".getBytes();
        BigInteger r = key.generateR();
        BigInteger s = key.generateS(r, data);
        System.out.println(key.verify(data,r,s)); 
    }

}

A profiler would be best here, but I think your problem is isProbablePrime. 此处最好使用探查器,但我认为您的问题是isProbablePrime。 You're passing in 20, which basically means you want a .9999999 certainty. 您要传递20,这基本上意味着您想要.9999999的确定性。 Try a smaller parameter or use other method for primality testing... 尝试使用较小的参数或使用其他方法进行素数测试...

isProbablePrime

public boolean isProbablePrime(int certainty)

    Returns true if this BigInteger is probably prime, false if it's definitely composite. If certainty is <= 0, true is returned.

    Parameters:
        certainty - a measure of the uncertainty that the caller is willing to tolerate: if the call returns true the probability that this BigInteger is prime exceeds (1 - 1/2certainty). The execution time of this method is proportional to the value of this parameter. 
    Returns:
        true if this BigInteger is probably prime, false if it's definitely composite.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM