Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.bouncycastle.crypto.test;
  
  
  import  junit.framework.TestCase;
 
 public class GCMReorderTest
     extends TestCase
 {
     private static final byte[] H;
     private static final SecureRandom random = new SecureRandom(); 
     private static final GCMMultiplier mul = new Tables64kGCMMultiplier();
     private static final GCMExponentiator exp = new Tables1kGCMExponentiator();
     private static final byte[] EMPTY = new byte[0];
 
     static
     {
          = new byte[16];
         .nextBytes();
         .init(Arrays.clone());
         .init(Arrays.clone());
     }
 
     public void testCombine() throws Exception
     {
         for (int count = 0; count < 10; ++count)
         {
             byte[] A = randomBytes(1000);
             byte[] C = randomBytes(1000);
 
             byte[] ghashA_ = GHASH(A);
             byte[] ghash_C = GHASH(C);
             byte[] ghashAC = GHASH(AC);
 
             byte[] ghashCombine = combine_GHASH(ghashA_, (long)A.length * 8, ghash_C, (long)C.length * 8);
 
             assertTrue(Arrays.areEqual(ghashACghashCombine));
         }
     }
 
     public void testConcatAuth() throws Exception
     {
         for (int count = 0; count < 10; ++count)
         {
             byte[] P = randomBlocks(100);
             byte[] A = randomBytes(1000);
             byte[] PA = concatArrays(PA);
 
             byte[] ghashP_ = GHASH(P);
             byte[] ghashA_ = GHASH(A);
             byte[] ghashPA_ = GHASH(PA);
             byte[] ghashConcat = concatAuth_GHASH(ghashP_, (long)P.length * 8, ghashA_, (long)A.length * 8);
 
             assertTrue(Arrays.areEqual(ghashPA_ghashConcat));
         }
     }
 
     public void testConcatCrypt() throws Exception
     {
         for (int count = 0; count < 10; ++count)
         {
             byte[] P = randomBlocks(100);
             byte[] A = randomBytes(1000);
             byte[] PA = concatArrays(PA);
     
             byte[] ghash_P = GHASH(P);
             byte[] ghash_A = GHASH(A);
             byte[] ghash_PA = GHASH(PA);
             byte[] ghashConcat = concatCrypt_GHASH(ghash_P, (long)P.length * 8, ghash_A, (long)A.length * 8);
 
             assertTrue(Arrays.areEqual(ghash_PAghashConcat));
         }
     }
 
     public void testExp()
     {
         {
             byte[] buf1 = new byte[16];
             buf1[0] = (byte)0x80;
     
             byte[] buf2 = new byte[16];
     
             for (int pow = 0; pow != 100; ++pow)
             {
                 .exponentiateX(powbuf2);
     
                 assertTrue(Arrays.areEqual(buf1buf2));
 
                 .multiplyH(buf1);
             }
         }
        long[] testPow = new long[]{ 10, 1, 8, 17, 24, 13, 2, 13, 2, 3 };
        byte[][] testData = new byte[][]{
            Hex.decode("9185848a877bd87ba071e281f476e8e7"),
            Hex.decode("697ce3052137d80745d524474fb6b290"),
            Hex.decode("2696fc47198bb23b11296e4f88720a17"),
            Hex.decode("01f2f0ead011a4ae0cf3572f1b76dd8e"),
            Hex.decode("a53060694a044e4b7fa1e661c5a7bb6b"),
            Hex.decode("39c0392e8b6b0e04a7565c85394c2c4c"),
            Hex.decode("519c362d502e07f2d8b7597a359a5214"),
            Hex.decode("5a527a393675705e19b2117f67695af4"),
            Hex.decode("27fc0901d1d332a53ba4d4386c2109d2"),
            Hex.decode("93ca9b57174aabedf8220e83366d7df6"),
        };
        for (int i = 0; i != 10; ++i)
        {
            long pow = testPow[i];
            byte[] data = Arrays.clone(testData[i]);
            byte[] expected = Arrays.clone(data);
            for (int j = 0; j < pow; ++j)
            {
                .multiplyH(expected);
            }
            byte[] H_a = new byte[16];
            .exponentiateX(powH_a);
            byte[] actual = multiply(dataH_a);
            assertTrue(Arrays.areEqual(expectedactual));
        }
    }
    public void testMultiply()
    {
        byte[] expected = Arrays.clone();
        .multiplyH(expected);
        assertTrue(Arrays.areEqual(expectedmultiply()));
        for (int count = 0; count < 10; ++count)
        {
            byte[] a = new byte[16];
            .nextBytes(a);
            byte[] b = new byte[16];
            .nextBytes(b);
            expected = Arrays.clone(a);
            .multiplyH(expected);
            assertTrue(Arrays.areEqual(expectedmultiply(a)));
            assertTrue(Arrays.areEqual(expectedmultiply(a)));
            expected = Arrays.clone(b);
            .multiplyH(expected);
            assertTrue(Arrays.areEqual(expectedmultiply(b)));
            assertTrue(Arrays.areEqual(expectedmultiply(b)));
            assertTrue(Arrays.areEqual(multiply(ab), multiply(ba)));
        }
    }
    private byte[] randomBlocks(int upper)
    {
        byte[] bs = new byte[16 * .nextInt(upper)];
        .nextBytes(bs);
        return bs;
    }
    private byte[] randomBytes(int upper)
    {
        byte[] bs = new byte[.nextInt(upper)];
        .nextBytes(bs);
        return bs;
    }
    private byte[] concatArrays(byte[] abyte[] bthrows IOException
    {
        byte[] ab = new byte[a.length + b.length];
        System.arraycopy(a, 0, ab, 0, a.length);
        System.arraycopy(b, 0, aba.lengthb.length);
        return ab;
    }
    private byte[] combine_GHASH(byte[] ghashA_long bitlenAbyte[] ghash_Clong bitlenC)
    {
        // Note: bitlenA must be aligned to the block size
        long c = (bitlenC + 127) >>> 7;
        byte[] H_c = new byte[16];
        .exponentiateX(cH_c);
        byte[] tmp1 = lengthBlock(bitlenA, 0);
        .multiplyH(tmp1);
        byte[] ghashAC = Arrays.clone(ghashA_);
        xor(ghashACtmp1);
        ghashAC = multiply(ghashACH_c);
        // No need to touch the len(C) part (second 8 bytes)
        xor(ghashACtmp1);
        xor(ghashACghash_C);
        return ghashAC;
    }
    private byte[] concatAuth_GHASH(byte[] ghashPlong bitlenPbyte[] ghashAlong bitlenA)
    {
        // Note: bitlenP must be aligned to the block size
        long a = (bitlenA + 127) >>> 7;
        byte[] tmp1 = lengthBlock(bitlenP, 0);
        .multiplyH(tmp1);
        byte[] tmp2 = lengthBlock(bitlenA ^ (bitlenP + bitlenA), 0);
        .multiplyH(tmp2);
        byte[] H_a = new byte[16];
        .exponentiateX(aH_a);
        
        byte[] ghashC = Arrays.clone(ghashP);
        xor(ghashCtmp1);
        ghashC = multiply(ghashCH_a);
        xor(ghashCtmp2);
        xor(ghashCghashA);
        return ghashC;
    }
    private byte[] concatCrypt_GHASH(byte[] ghashPlong bitlenPbyte[] ghashAlong bitlenA)
    {
        // Note: bitlenP must be aligned to the block size
        long a = (bitlenA + 127) >>> 7;
        byte[] tmp1 = lengthBlock(0, bitlenP);
        .multiplyH(tmp1);
        byte[] tmp2 = lengthBlock(0, bitlenA ^ (bitlenP + bitlenA));
        .multiplyH(tmp2);
        byte[] H_a = new byte[16];
        .exponentiateX(aH_a);
        
        byte[] ghashC = Arrays.clone(ghashP);
        xor(ghashCtmp1);
        ghashC = multiply(ghashCH_a);
        xor(ghashCtmp2);
        xor(ghashCghashA);
        return ghashC;
    }
    private byte[] GHASH(byte[] Abyte[] C)
    {
        byte[] X = new byte[16];
        {
            for (int pos = 0; pos < A.lengthpos += 16)
            {
                byte[] tmp = new byte[16];
                int num = Math.min(A.length - pos, 16);
                System.arraycopy(Apostmp, 0, num);
                xor(Xtmp);
                .multiplyH(X);
            }
        }
        {
            for (int pos = 0; pos < C.lengthpos += 16)
            {
                byte[] tmp = new byte[16];
                int num = Math.min(C.length - pos, 16);
                System.arraycopy(Cpostmp, 0, num);
                xor(Xtmp);
                .multiplyH(X);
            }
        }
        {
            xor(XlengthBlock((long)A.length * 8, (long)C.length * 8));
            .multiplyH(X);
        }
        return X;
    }
    private static byte[] lengthBlock(long bitlenAlong bitlenC)
    {
        byte[] tmp = new byte[16];
        Pack.longToBigEndian(bitlenAtmp, 0);
        Pack.longToBigEndian(bitlenCtmp, 8);
        return tmp;
    }
    private static void xor(byte[] blockbyte[] val)
    {
        for (int i = 15; i >= 0; --i)
        {
            block[i] ^= val[i];
        }
    }
    private static byte[] multiply(byte[] abyte[] b)
    {
        byte[] c = new byte[16];
        byte[] tmp = Arrays.clone(b);
        for (int i = 0; i < 16; ++i)
        {
            byte bits = a[i];
            for (int j = 7; j >= 0; --j)
            {
                if ((bits & (1 << j)) != 0)
                {
                    xor(ctmp);
                }
                boolean lsb = (tmp[15] & 1) != 0;
                shiftRight(tmp);
                if (lsb)
                {
                    // R = new byte[]{ 0xe1, ... };
//                    GCMUtil.xor(v, R);
                    tmp[0] ^= (byte)0xe1;
                }
            }
        }
        return c;
    }
    private static void shiftRight(byte[] block)
    {
        int i = 0;
        int bit = 0;
        for (;;)
        {
            int b = block[i] & 0xff;
            block[i] = (byte) ((b >>> 1) | bit);
            if (++i == 16)
            {
                break;
            }
            bit = (b & 1) << 7;
        }
    }
New to GrepCode? Check out our FAQ X