+++ /dev/null
-package org.bouncycastle.crypto.engines;\r
-\r
-import org.bouncycastle.crypto.StreamCipher;\r
-import org.bouncycastle.crypto.CipherParameters;\r
-import org.bouncycastle.crypto.DataLengthException;\r
-import org.bouncycastle.crypto.params.KeyParameter;\r
-\r
-public class RC4Engine implements StreamCipher\r
-{\r
- private final static int STATE_LENGTH = 256;\r
-\r
- /*\r
- * variables to hold the state of the RC4 engine\r
- * during encryption and decryption\r
- */\r
-\r
- private byte[] engineState = null;\r
- private int x = 0;\r
- private int y = 0;\r
- private byte[] workingKey = null;\r
-\r
- /**\r
- * initialise a RC4 cipher.\r
- *\r
- * @param forEncryption whether or not we are for encryption.\r
- * @param params the parameters required to set up the cipher.\r
- * @exception IllegalArgumentException if the params argument is\r
- * inappropriate.\r
- */\r
- public void init(\r
- boolean forEncryption, \r
- CipherParameters params\r
- )\r
- {\r
- if (params instanceof KeyParameter)\r
- {\r
- /* \r
- * RC4 encryption and decryption is completely\r
- * symmetrical, so the 'forEncryption' is \r
- * irrelevant.\r
- */\r
- workingKey = ((KeyParameter)params).getKey();\r
- setKey(workingKey);\r
-\r
- return;\r
- }\r
-\r
- throw new IllegalArgumentException("invalid parameter passed to RC4 init - " + params.getClass().getName());\r
- }\r
-\r
- public String getAlgorithmName()\r
- {\r
- return "RC4";\r
- }\r
-\r
- public byte returnByte(byte in)\r
- {\r
- x = (x + 1) & 0xff;\r
- y = (engineState[x] + y) & 0xff;\r
-\r
- // swap\r
- byte tmp = engineState[x];\r
- engineState[x] = engineState[y];\r
- engineState[y] = tmp;\r
-\r
- // xor\r
- return (byte)(in ^ engineState[(engineState[x] + engineState[y]) & 0xff]);\r
- }\r
-\r
- public void processBytes(\r
- byte[] in, \r
- int inOff, \r
- int len, \r
- byte[] out, \r
- int outOff\r
- )\r
- {\r
- if ((inOff + len) > in.length)\r
- {\r
- throw new DataLengthException("input buffer too short");\r
- }\r
-\r
- if ((outOff + len) > out.length)\r
- {\r
- throw new DataLengthException("output buffer too short");\r
- }\r
-\r
- for (int i = 0; i < len ; i++)\r
- {\r
- x = (x + 1) & 0xff;\r
- y = (engineState[x] + y) & 0xff;\r
-\r
- // swap\r
- byte tmp = engineState[x];\r
- engineState[x] = engineState[y];\r
- engineState[y] = tmp;\r
-\r
- // xor\r
- out[i+outOff] = (byte)(in[i + inOff]\r
- ^ engineState[(engineState[x] + engineState[y]) & 0xff]);\r
- }\r
- }\r
-\r
- public void reset()\r
- {\r
- setKey(workingKey);\r
- }\r
-\r
- // Private implementation\r
-\r
- private void setKey(byte[] keyBytes)\r
- {\r
- workingKey = keyBytes;\r
-\r
- // System.out.println("the key length is ; "+ workingKey.length);\r
-\r
- x = 0;\r
- y = 0;\r
-\r
- if (engineState == null)\r
- {\r
- engineState = new byte[STATE_LENGTH];\r
- }\r
-\r
- // reset the state of the engine\r
- for (int i=0; i < STATE_LENGTH; i++)\r
- {\r
- engineState[i] = (byte)i;\r
- }\r
- \r
- int i1 = 0;\r
- int i2 = 0;\r
-\r
- for (int i=0; i < STATE_LENGTH; i++)\r
- {\r
- i2 = ((keyBytes[i1] & 0xff) + engineState[i] + i2) & 0xff;\r
- // do the byte-swap inline\r
- byte tmp = engineState[i];\r
- engineState[i] = engineState[i2];\r
- engineState[i2] = tmp;\r
- i1 = (i1+1) % keyBytes.length; \r
- }\r
- }\r
-}\r