1package org.bouncycastle.crypto.modes.gcm; 2 3import org.bouncycastle.util.Pack; 4 5public abstract class GCMUtil 6{ 7 private static final int E1 = 0xe1000000; 8 private static final long E1L = (E1 & 0xFFFFFFFFL) << 32; 9 10 private static int[] generateLookup() 11 { 12 int[] lookup = new int[256]; 13 14 for (int c = 0; c < 256; ++c) 15 { 16 int v = 0; 17 for (int i = 7; i >= 0; --i) 18 { 19 if ((c & (1 << i)) != 0) 20 { 21 v ^= (E1 >>> (7 - i)); 22 } 23 } 24 lookup[c] = v; 25 } 26 27 return lookup; 28 } 29 30 private static final int[] LOOKUP = generateLookup(); 31 32 public static byte[] oneAsBytes() 33 { 34 byte[] tmp = new byte[16]; 35 tmp[0] = (byte)0x80; 36 return tmp; 37 } 38 39 public static int[] oneAsInts() 40 { 41 int[] tmp = new int[4]; 42 tmp[0] = 1 << 31; 43 return tmp; 44 } 45 46 public static long[] oneAsLongs() 47 { 48 long[] tmp = new long[2]; 49 tmp[0] = 1L << 63; 50 return tmp; 51 } 52 53 public static byte[] asBytes(int[] x) 54 { 55 byte[] z = new byte[16]; 56 Pack.intToBigEndian(x, z, 0); 57 return z; 58 } 59 60 public static void asBytes(int[] x, byte[] z) 61 { 62 Pack.intToBigEndian(x, z, 0); 63 } 64 65 public static byte[] asBytes(long[] x) 66 { 67 byte[] z = new byte[16]; 68 Pack.longToBigEndian(x, z, 0); 69 return z; 70 } 71 72 public static void asBytes(long[] x, byte[] z) 73 { 74 Pack.longToBigEndian(x, z, 0); 75 } 76 77 public static int[] asInts(byte[] x) 78 { 79 int[] z = new int[4]; 80 Pack.bigEndianToInt(x, 0, z); 81 return z; 82 } 83 84 public static void asInts(byte[] x, int[] z) 85 { 86 Pack.bigEndianToInt(x, 0, z); 87 } 88 89 public static long[] asLongs(byte[] x) 90 { 91 long[] z = new long[2]; 92 Pack.bigEndianToLong(x, 0, z); 93 return z; 94 } 95 96 public static void asLongs(byte[] x, long[] z) 97 { 98 Pack.bigEndianToLong(x, 0, z); 99 } 100 101 public static void multiply(byte[] x, byte[] y) 102 { 103 int[] t1 = GCMUtil.asInts(x); 104 int[] t2 = GCMUtil.asInts(y); 105 GCMUtil.multiply(t1, t2); 106 GCMUtil.asBytes(t1, x); 107 } 108 109 public static void multiply(int[] x, int[] y) 110 { 111 int r00 = x[0], r01 = x[1], r02 = x[2], r03 = x[3]; 112 int r10 = 0, r11 = 0, r12 = 0, r13 = 0; 113 114 for (int i = 0; i < 4; ++i) 115 { 116 int bits = y[i]; 117 for (int j = 0; j < 32; ++j) 118 { 119 int m1 = bits >> 31; bits <<= 1; 120 r10 ^= (r00 & m1); 121 r11 ^= (r01 & m1); 122 r12 ^= (r02 & m1); 123 r13 ^= (r03 & m1); 124 125 int m2 = (r03 << 31) >> 8; 126 r03 = (r03 >>> 1) | (r02 << 31); 127 r02 = (r02 >>> 1) | (r01 << 31); 128 r01 = (r01 >>> 1) | (r00 << 31); 129 r00 = (r00 >>> 1) ^ (m2 & E1); 130 } 131 } 132 133 x[0] = r10; 134 x[1] = r11; 135 x[2] = r12; 136 x[3] = r13; 137 } 138 139 public static void multiply(long[] x, long[] y) 140 { 141 long r00 = x[0], r01 = x[1], r10 = 0, r11 = 0; 142 143 for (int i = 0; i < 2; ++i) 144 { 145 long bits = y[i]; 146 for (int j = 0; j < 64; ++j) 147 { 148 long m1 = bits >> 63; bits <<= 1; 149 r10 ^= (r00 & m1); 150 r11 ^= (r01 & m1); 151 152 long m2 = (r01 << 63) >> 8; 153 r01 = (r01 >>> 1) | (r00 << 63); 154 r00 = (r00 >>> 1) ^ (m2 & E1L); 155 } 156 } 157 158 x[0] = r10; 159 x[1] = r11; 160 } 161 162 // P is the value with only bit i=1 set 163 public static void multiplyP(int[] x) 164 { 165 int m = shiftRight(x) >> 8; 166 x[0] ^= (m & E1); 167 } 168 169 public static void multiplyP(int[] x, int[] z) 170 { 171 int m = shiftRight(x, z) >> 8; 172 z[0] ^= (m & E1); 173 } 174 175 // P is the value with only bit i=1 set 176 public static void multiplyP8(int[] x) 177 { 178// for (int i = 8; i != 0; --i) 179// { 180// multiplyP(x); 181// } 182 183 int c = shiftRightN(x, 8); 184 x[0] ^= LOOKUP[c >>> 24]; 185 } 186 187 public static void multiplyP8(int[] x, int[] y) 188 { 189 int c = shiftRightN(x, 8, y); 190 y[0] ^= LOOKUP[c >>> 24]; 191 } 192 193 static int shiftRight(int[] x) 194 { 195// int c = 0; 196// for (int i = 0; i < 4; ++i) 197// { 198// int b = x[i]; 199// x[i] = (b >>> 1) | c; 200// c = b << 31; 201// } 202// return c; 203 204 int b = x[0]; 205 x[0] = b >>> 1; 206 int c = b << 31; 207 b = x[1]; 208 x[1] = (b >>> 1) | c; 209 c = b << 31; 210 b = x[2]; 211 x[2] = (b >>> 1) | c; 212 c = b << 31; 213 b = x[3]; 214 x[3] = (b >>> 1) | c; 215 return b << 31; 216 } 217 218 static int shiftRight(int[] x, int[] z) 219 { 220// int c = 0; 221// for (int i = 0; i < 4; ++i) 222// { 223// int b = x[i]; 224// z[i] = (b >>> 1) | c; 225// c = b << 31; 226// } 227// return c; 228 229 int b = x[0]; 230 z[0] = b >>> 1; 231 int c = b << 31; 232 b = x[1]; 233 z[1] = (b >>> 1) | c; 234 c = b << 31; 235 b = x[2]; 236 z[2] = (b >>> 1) | c; 237 c = b << 31; 238 b = x[3]; 239 z[3] = (b >>> 1) | c; 240 return b << 31; 241 } 242 243 static long shiftRight(long[] x) 244 { 245 long b = x[0]; 246 x[0] = b >>> 1; 247 long c = b << 63; 248 b = x[1]; 249 x[1] = (b >>> 1) | c; 250 return b << 63; 251 } 252 253 static long shiftRight(long[] x, long[] z) 254 { 255 long b = x[0]; 256 z[0] = b >>> 1; 257 long c = b << 63; 258 b = x[1]; 259 z[1] = (b >>> 1) | c; 260 return b << 63; 261 } 262 263 static int shiftRightN(int[] x, int n) 264 { 265// int c = 0, nInv = 32 - n; 266// for (int i = 0; i < 4; ++i) 267// { 268// int b = x[i]; 269// x[i] = (b >>> n) | c; 270// c = b << nInv; 271// } 272// return c; 273 274 int b = x[0], nInv = 32 - n; 275 x[0] = b >>> n; 276 int c = b << nInv; 277 b = x[1]; 278 x[1] = (b >>> n) | c; 279 c = b << nInv; 280 b = x[2]; 281 x[2] = (b >>> n) | c; 282 c = b << nInv; 283 b = x[3]; 284 x[3] = (b >>> n) | c; 285 return b << nInv; 286 } 287 288 static int shiftRightN(int[] x, int n, int[] z) 289 { 290// int c = 0, nInv = 32 - n; 291// for (int i = 0; i < 4; ++i) 292// { 293// int b = x[i]; 294// z[i] = (b >>> n) | c; 295// c = b << nInv; 296// } 297// return c; 298 299 int b = x[0], nInv = 32 - n; 300 z[0] = b >>> n; 301 int c = b << nInv; 302 b = x[1]; 303 z[1] = (b >>> n) | c; 304 c = b << nInv; 305 b = x[2]; 306 z[2] = (b >>> n) | c; 307 c = b << nInv; 308 b = x[3]; 309 z[3] = (b >>> n) | c; 310 return b << nInv; 311 } 312 313 public static void xor(byte[] x, byte[] y) 314 { 315 int i = 0; 316 do 317 { 318 x[i] ^= y[i]; ++i; 319 x[i] ^= y[i]; ++i; 320 x[i] ^= y[i]; ++i; 321 x[i] ^= y[i]; ++i; 322 } 323 while (i < 16); 324 } 325 326 public static void xor(byte[] x, byte[] y, int yOff, int yLen) 327 { 328 while (--yLen >= 0) 329 { 330 x[yLen] ^= y[yOff + yLen]; 331 } 332 } 333 334 public static void xor(byte[] x, byte[] y, byte[] z) 335 { 336 int i = 0; 337 do 338 { 339 z[i] = (byte)(x[i] ^ y[i]); ++i; 340 z[i] = (byte)(x[i] ^ y[i]); ++i; 341 z[i] = (byte)(x[i] ^ y[i]); ++i; 342 z[i] = (byte)(x[i] ^ y[i]); ++i; 343 } 344 while (i < 16); 345 } 346 347 public static void xor(int[] x, int[] y) 348 { 349 x[0] ^= y[0]; 350 x[1] ^= y[1]; 351 x[2] ^= y[2]; 352 x[3] ^= y[3]; 353 } 354 355 public static void xor(int[] x, int[] y, int[] z) 356 { 357 z[0] = x[0] ^ y[0]; 358 z[1] = x[1] ^ y[1]; 359 z[2] = x[2] ^ y[2]; 360 z[3] = x[3] ^ y[3]; 361 } 362 363 public static void xor(long[] x, long[] y) 364 { 365 x[0] ^= y[0]; 366 x[1] ^= y[1]; 367 } 368 369 public static void xor(long[] x, long[] y, long[] z) 370 { 371 z[0] = x[0] ^ y[0]; 372 z[1] = x[1] ^ y[1]; 373 } 374} 375