java/src/main/java/com/genexus/util/Rijndael_Algorithm.java
/**
     * Decrypt exactly one block of ciphertext.
     *
     * @param  in         The ciphertext.
     * @param  result     The resulting ciphertext.
     * @param  inOffset   Index of in from which to start considering data.
     * @param  sessionKey The session key to use for decryption.
     * @param  blockSize  The block size in bytes of this Rijndael.
     */
Decrypt exactly one block of ciphertext.
@param  in         The ciphertext.
@param  result     The resulting ciphertext.
@param  inOffset   Index of in from which to start considering data.
@param  sessionKey The session key to use for decryption.
@param  blockSize  The block size in bytes of this Rijndael.
Decrypt exactly one block of ciphertext . @param in The ciphertext . @param result The resulting ciphertext . @param inOffset Index of in from which to start considering data . @param sessionKey The session key to use for decryption . @param blockSize The block size in bytes of this Rijndael .
public static final void
    blockDecrypt (byte[] in, byte[] result, int inOffset, Object sessionKey, int blockSize) {
        if (blockSize == BLOCK_SIZE) {
            blockDecrypt(in, result, inOffset, sessionKey);
            return;
        }
if (RDEBUG) trace(IN, "blockDecrypt("+in+", "+inOffset+", "+sessionKey+", "+blockSize+")");
        Object[] sKey = (Object[]) sessionKey; 
        int[][] Kd = (int[][]) sKey[1];
        int BC = blockSize / 4;
        int ROUNDS = Kd.length - 1;
        int SC = BC == 4 ? 0 : (BC == 6 ? 1 : 2);
        int s1 = shifts[SC][1][1];
        int s2 = shifts[SC][2][1];
        int s3 = shifts[SC][3][1];
        int[] a = new int[BC];
        int[] t = new int[BC]; 
        int i;
        int j = 0, tt;
        for (i = 0; i < BC; i++)                   
            t[i] = ((in[inOffset++] & 0xFF) << 24 |
                    (in[inOffset++] & 0xFF) << 16 |
                    (in[inOffset++] & 0xFF) <<  8 |
                    (in[inOffset++] & 0xFF)        ) ^ Kd[0][i];
        for (int r = 1; r < ROUNDS; r++) {          
            for (i = 0; i < BC; i++)
                a[i] = (T5[(t[ i           ] >>> 24) & 0xFF] ^
                        T6[(t[(i + s1) % BC] >>> 16) & 0xFF] ^
                        T7[(t[(i + s2) % BC] >>>  8) & 0xFF] ^
                        T8[ t[(i + s3) % BC]         & 0xFF]  ) ^ Kd[r][i];
            System.arraycopy(a, 0, t, 0, BC);
if (RDEBUG && debuglevel > 6) System.out.println("PT"+r+"="+toString(t));
        }
        for (i = 0; i < BC; i++) {                   
            tt = Kd[ROUNDS][i];
            result[j++] = (byte)(Si[(t[ i           ] >>> 24) & 0xFF] ^ (tt >>> 24));
            result[j++] = (byte)(Si[(t[(i + s1) % BC] >>> 16) & 0xFF] ^ (tt >>> 16));
            result[j++] = (byte)(Si[(t[(i + s2) % BC] >>>  8) & 0xFF] ^ (tt >>>  8));
            result[j++] = (byte)(Si[ t[(i + s3) % BC]         & 0xFF] ^ tt);
        }
if (RDEBUG && debuglevel > 6) {
System.out.println("PT="+toString(result));
System.out.println();
}
if (RDEBUG) trace(OUT, "blockDecrypt()");
    }
public static final void blockDecrypt ( byte [ ] in , byte [ ] result , int inOffset , Object sessionKey , int blockSize ) { if ( blockSize == BLOCK_SIZE ) { blockDecrypt ( in , result , inOffset , sessionKey ) ; return ; } if ( RDEBUG ) trace ( IN , "blockDecrypt(" + in + ", " + inOffset + ", " + sessionKey + ", " + blockSize + ")" ) ; Object [ ] sKey = ( Object [ ] ) sessionKey ; int [ ] [ ] Kd = ( int [ ] [ ] ) sKey [ 1 ] ; int BC = blockSize / 4 ; int ROUNDS = Kd . length - 1 ; int SC = BC == 4 ? 0 : ( BC == 6 ? 1 : 2 ) ; int s1 = shifts [ SC ] [ 1 ] [ 1 ] ; int s2 = shifts [ SC ] [ 2 ] [ 1 ] ; int s3 = shifts [ SC ] [ 3 ] [ 1 ] ; int [ ] a = new int [ BC ] ; int [ ] t = new int [ BC ] ; int i ; int j = 0 , tt ; for ( i = 0 ; i < BC ; i ++ ) t [ i ] = ( ( in [ inOffset ++ ] & 0xFF ) << 24 | ( in [ inOffset ++ ] & 0xFF ) << 16 | ( in [ inOffset ++ ] & 0xFF ) << 8 | ( in [ inOffset ++ ] & 0xFF ) ) ^ Kd [ 0 ] [ i ] ; for ( int r = 1 ; r < ROUNDS ; r ++ ) { for ( i = 0 ; i < BC ; i ++ ) a [ i ] = ( T5 [ ( t [ i ] >>> 24 ) & 0xFF ] ^ T6 [ ( t [ ( i + s1 ) % BC ] >>> 16 ) & 0xFF ] ^ T7 [ ( t [ ( i + s2 ) % BC ] >>> 8 ) & 0xFF ] ^ T8 [ t [ ( i + s3 ) % BC ] & 0xFF ] ) ^ Kd [ r ] [ i ] ; System . arraycopy ( a , 0 , t , 0 , BC ) ; if ( RDEBUG && debuglevel > 6 ) System . out . println ( "PT" + r + "=" + toString ( t ) ) ; } for ( i = 0 ; i < BC ; i ++ ) { tt = Kd [ ROUNDS ] [ i ] ; result [ j ++ ] = ( byte ) ( Si [ ( t [ i ] >>> 24 ) & 0xFF ] ^ ( tt >>> 24 ) ) ; result [ j ++ ] = ( byte ) ( Si [ ( t [ ( i + s1 ) % BC ] >>> 16 ) & 0xFF ] ^ ( tt >>> 16 ) ) ; result [ j ++ ] = ( byte ) ( Si [ ( t [ ( i + s2 ) % BC ] >>> 8 ) & 0xFF ] ^ ( tt >>> 8 ) ) ; result [ j ++ ] = ( byte ) ( Si [ t [ ( i + s3 ) % BC ] & 0xFF ] ^ tt ) ; } if ( RDEBUG && debuglevel > 6 ) { System . out . println ( "PT=" + toString ( result ) ) ; System . out . println ( ) ; } if ( RDEBUG ) trace ( OUT , "blockDecrypt()" ) ; }
Decrypt exactly one block of ciphertext.
Decrypt exactly one block of ciphertext .
// extract decryption round keys // temporary work array // ciphertext to ints + key // apply round transforms // last round is special