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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* RSAKeyPairGenerator.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.rsa;
40
 
41
import gnu.java.security.Configuration;
42
import gnu.java.security.Registry;
43
import gnu.java.security.key.IKeyPairGenerator;
44
import gnu.java.security.util.PRNG;
45
 
46
import java.math.BigInteger;
47
import java.security.KeyPair;
48
import java.security.PrivateKey;
49
import java.security.PublicKey;
50
import java.security.SecureRandom;
51
import java.security.spec.RSAKeyGenParameterSpec;
52
import java.util.Map;
53
import java.util.logging.Logger;
54
 
55
/**
56
 * A key-pair generator for asymetric keys to use in conjunction with the RSA
57
 * scheme.
58
 * <p>
59
 * Reference:
60
 * <ol>
61
 * <li><a
62
 * href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip">
63
 * RSA-PSS Signature Scheme with Appendix</a>, part B. Primitive specification
64
 * and supporting documentation. Jakob Jonsson and Burt Kaliski. </li>
65
 * <li><a href="http://www.cacr.math.uwaterloo.ca/hac/">Handbook of Applied
66
 * Cryptography</a>, Alfred J. Menezes, Paul C. van Oorschot and Scott A.
67
 * Vanstone. Section 11.3 RSA and related signature schemes.</li>
68
 * </ol>
69
 */
70
public class RSAKeyPairGenerator
71
    implements IKeyPairGenerator
72
{
73
  private static final Logger log = Logger.getLogger(RSAKeyPairGenerator.class.getName());
74
 
75
  /** The BigInteger constant 1. */
76
  private static final BigInteger ONE = BigInteger.ONE;
77
 
78
  /** The BigInteger constant 2. */
79
  private static final BigInteger TWO = BigInteger.valueOf(2L);
80
 
81
  /** Property name of the length (Integer) of the modulus of an RSA key. */
82
  public static final String MODULUS_LENGTH = "gnu.crypto.rsa.L";
83
 
84
  /**
85
   * Property name of an optional {@link SecureRandom} instance to use. The
86
   * default is to use a classloader singleton from {@link PRNG}.
87
   */
88
  public static final String SOURCE_OF_RANDOMNESS = "gnu.crypto.rsa.prng";
89
 
90
  /**
91
   * Property name of an optional {@link RSAKeyGenParameterSpec} instance to use
92
   * for this generator's <code>n</code>, and <code>e</code> values. The
93
   * default is to generate <code>n</code> and use a fixed value for
94
   * <code>e</.code> (Fermat's F4 number).
95
   */
96
  public static final String RSA_PARAMETERS = "gnu.crypto.rsa.params";
97
 
98
  /**
99
   * Property name of the preferred encoding format to use when externalizing
100
   * generated instance of key-pairs from this generator. The property is taken
101
   * to be an {@link Integer} that encapsulates an encoding format identifier.
102
   */
103
  public static final String PREFERRED_ENCODING_FORMAT = "gnu.crypto.rsa.encoding";
104
 
105
  /** Default value for the modulus length. */
106
  private static final int DEFAULT_MODULUS_LENGTH = 1024;
107
 
108
  /** Default encoding format to use when none was specified. */
109
  private static final int DEFAULT_ENCODING_FORMAT = Registry.RAW_ENCODING_ID;
110
 
111
  /** The desired bit length of the modulus. */
112
  private int L;
113
 
114
  /**
115
   * This implementation uses, by default, Fermat's F4 number as the public
116
   * exponent.
117
   */
118
  private BigInteger e = BigInteger.valueOf(65537L);
119
 
120
  /** The optional {@link SecureRandom} instance to use. */
121
  private SecureRandom rnd = null;
122
 
123
  /** Our default source of randomness. */
124
  private PRNG prng = null;
125
 
126
  /** Preferred encoding format of generated keys. */
127
  private int preferredFormat;
128
 
129
  // implicit 0-arguments constructor
130
 
131
  public String name()
132
  {
133
    return Registry.RSA_KPG;
134
  }
135
 
136
  /**
137
   * Configures this instance.
138
   *
139
   * @param attributes the map of name/value pairs to use.
140
   * @exception IllegalArgumentException if the designated MODULUS_LENGTH value
141
   *              is less than 1024.
142
   */
143
  public void setup(Map attributes)
144
  {
145
    if (Configuration.DEBUG)
146
      log.entering(this.getClass().getName(), "setup", attributes);
147
    // do we have a SecureRandom, or should we use our own?
148
    rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS);
149
    // are we given a set of RSA params or we shall use our own?
150
    RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) attributes.get(RSA_PARAMETERS);
