1
package org.bouncycastle.crypto.engines;
3
import org.bouncycastle.crypto.BlockCipher;
4
import org.bouncycastle.crypto.CipherParameters;
5
import org.bouncycastle.crypto.DataLengthException;
6
import org.bouncycastle.crypto.params.KeyParameter;
11
public class TEAEngine
12
implements BlockCipher
14
private static final int rounds = 32,
18
d_sum = 0xC6EF3720; // sum on decrypt
20
* the expanded key array of 4 subkeys
22
private int _a, _b, _c, _d;
23
private boolean _initialised;
24
private boolean _forEncryption;
27
* Create an instance of the TEA encryption algorithm
28
* and set some defaults
35
public String getAlgorithmName()
40
public int getBlockSize()
48
* @param forEncryption whether or not we are for encryption.
49
* @param params the parameters required to set up the cipher.
50
* @exception IllegalArgumentException if the params argument is
54
boolean forEncryption,
55
CipherParameters params)
57
if (!(params instanceof KeyParameter))
59
throw new IllegalArgumentException("invalid parameter passed to TEA init - " + params.getClass().getName());
62
_forEncryption = forEncryption;
65
KeyParameter p = (KeyParameter)params;
70
public int processBlock(
78
throw new IllegalStateException(getAlgorithmName()+" not initialised");
81
if ((inOff + block_size) > in.length)
83
throw new DataLengthException("input buffer too short");
86
if ((outOff + block_size) > out.length)
88
throw new DataLengthException("output buffer too short");
91
return (_forEncryption) ? encryptBlock(in, inOff, out, outOff)
92
: decryptBlock(in, inOff, out, outOff);
102
* @param key the key to be used
107
_a = bytesToInt(key, 0);
108
_b = bytesToInt(key, 4);
109
_c = bytesToInt(key, 8);
110
_d = bytesToInt(key, 12);
113
private int encryptBlock(
119
// Pack bytes into integers
120
int v0 = bytesToInt(in, inOff);
121
int v1 = bytesToInt(in, inOff + 4);
125
for (int i = 0; i != rounds; i++)
128
v0 += ((v1 << 4) + _a) ^ (v1 + sum) ^ ((v1 >>> 5) + _b);
129
v1 += ((v0 << 4) + _c) ^ (v0 + sum) ^ ((v0 >>> 5) + _d);
132
unpackInt(v0, out, outOff);
133
unpackInt(v1, out, outOff + 4);
138
private int decryptBlock(
144
// Pack bytes into integers
145
int v0 = bytesToInt(in, inOff);
146
int v1 = bytesToInt(in, inOff + 4);
150
for (int i = 0; i != rounds; i++)
152
v1 -= ((v0 << 4) + _c) ^ (v0 + sum) ^ ((v0 >>> 5) + _d);
153
v0 -= ((v1 << 4) + _a) ^ (v1 + sum) ^ ((v1 >>> 5) + _b);
157
unpackInt(v0, out, outOff);
158
unpackInt(v1, out, outOff + 4);
163
private int bytesToInt(byte[] in, int inOff)
165
return ((in[inOff++]) << 24) |
166
((in[inOff++] & 255) << 16) |
167
((in[inOff++] & 255) << 8) |
171
private void unpackInt(int v, byte[] out, int outOff)
173
out[outOff++] = (byte)(v >>> 24);
174
out[outOff++] = (byte)(v >>> 16);
175
out[outOff++] = (byte)(v >>> 8);
176
out[outOff ] = (byte)v;