-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDiscreteLogarithm.java
More file actions
61 lines (54 loc) · 2.21 KB
/
DiscreteLogarithm.java
File metadata and controls
61 lines (54 loc) · 2.21 KB
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
package nth.api.cryptography.twofish;
import java.math.BigInteger;
import java.util.Random;
/**
* @author Hau Trung Nguyen
*/
public class DiscreteLogarithm {
private static final Random R = new Random();
public static final int BIT_LENGTH = 128;
public static BigInteger[] getPQGYX() {
BigInteger q = BigInteger.probablePrime(BIT_LENGTH, R);
final BigInteger multiply = q.multiply(new BigInteger(256 - BIT_LENGTH, R));
BigInteger p = multiply.add(BigInteger.ONE);
do {
p = p.add(q);
} while (!p.isProbablePrime(20) || !(p.subtract(BigInteger.ONE)).remainder(q).equals(BigInteger.ZERO));
BigInteger phi;
do {
phi = new BigInteger(p.bitLength(), R);
} while (phi.compareTo(p) >= 0);
//
assert p.subtract(BigInteger.ONE).mod(q).equals(BigInteger.ZERO);
//
BigInteger g = phi.modPow(p.subtract(BigInteger.ONE).divide(q), p);
BigInteger x;
do {
x = new BigInteger(q.bitLength(), R);
} while (x.compareTo(q.subtract(BigInteger.ONE)) > 0 || x.equals(BigInteger.ZERO) || x.equals(BigInteger.ONE));
BigInteger y = g.modPow(x, p);
return new BigInteger[]{p, q, g, y, x};
}
public static BigInteger[] sign(byte[] hash, BigInteger p, BigInteger g, BigInteger q, BigInteger x, BigInteger y) {
assert y.equals(g.modPow(x, p));
//
BigInteger h = new BigInteger(hash);
//
BigInteger k;
do {
k = new BigInteger(q.bitLength(), R);
} while (k.compareTo(q) >= 0 || k.compareTo(BigInteger.ZERO) <= 0);
final BigInteger r = g.modPow(k, p);
final BigInteger rho = r.mod(q);
final BigInteger s = k.subtract(rho.multiply(h).multiply(x)).mod(q);
return new BigInteger[]{r, s};
}
public static boolean verify(byte[] hash, BigInteger[] sign, BigInteger p, BigInteger g, BigInteger q, BigInteger y) {
BigInteger h = new BigInteger(hash);
BigInteger r = sign[0];
BigInteger s = sign[1];
BigInteger rho = r.mod(q);
final BigInteger test = g.modPow(s, p).multiply(y.modPow(rho.multiply(h), p)).mod(p);
return r.equals(test);
}
}