151
    // find out the modulus length
152
    if (params != null)
153
      {
154
        L = params.getKeysize();
155
        e = params.getPublicExponent();
156
      }
157
    else
158
      {
159
        Integer l = (Integer) attributes.get(MODULUS_LENGTH);
160
        L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue());
161
      }
162
    if (L < 1024)
163
      throw new IllegalArgumentException(MODULUS_LENGTH);
164
 
165
    // what is the preferred encoding format
166
    Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT);
167
    preferredFormat = formatID == null ? DEFAULT_ENCODING_FORMAT
168
                                       : formatID.intValue();
169
    if (Configuration.DEBUG)
170
      log.exiting(this.getClass().getName(), "setup");
171
  }
172
 
173
  /**
174
   * <p>
175
   * The algorithm used here is described in <i>nessie-pss-B.pdf</i> document
176
   * which is part of the RSA-PSS submission to NESSIE.
177
   * </p>
178
   *
179
   * @return an RSA keypair.
180
   */
181
  public KeyPair generate()
182
  {
183
    if (Configuration.DEBUG)
184
      log.entering(this.getClass().getName(), "generate");
185
    BigInteger p, q, n, d;
186
    // 1. Generate a prime p in the interval [2**(M-1), 2**M - 1], where
187
    // M = CEILING(L/2), and such that GCD(p, e) = 1
188
    int M = (L + 1) / 2;
189
    BigInteger lower = TWO.pow(M - 1);
190
    BigInteger upper = TWO.pow(M).subtract(ONE);
191
    byte[] kb = new byte[(M + 7) / 8]; // enough bytes to frame M bits
192
    step1: while (true)
193
      {
194
        nextRandomBytes(kb);
195
        p = new BigInteger(1, kb).setBit(0);
196
        if (p.compareTo(lower) >= 0 && p.compareTo(upper) <= 0
197
            && p.isProbablePrime(80) && p.gcd(e).equals(ONE))
198
          break step1;
199
      }
200
    // 2. Generate a prime q such that the product of p and q is an L-bit
201
    // number, and such that GCD(q, e) = 1
202
    step2: while (true)
203
      {
204
        nextRandomBytes(kb);
205
        q = new BigInteger(1, kb).setBit(0);
206
        n = p.multiply(q);
207
        if (n.bitLength() == L && q.isProbablePrime(80) && q.gcd(e).equals(ONE))
208
          break step2;
209
        // TODO: test for p != q
210
      }
211
    // TODO: ensure p < q
212
    // 3. Put n = pq. The public key is (n, e).
213
    // 4. Compute the parameters necessary for the private key K (see
214
    // Section 2.2).
215
    BigInteger phi = p.subtract(ONE).multiply(q.subtract(ONE));
216
    d = e.modInverse(phi);
217
    // 5. Output the public key and the private key.
218
    PublicKey pubK = new GnuRSAPublicKey(preferredFormat, n, e);
219
    PrivateKey secK = new GnuRSAPrivateKey(preferredFormat, p, q, e, d);
220
    KeyPair result = new KeyPair(pubK, secK);
221
    if (Configuration.DEBUG)
222
      log.exiting(this.getClass().getName(), "generate", result);
223
    return result;
224
  }
225
 
226
  /**
227
   * Fills the designated byte array with random data.
228
   *
229
   * @param buffer the byte array to fill with random data.
230
   */
231
  private void nextRandomBytes(byte[] buffer)
232
  {
233
    if (rnd != null)
234
      rnd.nextBytes(buffer);
235
    else
236
      getDefaultPRNG().nextBytes(buffer);
237
  }
238
 
239
  private PRNG getDefaultPRNG()
240
  {
241
    if (prng == null)
242
      prng = PRNG.getInstance();
243
 
244
    return prng;
245
  }
246
}

powered by: WebSVN 2.1.0

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