1 21 package com.db4o.io.crypt; 22 23 26 public class XTEA { 27 28 31 public final static class IterationSpec { 32 int _iterations; 33 int _deltaSumInitial; 34 35 IterationSpec(int iterations,int deltaSumInitial) { 36 _iterations=iterations; 37 _deltaSumInitial=deltaSumInitial; 38 } 39 } 40 41 public final static IterationSpec ITERATIONS8=new IterationSpec(8,0xF1BBCDC8); 42 public final static IterationSpec ITERATIONS16=new IterationSpec(16,0xE3779B90); 43 public final static IterationSpec ITERATIONS32=new IterationSpec(32,0xC6EF3720); 44 public final static IterationSpec ITERATIONS64=new IterationSpec(64,0x8DDE6E40); 45 46 private final IterationSpec _iterationSpec; 47 48 private static final int DELTA = 0x9E3779B9; 49 50 private int[] _key; 51 52 62 public XTEA(String key, IterationSpec iterationSpec) { 63 this(new KeyGenerator().core(key), iterationSpec); 64 } 65 66 75 public XTEA(String key) { 76 this(new KeyGenerator().core(key), ITERATIONS32); 77 } 78 79 84 private XTEA(int[] key, IterationSpec iterationSpec) throws IllegalArgumentException { 85 if (key.length != 4) { 86 throw new IllegalArgumentException (); 87 } 88 _key = key; 89 _iterationSpec=iterationSpec; 90 } 91 92 105 private void byte2int(byte[] bytes, int offset, int[] res) { 106 res[0] = (((bytes[offset] & 0xff) << 24) 107 | ((bytes[offset + 1] & 0xff) << 16) 108 | ((bytes[offset + 2] & 0xff) << 8) | (bytes[offset + 3] & 0xff)); 109 res[1] = (((bytes[offset + 4] & 0xff) << 24) 110 | ((bytes[offset + 5] & 0xff) << 16) 111 | ((bytes[offset + 6] & 0xff) << 8) | (bytes[offset + 7] & 0xff)); 112 } 113 114 127 private void int2byte(int[] i, int offset, byte[] res) { 128 res[offset] = (byte) ((i[0] & 0xff000000) >>> 24); 129 res[offset + 1] = (byte) ((i[0] & 0x00ff0000) >>> 16); 130 res[offset + 2] = (byte) ((i[0] & 0x0000ff00) >>> 8); 131 res[offset + 3] = (byte) (i[0] & 0x000000ff); 132 res[offset + 4] = (byte) ((i[1] & 0xff000000) >>> 24); 133 res[offset + 5] = (byte) ((i[1] & 0x00ff0000) >>> 16); 134 res[offset + 6] = (byte) ((i[1] & 0x0000ff00) >>> 8); 135 res[offset + 7] = (byte) (i[1] & 0x000000ff); 136 137 } 138 139 146 private void encipher(int[] block) { 147 int n = _iterationSpec._iterations; 148 int delta_sum = 0; 149 while (n-- > 0) { 150 block[0] += ((block[1] << 4 ^ block[1] >> 5) + block[1]) 151 ^ (delta_sum + _key[delta_sum & 3]); 152 delta_sum += DELTA; 153 block[1] += ((block[0] << 4 ^ block[0] >> 5) + block[0]) 154 ^ (delta_sum + _key[delta_sum >> 11 & 3]); 155 156 } 157 } 158 159 166 private void decipher(int[] e_block) { 167 int delta_sum = _iterationSpec._deltaSumInitial; 168 int n = _iterationSpec._iterations; 169 while (n-- > 0) { 170 e_block[1] -= ((e_block[0] << 4 ^ e_block[0] >> 5) + e_block[0]) 171 ^ (delta_sum + _key[delta_sum >> 11 & 3]); 172 delta_sum -= DELTA; 173 e_block[0] -= ((e_block[1] << 4 ^ e_block[1] >> 5) + e_block[1]) 174 ^ (delta_sum + _key[delta_sum & 3]); 175 } 176 } 177 178 184 public void encrypt(byte[] buffer) { 185 int[] asInt = new int[2]; 186 for (int i = 0; i < buffer.length; i += 8) { 187 byte2int(buffer, i, asInt); 188 encipher(asInt); 189 int2byte(asInt, i, buffer); 190 } 191 } 192 193 200 public void decrypt(byte[] buffer) { 201 int[] asInt = new int[2]; 202 for (int i = 0; i < buffer.length; i += 8) { 203 byte2int(buffer, i, asInt); 204 decipher(asInt); 205 int2byte(asInt, i, buffer); 206 } 207 } 208 } 209 | Popular Tags |