OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [security/] [key/] [dss/] [DSSKeyPairGenerator.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* DSSKeyPairGenerator.java --
2
   Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
3
 
4
This file is a part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or (at
9
your option) any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19
USA
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version.  */
37
 
38
 
39
package gnu.java.security.key.dss;
40
 
41
import gnu.java.security.Configuration;
42
import gnu.java.security.Registry;
43
import gnu.java.security.hash.Sha160;
44
import gnu.java.security.key.IKeyPairGenerator;
45
import gnu.java.security.util.PRNG;
46
 
47
import java.math.BigInteger;
48
import java.security.KeyPair;
49
import java.security.PrivateKey;
50
import java.security.PublicKey;
51
import java.security.SecureRandom;
52
import java.security.spec.DSAParameterSpec;
53
import java.util.Map;
54
import java.util.logging.Logger;
55
 
56
/**
57
 * A key-pair generator for asymetric keys to use in conjunction with the DSS
58
 * (Digital Signature Standard).
59
 * <p>
60
 * References:
61
 * <p>
62
 * <a href="http://www.itl.nist.gov/fipspubs/fip186.htm">Digital Signature
63
 * Standard (DSS)</a>, Federal Information Processing Standards Publication
64
 * 186. National Institute of Standards and Technology.
65
 */
66
public class DSSKeyPairGenerator
67
    implements IKeyPairGenerator
68
{
69
  private static final Logger log = Logger.getLogger(DSSKeyPairGenerator.class.getName());
70
 
71
  /** The BigInteger constant 2. */
72
  private static final BigInteger TWO = BigInteger.valueOf(2L);
73
 
74
  /** Property name of the length (Integer) of the modulus (p) of a DSS key. */
75
  public static final String MODULUS_LENGTH = "gnu.crypto.dss.L";
76
 
77
  /**
78
   * Property name of the Boolean indicating wether or not to use default pre-
79
   * computed values of <code>p</code>, <code>q</code> and <code>g</code>
80
   * for a given modulus length. The ultimate behaviour of this generator with
81
   * regard to using pre-computed parameter sets will depend on the value of
82
   * this property and of the following one {@link #STRICT_DEFAULTS}:
83
   * <ol>
84
   * <li>If this property is {@link Boolean#FALSE} then this generator will
85
   * accept being setup for generating parameters for any modulus length
86
   * provided the modulus length is between <code>512</code> and
87
   * <code>1024</code>, and is of the form <code>512 + 64 * n</code>. In
88
   * addition, a new paramter set will always be generated; i.e. no pre-
89
   * computed values are used.</li>
90
   * <li>If this property is {@link Boolean#TRUE} and the value of
91
   * {@link #STRICT_DEFAULTS} is also {@link Boolean#TRUE} then this generator
92
   * will only accept being setup for generating parameters for modulus lengths
93
   * of <code>512</code>, <code>768</code> and <code>1024</code>. Any
94
   * other value, of the modulus length, even if between <code>512</code> and
95
   * <code>1024</code>, and of the form <code>512 + 64 * n</code>, will
96
   * cause an {@link IllegalArgumentException} to be thrown. When those modulus
97
   * length (<code>512</code>, <code>768</code>, and <code>1024</code>)
98
   * are specified, the paramter set is always the same.</li>
99
   * <li>Finally, if this property is {@link Boolean#TRUE} and the value of
100
   * {@link #STRICT_DEFAULTS} is {@link Boolean#FALSE} then this generator will
101
   * behave as in point 1 above, except that it will use pre-computed values
102
   * when possible; i.e. the modulus length is one of <code>512</code>,
103
   * <code>768</code>, or <code>1024</code>.</li>
104
   * </ol>
105
   * The default value of this property is {@link Boolean#TRUE}.
106
   */
107
  public static final String USE_DEFAULTS = "gnu.crypto.dss.use.defaults";
108
 
109
  /**
110
   * Property name of the Boolean indicating wether or not to generate new
111
   * parameters, even if the modulus length <i>L</i> is not one of the pre-
112
   * computed defaults (value {@link Boolean#FALSE}), or throw an exception
113
   * (value {@link Boolean#TRUE}) -- the exception in this case is an
114
   * {@link IllegalArgumentException}. The default value for this property is
115
   * {@link Boolean#FALSE}. The ultimate behaviour of this generator will
116
   * depend on the values of this and {@link #USE_DEFAULTS} properties -- see
117
   * {@link #USE_DEFAULTS} for more information.
118
   */
119
  public static final String STRICT_DEFAULTS = "gnu.crypto.dss.strict.defaults";
120
 
121
  /**
122
   * Property name of an optional {@link SecureRandom} instance to use. The
123
   * default is to use a classloader singleton from {@link PRNG}.
124
   */
125
  public static final String SOURCE_OF_RANDOMNESS = "gnu.crypto.dss.prng";
126
 
127
  /**
128
   * Property name of an optional {@link DSAParameterSpec} instance to use for
129
   * this generator's <code>p</code>, <code>q</code>, and <code>g</code>
130
   * values. The default is to generate these values or use pre-computed ones,
131
   * depending on the value of the <code>USE_DEFAULTS</code> attribute.
132
   */
133
  public static final String DSS_PARAMETERS = "gnu.crypto.dss.params";
134
 
135
  /**
136
   * Property name of the preferred encoding format to use when externalizing
137
   * generated instance of key-pairs from this generator. The property is taken
138
   * to be an {@link Integer} that encapsulates an encoding format identifier.
139
   */
140
  public static final String PREFERRED_ENCODING_FORMAT = "gnu.crypto.dss.encoding";
141
 
142
  /** Default value for the modulus length. */
143
  public static final int DEFAULT_MODULUS_LENGTH = 1024;
144
 
145
  /** Default encoding format to use when none was specified. */
146
  private static final int DEFAULT_ENCODING_FORMAT = Registry.RAW_ENCODING_ID;
147
 
148
  /** Initial SHS context. */
149
  private static final int[] T_SHS = new int[] {
150
      0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
151
  };
152
 
153
  // from jdk1.3.1/docs/guide/security/CryptoSpec.html#AppB
154
  public static final DSAParameterSpec KEY_PARAMS_512 = new DSAParameterSpec(
155
      new BigInteger(
156
          "fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae"
157
        + "01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17", 16),
158
      new BigInteger("962eddcc369cba8ebb260ee6b6a126d9346e38c5", 16),
159
      new BigInteger(
160
          "678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e"
161
        + "35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4", 16));
162
  public static final DSAParameterSpec KEY_PARAMS_768 = new DSAParameterSpec(
163
      new BigInteger(
164
          "e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5d8901419"
165
        + "22d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a22219d470bce7d77"
166
        + "7d4a21fbe9c270b57f607002f3cef8393694cf45ee3688c11a8c56ab127a3daf", 16),
167
      new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", 16),
168
      new BigInteger(
169
          "30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7a31d23c4"
170
        + "dbbcbe06174544401a5b2c020965d8c2bd2171d3668445771f74ba084d2029d8"
171
        + "3c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a7064f316933a346d3f529252", 16));
172
  public static final DSAParameterSpec KEY_PARAMS_1024 = new DSAParameterSpec(
173
      new BigInteger(
174
          "fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669"
175
        + "455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b7"
176
        + "6b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb"
177
        + "83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16),
178
      new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16),
179
      new BigInteger(
180
          "f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d078267"
181
        + "5159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e1"
182
        + "3c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243b"
183
        + "cca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16));
184
 
185
  private static final BigInteger TWO_POW_160 = TWO.pow(160);
186
 
187
  /** The length of the modulus of DSS keys generated by this instance. */
188
  private int L;
189
 
190
  /** The optional {@link SecureRandom} instance to use. */
191
  private SecureRandom rnd = null;
192
 
193
  private BigInteger seed;
194
 
195
  private BigInteger counter;
196
 
197
  private BigInteger p;
198
 
199
  private BigInteger q;
200
 
201
  private BigInteger e;
202
 
203
  private BigInteger g;
204
 
205
  private BigInteger XKEY;
206
 
207
  /** Our default source of randomness. */
208
  private PRNG prng = null;
209
 
210
  /** Preferred encoding format of generated keys. */
211
  private int preferredFormat;
212
 
213
  public String name()
214
  {
215
    return Registry.DSS_KPG;
216
  }
217
 
218
  /**
219
   * Configures this instance.
220
   *
221
   * @param attributes the map of name/value pairs to use.
222
   * @exception IllegalArgumentException if the designated MODULUS_LENGTH value
223
   *              is not greater than 512, less than 1024 and not of the form
224
   *              <code>512 + 64j</code>.
225
   */
226
  public void setup(Map attributes)
227
  {
228
    // find out the modulus length
229
    Integer l = (Integer) attributes.get(MODULUS_LENGTH);
230
    L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue());
231
    if ((L % 64) != 0 || L < 512 || L > 1024)
232
      throw new IllegalArgumentException(MODULUS_LENGTH);
233
 
234
    // should we use the default pre-computed params?
235
    Boolean useDefaults = (Boolean) attributes.get(USE_DEFAULTS);
236
    if (useDefaults == null)
237
      useDefaults = Boolean.TRUE;
238
 
239
    Boolean strictDefaults = (Boolean) attributes.get(STRICT_DEFAULTS);
240
    if (strictDefaults == null)
241
      strictDefaults = Boolean.FALSE;
242
 
243
    // are we given a set of DSA params or we shall use/generate our own?
244
    DSAParameterSpec params = (DSAParameterSpec) attributes.get(DSS_PARAMETERS);
245
    if (params != null)
246
      {
247
        p = params.getP();
248
        q = params.getQ();
249
        g = params.getG();
250
      }
251
    else if (useDefaults.equals(Boolean.TRUE))
252
      {
253
        switch (L)
254
          {
255
          case 512:
256
            p = KEY_PARAMS_512.getP();
257
            q = KEY_PARAMS_512.getQ();
258
            g = KEY_PARAMS_512.getG();
259
            break;
260
          case 768:
261
            p = KEY_PARAMS_768.getP();
262
            q = KEY_PARAMS_768.getQ();
263
            g = KEY_PARAMS_768.getG();
264
            break;
265
          case 1024:
266
            p = KEY_PARAMS_1024.getP();
267
            q = KEY_PARAMS_1024.getQ();
268
            g = KEY_PARAMS_1024.getG();
269
            break;
270
          default:
271
            if (strictDefaults.equals(Boolean.TRUE))
272
              throw new IllegalArgumentException(
273
                  "Does not provide default parameters for " + L
274
                  + "-bit modulus length");
275
            else
276
              {
277
                p = null;
278
                q = null;
279
                g = null;
280
              }
281
          }
282
      }
283
    else
284
      {
285
        p = null;
286
        q = null;
287
        g = null;
288
      }
289
    // do we have a SecureRandom, or should we use our own?
290
    rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS);
291
    // what is the preferred encoding format
292
    Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT);
293
    preferredFormat = formatID == null ? DEFAULT_ENCODING_FORMAT
294
                                       : formatID.intValue();
295
    // set the seed-key
296
    byte[] kb = new byte[20]; // we need 160 bits of randomness
297
    nextRandomBytes(kb);
298
    XKEY = new BigInteger(1, kb).setBit(159).setBit(0);
299
  }
300
 
301
  public KeyPair generate()
302
  {
303
    if (p == null)
304
      {
305
        BigInteger[] params = new FIPS186(L, rnd).generateParameters();
306
        seed = params[FIPS186.DSA_PARAMS_SEED];
307
        counter = params[FIPS186.DSA_PARAMS_COUNTER];
308
        q = params[FIPS186.DSA_PARAMS_Q];
309
        p = params[FIPS186.DSA_PARAMS_P];
310
        e = params[FIPS186.DSA_PARAMS_E];
311
        g = params[FIPS186.DSA_PARAMS_G];
312
        if (Configuration.DEBUG)
313
          {
314
            log.fine("seed: " + seed.toString(16));
315
            log.fine("counter: " + counter.intValue());
316
            log.fine("q: " + q.toString(16));
317
            log.fine("p: " + p.toString(16));
318
            log.fine("e: " + e.toString(16));
319
            log.fine("g: " + g.toString(16));
320
          }
321
      }
322
    BigInteger x = nextX();
323
    BigInteger y = g.modPow(x, p);
324
    PublicKey pubK = new DSSPublicKey(preferredFormat, p, q, g, y);
325
    PrivateKey secK = new DSSPrivateKey(preferredFormat, p, q, g, x);
326
    return new KeyPair(pubK, secK);
327
  }
328
 
329
  /**
330
   * This method applies the following algorithm described in 3.1 of FIPS-186:
331
   * <ol>
332
   * <li>XSEED = optional user input.</li>
333
   * <li>XVAL = (XKEY + XSEED) mod 2<sup>b</sup>.</li>
334
   * <li>x = G(t, XVAL) mod q.</li>
335
   * <li>XKEY = (1 + XKEY + x) mod 2<sup>b</sup>.</li>
336
   * </ol>
337
   * <p>
338
   * Where <code>b</code> is the length of a secret b-bit seed-key (XKEY).
339
   * <p>
340
   * Note that in this implementation, XSEED, the optional user input, is always
341
   * zero.
342
   */
343
  private synchronized BigInteger nextX()
344
  {
345
    byte[] xk = XKEY.toByteArray();
346
    byte[] in = new byte[64]; // 512-bit block for SHS
347
    System.arraycopy(xk, 0, in, 0, xk.length);
348
    int[] H = Sha160.G(T_SHS[0], T_SHS[1], T_SHS[2], T_SHS[3], T_SHS[4], in, 0);
349
    byte[] h = new byte[20];
350
    for (int i = 0, j = 0; i < 5; i++)
351
      {
352
        h[j++] = (byte)(H[i] >>> 24);
353
        h[j++] = (byte)(H[i] >>> 16);
354
        h[j++] = (byte)(H[i] >>> 8);
355
        h[j++] = (byte) H[i];
356
      }
357
    BigInteger result = new BigInteger(1, h).mod(q);
358
    XKEY = XKEY.add(result).add(BigInteger.ONE).mod(TWO_POW_160);
359
    return result;
360
  }
361
 
362
  /**
363
   * Fills the designated byte array with random data.
364
   *
365
   * @param buffer the byte array to fill with random data.
366
   */
367
  private void nextRandomBytes(byte[] buffer)
368
  {
369
    if (rnd != null)
370
      rnd.nextBytes(buffer);
371
    else
372
      getDefaultPRNG().nextBytes(buffer);
373
  }
374
 
375
  private PRNG getDefaultPRNG()
376
  {
377
    if (prng == null)
378
      prng = PRNG.getInstance();
379
 
380
    return prng;
381
  }
382
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.