ARC4public final class ARC4 extends Cipher This class implements the ARCfour stream cipher |
Fields Summary |
---|
private int | modeCurrent cipher mode. | private SecretKey | ckeyLocal certificate key. | private byte[] | SSeed array. | private int[] | iiFirst intermediate result array. | private int[] | jjSecond intermediate result array. |
Methods Summary |
---|
public void | ARC4()Constructor for algorithm 3 (ALG_ARCFOUR)
mode = Cipher.MODE_UNINITIALIZED;
S = null;
ii = null;
jj = null;
| public int | doFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)Encrypts or decrypts data in a single-part operation, or finishes a
multiple-part operation. The data is encrypted or decrypted,
depending on how this cipher was initialized.
The first inputLen bytes in the input
buffer, starting at inputOffset inclusive, and any input
bytes that may have been buffered during a previous
update operation, are processed, with padding
(if requested) being applied.
The result is stored in the output buffer, starting at
outputOffset inclusive.
If the output buffer is too small to hold the result,
a ShortBufferException is thrown. In this case, repeat this
call with a larger output buffer.
Upon finishing, this method resets this cipher object to the state
it was in when previously initialized via a call to init .
That is, the object is reset and available to encrypt or decrypt
(depending on the operation mode that was specified in the call to
init ) more data.
Note: if any exception is thrown, this cipher object may need to
be reset before it can be used again.
Note: this method should be copy-safe, which means the
input and output buffers can reference
the same byte array and no unprocessed input data is overwritten
when the result is copied into the output buffer.
int val = update(input, inputOffset, inputLen, output, outputOffset);
try {
init(mode, ckey);
} catch (InvalidKeyException ike) {
// ignore, the key was already checked
}
return val;
| public void | init(int opmode, Key key, CryptoParameter params)Initializes the cipher's S-boxes based on the key.
This code is based on the cipher's description in
Bruce Schenier's "Applied Cryptography", Second Edition, pp 397-398,
ISBN 0-471-11709-9
if (!(key instanceof SecretKey)) {
throw new InvalidKeyException();
}
if (opmode != Cipher.ENCRYPT_MODE && opmode != Cipher.DECRYPT_MODE) {
throw new IllegalArgumentException();
}
mode = opmode;
ckey = (SecretKey)key;
// Initialize the counters
ii = new int[1];
ii[0] = 0;
jj = new int[1];
jj[0] = 0;
S = new byte[256];
// Initialize S
for (int i = 0; i < 256; i++) {
S[i] = (byte) i;
}
// Initilaize K based on the key
byte[] K = new byte[256];
int index = 0;
while (index < 256) {
for (int i = 0; (i < ckey.secret.length) && (index < 256); i++) {
K[index++] = ckey.secret[i];
}
}
// Populate the 8*8 S-box
int j = 0;
byte temp;
for (int i = 0; i < 256; i++) {
j = (j + ((S[i] + K[i]) & 0xff)) & 0xff;
temp = S[i];
S[i] = S[j];
S[j] = temp;
}
| private static native void | nativetx(byte[] S, int[] X, int[] Y, byte[] inbuf, int inoff, int inlen, byte[] outbuf, int outoff)Native function to transform a buffer.
| protected void | setChainingModeAndPadding(java.lang.String mode, java.lang.String padding)Called by the factory method to set the mode and padding parameters.
Need because Class.newInstance does not take args.
if (!(mode.equals("") || mode.equals("NONE"))) {
throw new IllegalArgumentException();
}
// NOPADDING is not an option.
if (!(padding.equals("") || padding.equals("NOPADDING"))) {
throw new NoSuchPaddingException();
}
| private int | transform(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff)Transform a buffer of data,
/*
* Normally, we would use something like:
* int test = inBuf[inOff] + inBuf[inLen - 1] +
* inBuf[inOff + inLen - 1] +
* outBuf[outOff] + outBuf[outOff + inLen - 1];
* to force an array bounds check that might otherwise crash
* the VM. However, since we have such checks in the update
* method, we do not need them here.
*/
nativetx(S, ii, jj, inBuf, inOff, inLen, outBuf, outOff);
return inLen;
| public int | update(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)Update the current data record.
Util.checkBounds(input, inputOffset, inputLen,
output, outputOffset);
if (mode == Cipher.MODE_UNINITIALIZED) {
throw new IllegalStateException();
}
if (inputLen == 0) {
return 0;
}
if (output.length - outputOffset < inputLen) {
throw new ShortBufferException();
}
return transform(input, inputOffset, inputLen, output, outputOffset);
|
|