1 package org.bouncycastle.crypto.modes.gcm; 2 3 import org.bouncycastle.crypto.util.Pack; 4 5 public class Tables8kGCMMultiplier implements GCMMultiplier 6 { 7 private final int[][][] M = new int[32][16][]; 8 init(byte[] H)9 public void init(byte[] H) 10 { 11 M[0][0] = new int[4]; 12 M[1][0] = new int[4]; 13 M[1][8] = GCMUtil.asInts(H); 14 15 for (int j = 4; j >= 1; j >>= 1) 16 { 17 int[] tmp = new int[4]; 18 System.arraycopy(M[1][j + j], 0, tmp, 0, 4); 19 20 GCMUtil.multiplyP(tmp); 21 M[1][j] = tmp; 22 } 23 24 { 25 int[] tmp = new int[4]; 26 System.arraycopy(M[1][1], 0, tmp, 0, 4); 27 28 GCMUtil.multiplyP(tmp); 29 M[0][8] = tmp; 30 } 31 32 for (int j = 4; j >= 1; j >>= 1) 33 { 34 int[] tmp = new int[4]; 35 System.arraycopy(M[0][j + j], 0, tmp, 0, 4); 36 37 GCMUtil.multiplyP(tmp); 38 M[0][j] = tmp; 39 } 40 41 int i = 0; 42 for (;;) 43 { 44 for (int j = 2; j < 16; j += j) 45 { 46 for (int k = 1; k < j; ++k) 47 { 48 int[] tmp = new int[4]; 49 System.arraycopy(M[i][j], 0, tmp, 0, 4); 50 51 GCMUtil.xor(tmp, M[i][k]); 52 M[i][j + k] = tmp; 53 } 54 } 55 56 if (++i == 32) 57 { 58 return; 59 } 60 61 if (i > 1) 62 { 63 M[i][0] = new int[4]; 64 for(int j = 8; j > 0; j >>= 1) 65 { 66 int[] tmp = new int[4]; 67 System.arraycopy(M[i - 2][j], 0, tmp, 0, 4); 68 69 GCMUtil.multiplyP8(tmp); 70 M[i][j] = tmp; 71 } 72 } 73 } 74 } 75 multiplyH(byte[] x)76 public void multiplyH(byte[] x) 77 { 78 // assert x.Length == 16; 79 80 int[] z = new int[4]; 81 for (int i = 15; i >= 0; --i) 82 { 83 // GCMUtil.xor(z, M[i + i][x[i] & 0x0f]); 84 int[] m = M[i + i][x[i] & 0x0f]; 85 z[0] ^= m[0]; 86 z[1] ^= m[1]; 87 z[2] ^= m[2]; 88 z[3] ^= m[3]; 89 // GCMUtil.xor(z, M[i + i + 1][(x[i] & 0xf0) >>> 4]); 90 m = M[i + i + 1][(x[i] & 0xf0) >>> 4]; 91 z[0] ^= m[0]; 92 z[1] ^= m[1]; 93 z[2] ^= m[2]; 94 z[3] ^= m[3]; 95 } 96 97 Pack.intToBigEndian(z[0], x, 0); 98 Pack.intToBigEndian(z[1], x, 4); 99 Pack.intToBigEndian(z[2], x, 8); 100 Pack.intToBigEndian(z[3], x, 12); 101 } 102 } 103