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