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 + -
显示快捷键?