The Java Provider Architecture 
by Paul Tremblett


Example 1:

-------------
PROVIDER # 1
SUN version 1.2
info: SUN (DSA key/parameter generation; DSS signing; SHA-1, MD5 digests, SecureRandom)
name: SUN
version: 1.2
string: SUN version 1.2

-------------
PROVIDER # 2
SunJCE version 1.2
info: SUN JCE Provider (implements DES, Triple DES, PBE, Diffie-Hellman)
name: SunJCE
version: 1.2
string: SunJCE version 1.2


Example 2: 

com/
com/beechwood/
com/beechwood/crypto/
com/beechwood/crypto/provider/
com/beechwood/crypto/provider/Corbett.class
com/beechwood/crypto/cipher/
com/beechwood/crypto/cipher/Enigma.class
com/beechwood/crypto/cipher/EnigmaMachine.class
com/beechwood/crypto/cipher/EnigmaRotor.class
com/beechwood/crypto/cipher/EnigmaRotorTrippedException.class
com/beechwood/crypto/cipher/EnigmaReflector.class
com/beechwood/crypto/spec/
com/beechwood/crypto/spec/EnigmaParameterSpec.class
com/beechwood/crypto/interfaces/
com/beechwood/crypto/interfaces/EnigmaParams.class


Example 3: 

-------------
PROVIDER # 1
SUN version 1.2
info: SUN (DSA key/parameter generation; DSS signing; SHA-1, MD5 digests, SecureRandom)
name: SUN
version: 1.2
string: SUN version 1.2

-------------
PROVIDER # 2
SunJCE version 1.2
info: SUN JCE Provider (implements DES, Triple DES, PBE, Diffie-Hellman)
name: SunJCE
version: 1.2
string: SunJCE version 1.2

-------------
PROVIDER # 3
Corbett version 1.0
info: Provider For Dr. Dobb's Article
name: Corbett
version: 1.0
string: Corbett version 1.0



Listing One
package com.beechwood.crypto.cipher;
import java.security.SecureRandom;
public class EnigmaRotor {
  private int notchIndex;
  private int startPosition = 0;
  private int currentIndex = 0;

  private int[] b = new int[256];
  private int[] f = new int[256];

  public EnigmaRotor(long seed, int notchIndex) {
    this.notchIndex = notchIndex;
    int fx = 0;
    int bx;
    for (int i = 0; i < 256; ++i)
      f[i] = b[i] = -1;
    SecureRandom r = new SecureRandom();
    r.setSeed(seed);
    byte[] rb = new byte[1];
    for (int i = 0; i < 256; ++i) {
      r.nextBytes(rb);
      bx = rb[0] & 0xff;
      if (b[bx] < 0) {
        b[bx] = fx;
      }
      else {
        bx = (bx + 128) % 256;
        while (true) {
          if (bx > 255)
            bx = 0; 
          if (b[bx] < 0)
            break;
          bx++;
        }
        b[bx] = fx;
      }
      f[fx] = bx;
      fx++;
    }
  }
  public void setStartingPosition(int startPosition) {
    this.startPosition = currentIndex = startPosition;
  }
  public void advance() throws EnigmaRotorTrippedException {
    currentIndex++;
    if (currentIndex > 255) {
      currentIndex = 0;
    }
    if (currentIndex == notchIndex) {
      throw new EnigmaRotorTrippedException("notch at " + 
        notchIndex + " tripped");
    }
  }
  public int processByte(int i, boolean forward) {
    int ri;
    int ix;
    if (forward) {
      ix = (i + currentIndex) % 256;
      ri = b[ix];
    }
    else {
      ix = i;
      ri = (f[ix] - currentIndex + 256) % 256;
    }
    return ri;
  }
}


Listing Two
package com.beechwood.crypto.cipher;
public class EnigmaRotorTrippedException extends Exception {
  public EnigmaRotorTrippedException() {
    super();
  }
  public EnigmaRotorTrippedException(String msg) {
    super(msg);
  }
}

Listing Three
package com.beechwood.crypto.cipher;
import java.security.SecureRandom;
public class EnigmaReflector {
  int[] contacts = new int[256];
  public EnigmaReflector(long seed) {
    byte[] rb = new byte[1];
    int[] mi = new int[256];
    for (int i = 0; i < 256; ++i)
      mi[i] = -1;
    SecureRandom r = new SecureRandom();
    r.setSeed(seed);
    int[] f = new int[2];
    for (int i = 0; i < 128; ++i) {
      for (int j = 0; j < 2; ++j) {
        r.nextBytes(rb);
        int ix  = rb[0] &0x3f;
        while (true) {
          if (mi[ix] < 0) {
            mi[ix] = 1;
            f[j] = ix;
            break;
          }
          ++ix;
          if (ix > 255) {
            ix = 0;
          }
        }
      }
      contacts[f[0]] = f[1];
      contacts[f[1]] = f[0];
    }
  }
  public int reflect(int i) {
    return contacts[i];
  }
}


Listing Four
package com.beechwood.crypto.cipher;
public class EnigmaMachine {
  EnigmaRotor[] rotors;
  int rotorCount;
  EnigmaReflector reflector;

  public EnigmaMachine(EnigmaRotor[] rotors, EnigmaReflector ref) {
    this.rotors = rotors;
    rotorCount = rotors.length;
    reflector = ref;
  }
  protected void processMessage(byte[] in, int inOffset, 
      byte[] out, int outOffset, int len) {
    int ox = 0;
    for (int i = inOffset; i < len; ++i) {
      for (int rotorIndex = 0; rotorIndex < rotorCount; ++rotorIndex) {
        try {
          rotors[rotorIndex].advance();
          break;
        }
        catch (EnigmaRotorTrippedException erte) {
        }
      }
      int ic = ((int)in[i]) & 0xff;
      for (int k = 0; k < rotorCount; ++k) {
        ic = rotors[k].processByte(ic, true);
      }
      ic = reflector.reflect(ic);
      for (int k = rotorCount - 1; k >= 0; --k) {
        ic = rotors[k].processByte(ic, false);
      }
      out[ox++] = (byte)ic;
    }
  }
}


Listing Five
package com.beechwood.crypto.interfaces;
public abstract interface EnigmaParams {
  public int[] getNotchPositions();
  public int[] getStartPositions();
  public int getRotorCount();
}







5


