Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Re-licensed under Apache 2 license with Thomas Mueller permission
   *
   * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
   * Version 1.0, and under the Eclipse Public License, Version 1.0
   * (http://h2database.com/html/license.html).
   * Initial Developer: H2 Group
   */
  package org.mapdb;
 
 
An implementation of the EncryptionXTEA block cipher algorithm.

This implementation uses 32 rounds. The best attack reported as of 2009 is 36 rounds (Wikipedia).

It requires 32 byte long encryption key, so SHA256 password hash is used.

 
 public final class EncryptionXTEA{

    
Blocks sizes are always multiples of this number.
 
     public static final int ALIGN = 16;
 
     private static final int DELTA = 0x9E3779B9;
     private final int k0k1k2k3k4k5k6k7k8k9k10k11k12k13k14k15;
     private final int k16k17k18k19k20k21k22k23k24k25k26k27k28k29k30k31;
 
 
     public EncryptionXTEA(byte[] password) {
         byte[] b = getHash(passwordfalse);
         int[] key = new int[4];
         for (int i = 0; i < 16;) {
             key[i / 4] = (b[i++] << 24) + ((b[i++] & 255) << 16) + ((b[i++] & 255) << 8) + (b[i++] & 255);
         }
         int[] r = new int[32];
         for (int i = 0, sum = 0; i < 32;) {
             r[i++] = sum + key[sum & 3];
             sum += ;
             r[i++] = sum + key[ (sum >>> 11) & 3];
         }
          = r[0];  = r[1];  = r[2];  = r[3];  = r[4];  = r[5];  = r[6];  = r[7];
          = r[8];  = r[9];  = r[10];  = r[11];  = r[12];  = r[13];  = r[14];  = r[15];
          = r[16];  = r[17];  = r[18];  = r[19];  = r[20];  = r[21];  = r[22];  = r[23];
          = r[24];  = r[25];  = r[26];  = r[27];  = r[28];  = r[29];  = r[30];  = r[31];
     }
 
 
     public void encrypt(byte[] bytesint offint len) {
         if (len %  != 0) {
             throw new InternalError("unaligned len " + len);
         }
         for (int i = offi < off + leni += 8) {
             encryptBlock(bytesbytesi);
         }
     }
 
     public void decrypt(byte[] bytesint offint len) {
         if (len %  != 0) {
             throw new InternalError("unaligned len " + len);
         }
         for (int i = offi < off + leni += 8) {
             decryptBlock(bytesbytesi);
         }
     }
 
     private void encryptBlock(byte[] inbyte[] outint off) {
         int y = (in[off] << 24) | ((in[off+1] & 255) << 16) | ((in[off+2] & 255) << 8) | (in[off+3] & 255);
         int z = (in[off+4] << 24) | ((in[off+5] & 255) << 16) | ((in[off+6] & 255) << 8) | (in[off+7] & 255);
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         y += (((z << 4) ^ (z >>> 5)) + z) ^ z += (((y >>> 5) ^ (y << 4)) + y) ^ ;
         out[off] = (byte) (y >> 24); out[off+1] = (byte) (y >> 16); out[off+2] = (byte) (y >> 8); out[off+3] = (bytey;
         out[off+4] = (byte) (z >> 24); out[off+5] = (byte) (z >> 16); out[off+6] = (byte) (z >> 8); out[off+7] = (bytez;
     }
 
     private void decryptBlock(byte[] inbyte[] outint off) {
         int y = (in[off] << 24) | ((in[off+1] & 255) << 16) | ((in[off+2] & 255) << 8) | (in[off+3] & 255);
         int z = (in[off+4] << 24) | ((in[off+5] & 255) << 16) | ((in[off+6] & 255) << 8) | (in[off+7] & 255);
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        z -= (((y >>> 5) ^ (y << 4)) + y) ^ y -= (((z << 4) ^ (z >>> 5)) + z) ^ ;
        out[off] = (byte) (y >> 24); out[off+1] = (byte) (y >> 16); out[off+2] = (byte) (y >> 8); out[off+3] = (bytey;
        out[off+4] = (byte) (z >> 24); out[off+5] = (byte) (z >> 16); out[off+6] = (byte) (z >> 8); out[off+7] = (bytez;
    }


    
The first 32 bits of the fractional parts of the cube roots of the first sixty-four prime numbers. Used for SHA256 password hash
    private static final int[] K = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
            0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98,
            0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
            0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6,
            0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
            0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3,
            0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138,
            0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e,
            0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
            0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116,
            0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
            0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814,
            0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };


    
Calculate the hash code for the given data.

Parameters:
data the data to hash
nullData if the data should be filled with zeros after calculating the hash code
Returns:
the hash code
    public static byte[] getHash(byte[] databoolean nullData) {
        int byteLen = data.length;
        int intLen = ((byteLen + 9 + 63) / 64) * 16;
        byte[] bytes = new byte[intLen * 4];
        System.arraycopy(data, 0, bytes, 0, byteLen);
        if (nullData) {
            Arrays.fill(data, (byte) 0);
        }
        bytes[byteLen] = (byte) 0x80;
        int[] buff = new int[intLen];
        for (int i = 0, j = 0; j < intLeni += 4, j++) {
            buff[j] = readInt(bytesi);
        }
        buff[intLen - 2] = byteLen >>> 29;
        buff[intLen - 1] = byteLen << 3;
        int[] w = new int[64];
        int[] hh = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
                0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
        for (int block = 0; block < intLenblock += 16) {
            for (int i = 0; i < 16; i++) {
                w[i] = buff[block + i];
            }
            for (int i = 16; i < 64; i++) {
                int x = w[i - 2];
                int theta1 = rot(x, 17) ^ rot(x, 19) ^ (x >>> 10);
                x = w[i - 15];
                int theta0 = rot(x, 7) ^ rot(x, 18) ^ (x >>> 3);
                w[i] = theta1 + w[i - 7] + theta0 + w[i - 16];
            }
            int a = hh[0], b = hh[1], c = hh[2], d = hh[3];
            int e = hh[4], f = hh[5], g = hh[6], h = hh[7];
            for (int i = 0; i < 64; i++) {
                int t1 = h + (rot(e, 6) ^ rot(e, 11) ^ rot(e, 25))
                        + ((e & f) ^ ((~e) & g)) + [i] + w[i];
                int t2 = (rot(a, 2) ^ rot(a, 13) ^ rot(a, 22))
                        + ((a & b) ^ (a & c) ^ (b & c));
                h = g;
                g = f;
                f = e;
                e = d + t1;
                d = c;
                c = b;
                b = a;
                a = t1 + t2;
            }
            hh[0] += a;
            hh[1] += b;
            hh[2] += c;
            hh[3] += d;
            hh[4] += e;
            hh[5] += f;
            hh[6] += g;
            hh[7] += h;
        }
        byte[] result = new byte[32];
        for (int i = 0; i < 8; i++) {
            writeInt(resulti * 4, hh[i]);
        }
        Arrays.fill(w, 0);
        Arrays.fill(buff, 0);
        Arrays.fill(hh, 0);
        Arrays.fill(bytes, (byte) 0);
        return result;
    }
    private static int rot(int iint count) {
        return (i << (32 - count)) | (i >>> count);
    }
    private static int readInt(byte[] bint i) {
        return ((b[i] & 0xff) << 24) + ((b[i + 1] & 0xff) << 16)
                + ((b[i + 2] & 0xff) << 8) + (b[i + 3] & 0xff);
    }
    private static void writeInt(byte[] bint iint value) {
        b[i] = (byte) (value >> 24);
        b[i + 1] = (byte) (value >> 16);
        b[i + 2] = (byte) (value >> 8);
        b[i + 3] = (bytevalue;
    }
New to GrepCode? Check out our FAQ X