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