dsskeypairgenerator.java
来自「linux下建立JAVA虚拟机的源码KAFFE」· Java 代码 · 共 446 行 · 第 1/2 页
JAVA
446 行
private SecureRandom rnd = null; private BigInteger seed; private BigInteger counter; private BigInteger p; private BigInteger q; private BigInteger e; private BigInteger g; private BigInteger XKEY; /** Our default source of randomness. */ private PRNG prng = null; /** Preferred encoding format of generated keys. */ private int preferredFormat; // Constructor(s) // ------------------------------------------------------------------------- // implicit 0-arguments constructor // Class methods // ------------------------------------------------------------------------- // Instance methods // ------------------------------------------------------------------------- // gnu.crypto.key.IKeyPairGenerator interface implementation --------------- public String name() { return Registry.DSS_KPG; } /** * <p>Configures this instance.</p> * * @param attributes the map of name/value pairs to use. * @exception IllegalArgumentException if the designated MODULUS_LENGTH * value is not greater than 512, less than 1024 and not of the form * <code>512 + 64j</code>. */ public void setup(Map attributes) { // find out the modulus length Integer l = (Integer) attributes.get(MODULUS_LENGTH); L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue()); if ((L % 64) != 0 || L < 512 || L > 1024) throw new IllegalArgumentException(MODULUS_LENGTH); // should we use the default pre-computed params? Boolean useDefaults = (Boolean) attributes.get(USE_DEFAULTS); if (useDefaults == null) { useDefaults = Boolean.TRUE; } Boolean strictDefaults = (Boolean) attributes.get(STRICT_DEFAULTS); if (strictDefaults == null) strictDefaults = Boolean.FALSE; // are we given a set of DSA params or we shall use/generate our own? DSAParameterSpec params = (DSAParameterSpec) attributes.get(DSS_PARAMETERS); if (params != null) { p = params.getP(); q = params.getQ(); g = params.getG(); } else if (useDefaults.equals(Boolean.TRUE)) { switch (L) { case 512: p = KEY_PARAMS_512.getP(); q = KEY_PARAMS_512.getQ(); g = KEY_PARAMS_512.getG(); break; case 768: p = KEY_PARAMS_768.getP(); q = KEY_PARAMS_768.getQ(); g = KEY_PARAMS_768.getG(); break; case 1024: p = KEY_PARAMS_1024.getP(); q = KEY_PARAMS_1024.getQ(); g = KEY_PARAMS_1024.getG(); break; default: if (strictDefaults.equals(Boolean.TRUE)) throw new IllegalArgumentException( "Does not provide default parameters for " + L + "-bit modulus length"); else { p = null; q = null; g = null; } } } else { p = null; q = null; g = null; } // do we have a SecureRandom, or should we use our own? rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS); // what is the preferred encoding format Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT); preferredFormat = formatID == null ? DEFAULT_ENCODING_FORMAT : formatID.intValue(); // set the seed-key byte[] kb = new byte[20]; // we need 160 bits of randomness nextRandomBytes(kb); XKEY = new BigInteger(1, kb).setBit(159).setBit(0); } public KeyPair generate() { if (p == null) { BigInteger[] params = new FIPS186(L, rnd).generateParameters(); seed = params[FIPS186.DSA_PARAMS_SEED]; counter = params[FIPS186.DSA_PARAMS_COUNTER]; q = params[FIPS186.DSA_PARAMS_Q]; p = params[FIPS186.DSA_PARAMS_P]; e = params[FIPS186.DSA_PARAMS_E]; g = params[FIPS186.DSA_PARAMS_G]; if (DEBUG && debuglevel > 0) { debug("seed: " + seed.toString(16)); debug("counter: " + counter.intValue()); debug("q: " + q.toString(16)); debug("p: " + p.toString(16)); debug("e: " + e.toString(16)); debug("g: " + g.toString(16)); } } BigInteger x = nextX(); BigInteger y = g.modPow(x, p); PublicKey pubK = new DSSPublicKey(preferredFormat, p, q, g, y); PrivateKey secK = new DSSPrivateKey(preferredFormat, p, q, g, x); return new KeyPair(pubK, secK); } // Other instance methods -------------------------------------------------- /** * <p>This method applies the following algorithm described in 3.1 of * FIPS-186:</p> * * <ol> * <li>XSEED = optional user input.</li> * <li>XVAL = (XKEY + XSEED) mod 2<sup>b</sup>.</li> * <li>x = G(t, XVAL) mod q.</li> * <li>XKEY = (1 + XKEY + x) mod 2<sup>b</sup>.</li> * </ol> * * <p>Where <code>b</code> is the length of a secret b-bit seed-key (XKEY).</p> * * <p>Note that in this implementation, XSEED, the optional user input, is * always zero.</p> */ private synchronized BigInteger nextX() { byte[] xk = XKEY.toByteArray(); byte[] in = new byte[64]; // 512-bit block for SHS System.arraycopy(xk, 0, in, 0, xk.length); int[] H = Sha160.G(T_SHS[0], T_SHS[1], T_SHS[2], T_SHS[3], T_SHS[4], in, 0); byte[] h = new byte[20]; for (int i = 0, j = 0; i < 5; i++) { h[j++] = (byte) (H[i] >>> 24); h[j++] = (byte) (H[i] >>> 16); h[j++] = (byte) (H[i] >>> 8); h[j++] = (byte) H[i]; } BigInteger result = new BigInteger(1, h).mod(q); XKEY = XKEY.add(result).add(BigInteger.ONE).mod(TWO_POW_160); return result; } /** * <p>Fills the designated byte array with random data.</p> * * @param buffer the byte array to fill with random data. */ private void nextRandomBytes(byte[] buffer) { if (rnd != null) { rnd.nextBytes(buffer); } else getDefaultPRNG().nextBytes(buffer); } private PRNG getDefaultPRNG() { if (prng == null) prng = PRNG.getInstance(); return prng; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?