Provides a basic API for algorithms to generate Public/Private keypairs, and Key Agreement schemes.

## Package overview

The contents of this package hierarchy is organised as follows:

- interfaces that describe the visible methods of concrete implementations of those interfaces,
- Factory classes that generate specific instances given a canonical name.
- common classes used by two or more concrete implementations,
- separate sub-packages for each implemented algorithm.

The four key-pair generation algorithms currently implemented in this library are:

- Diffie-Hellman: `gnu.crypto.key.dh`,
- Digital Signature Scheme: `gnu.crypto.key.dss`,
- Rivest, Shamir and Adleman (RSA): `gnu.crypto.key.rsa`,
- Secure Remote Password 6: `gnu.crypto.key.srp6`.

The Key Agreement protocols currently implemented in this library are:

- Diffie-Hellman
  1. Basic version: also described in RFC-2631 as Static-Static mode, and
  2. ElGamal version: also known as half-certified Diffie-Hellman, or Ephemeral-Static mode in RFC-2631.
- Secure Remote Password
  1. Basic version: described, by Thomas J. Wu, in SRP Protocol Design, and
  2. The version adopted for use as a SASL (Simple Authentication and Security Layer) mechanism in the internet draft Secure Remote Password Authentication Mechanism.

The following diagram shows the important classes participating in key-pair generation:

The next diagram shows the important classes participating in key agreements:

The next two diagrams show the sequences involved in generating a keypair, and establishing a key agreement protocol.

The following example shows the code that can be used to generate a key- pair:

    import gnu.crypto.sig.rsa.RSA;
    import gnu.crypto.key.rsa.RSAKeyPairGenerator;

    import java.math.BigInteger;
    import java.security.KeyPair;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPrivateCrtKey;
    import java.security.interfaces.RSAPublicKey;
    import java.util.HashMap;
    import java.util.Random;

    ...
    RSAKeyPairGenerator kpg = new RSAKeyPairGenerator();
    HashMap map = new HashMap();
    map.put(RSAKeyPairGenerator.MODULUS_LENGTH, new Integer(1024));
    kpg.setup(map);

    KeyPair kp = kpg.generate();

    BigInteger n1 = ((RSAPublicKey) kp.getPublic()).getModulus();
    BigInteger e =  ((RSAPublicKey) kp.getPublic()).getPublicExponent();

    BigInteger n2 = ((RSAPrivateKey) kp.getPrivate()).getModulus();
    BigInteger d =  ((RSAPrivateKey) kp.getPrivate()).getPrivateExponent();

    BigInteger p =    ((RSAPrivateCrtKey) kp.getPrivate()).getPrimeP();
    BigInteger q =    ((RSAPrivateCrtKey) kp.getPrivate()).getPrimeQ();
    BigInteger dP =   ((RSAPrivateCrtKey) kp.getPrivate()).getPrimeExponentP();
    BigInteger dQ =   ((RSAPrivateCrtKey) kp.getPrivate()).getPrimeExponentQ();
    BigInteger qInv = ((RSAPrivateCrtKey) kp.getPrivate()).getCrtCoefficient();