blob: 51e30028b132bdb2904e6f8a76b11fb16fd02e54 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/**
25 * @test
26 * @bug 6330287 6331386
27 * @summary verify that DHKeyPairGenerator returns keys of the expected size
28 * (modulus and exponent)
29 * -and-
30 * DHKeyPairGenerator is using BigInteger.setBit
31 * @author Andreas Sterbenz
32 */
33
34import java.math.BigInteger;
35import java.util.Arrays;
36
37import java.security.*;
38import javax.crypto.*;
39import javax.crypto.interfaces.*;
40import javax.crypto.spec.*;
41
42/*
43 * NOTE: BigInteger's bitlength() doesn't report leading zeros, only
44 * the number of bits needed to actually represent the number. i.e.
45 *
46 * new BigInteger("4").bitLength() = 3
47 *
48 * Since the private key x can vary 1 <= x <= p-2, we can't do any
49 * bitlength-based calculations here. But we can check that p conforms
50 * as expected.
51 *
52 * If not specified, we're currently using an lsize of Math.max(384, psize/2).
53 */
54public class TestExponentSize {
55
56 /*
57 * Sizes and values for various lengths.
58 */
59 private enum Sizes {
60 two56(256), three84(384), five12(512), seven68(768), ten24(1024);
61
62 private final int intSize;
63 private final BigInteger bigIntValue;
64
65 Sizes(int size) {
66 intSize = size;
67 byte [] bits = new byte[intSize/8];
68 Arrays.fill(bits, (byte)0xff);
69 bigIntValue = new BigInteger(1, bits);
70 }
71
72 int getIntSize() {
73 return intSize;
74 }
75
76 BigInteger getBigIntValue() {
77 return bigIntValue;
78 }
79 }
80
81 public static void main(String[] args) throws Exception {
82 KeyPair kp;
83 KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", "SunJCE");
84
85 // Sun's default uses a default psize of 1024/lsize of 512
86 kp = kpg.generateKeyPair();
87 checkKeyPair(kp, Sizes.ten24, Sizes.five12);
88
89 DHPublicKey publicKey = (DHPublicKey)kp.getPublic();
90 BigInteger p = publicKey.getParams().getP();
91 BigInteger g = publicKey.getParams().getG();
92
93 kpg.initialize(Sizes.ten24.getIntSize());
94 kp = kpg.generateKeyPair();
95 checkKeyPair(kp, Sizes.ten24, Sizes.five12);
96
97 kpg.initialize(new DHParameterSpec(p, g, Sizes.ten24.getIntSize()));
98 kp = kpg.generateKeyPair();
99 checkKeyPair(kp, Sizes.ten24, Sizes.ten24);
100
101 kpg.initialize(new DHParameterSpec(p, g, Sizes.five12.getIntSize()));
102 kp = kpg.generateKeyPair();
103 checkKeyPair(kp, Sizes.ten24, Sizes.five12);
104
105 kpg.initialize(new DHParameterSpec(p, g, Sizes.two56.getIntSize()));
106 kp = kpg.generateKeyPair();
107 checkKeyPair(kp, Sizes.ten24, Sizes.two56);
108
109 kpg.initialize(Sizes.five12.getIntSize());
110 kp = kpg.generateKeyPair();
111 checkKeyPair(kp, Sizes.five12, Sizes.three84);
112
113 kpg.initialize(Sizes.seven68.getIntSize());
114 kp = kpg.generateKeyPair();
115 checkKeyPair(kp, Sizes.seven68, Sizes.three84);
116
117 System.out.println("OK");
118 }
119
120 private static void checkKeyPair(KeyPair kp, Sizes modulusSize,
121 Sizes exponentSize) throws Exception {
122
123 System.out.println("Checking (" + modulusSize + ", " +
124 exponentSize + ")");
125 DHPrivateKey privateKey = (DHPrivateKey)kp.getPrivate();
126 BigInteger p = privateKey.getParams().getP();
127 BigInteger x = privateKey.getX();
128
129 if (p.bitLength() != modulusSize.getIntSize()) {
130 throw new Exception("Invalid modulus size: " + p.bitLength());
131 }
132
133 if (x.bitLength() > exponentSize.getIntSize()) {
134 throw new Exception("X has more bits than expected: " +
135 x.bitLength());
136 }
137
138 BigInteger pMinus2 =
139 p.subtract(BigInteger.ONE).subtract(BigInteger.ONE);
140
141 if ((x.compareTo(BigInteger.ONE) < 0 ||
142 (x.compareTo(pMinus2)) > 0)) {
143 throw new Exception(
144 "X outside range 1<=x<p-2: x: " + x + " p: " + p);
145 }
146 }
147}