/* Anubis.java -- 
   Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.

This file is a part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version.  */


package gnu.javax.crypto.cipher;

import gnu.java.security.Configuration;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;

import java.security.InvalidKeyException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.logging.Logger;

/**
 * Anubis is a 128-bit block cipher that accepts a variable-length key. The
 * cipher is a uniform substitution-permutation network whose inverse only
 * differs from the forward operation in the key schedule. The design of both
 * the round transformation and the key schedule is based upon the Wide Trail
 * strategy and permits a wide variety of implementation trade-offs.
 * <p>
 * References:
 * <ol>
 * <li><a
 * href="http://planeta.terra.com.br/informatica/paulobarreto/AnubisPage.html">The
 * ANUBIS Block Cipher</a>.<br>
 * <a href="mailto:paulo.barreto@terra.com.br">Paulo S.L.M. Barreto</a> and <a
 * href="mailto:vincent.rijmen@esat.kuleuven.ac.be">Vincent Rijmen</a>.</li>
 * </ol>
 */
public final class Anubis
    extends BaseCipher
{
  private static final Logger log = Logger.getLogger(Anubis.class.getName());
  private static final int DEFAULT_BLOCK_SIZE = 16; // in bytes
  private static final int DEFAULT_KEY_SIZE = 16; // in bytes
  private static final String Sd = // p. 25 [ANUBIS]
      "\uBA54\u2F74\u53D3\uD24D\u50AC\u8DBF\u7052\u9A4C"
    + "\uEAD5\u97D1\u3351\u5BA6\uDE48\uA899\uDB32\uB7FC"
    + "\uE39E\u919B\uE2BB\u416E\uA5CB\u6B95\uA1F3\uB102"
    + "\uCCC4\u1D14\uC363\uDA5D\u5FDC\u7DCD\u7F5A\u6C5C"
    + "\uF726\uFFED\uE89D\u6F8E\u19A0\uF089\u0F07\uAFFB"
    + "\u0815\u0D04\u0164\uDF76\u79DD\u3D16\u3F37\u6D38"
    + "\uB973\uE935\u5571\u7B8C\u7288\uF62A\u3E5E\u2746"
    + "\u0C65\u6861\u03C1\u57D6\uD958\uD866\uD73A\uC83C"
    + "\uFA96\uA798\uECB8\uC7AE\u694B\uABA9\u670A\u47F2"
    + "\uB522\uE5EE\uBE2B\u8112\u831B\u0E23\uF545\u21CE"
    + "\u492C\uF9E6\uB628\u1782\u1A8B\uFE8A\u09C9\u874E"
    + "\uE12E\uE4E0\uEB90\uA41E\u8560\u0025\uF4F1\u940B"
    + "\uE775\uEF34\u31D4\uD086\u7EAD\uFD29\u303B\u9FF8"
    + "\uC613\u0605\uC511\u777C\u7A78\u361C\u3959\u1856"
    + "\uB3B0\u2420\uB292\uA3C0\u4462\u10B4\u8443\u93C2"
    + "\u4ABD\u8F2D\uBC9C\u6A40\uCFA2\u804F\u1FCA\uAA42";
  private static final byte[] S = new byte[256];
  private static final int[] T0 = new int[256];
  private static final int[] T1 = new int[256];
  private static final int[] T2 = new int[256];
  private static final int[] T3 = new int[256];
  private static final int[] T4 = new int[256];
  private static final int[] T5 = new int[256];
  /**
   * Anubis round constants. This is the largest possible considering that we
   * always use R values, R = 8 + N, and 4 &lt;= N &lt;= 10.
   */
  private static final int[] rc = new int[18];
  /**
   * KAT vector (from ecb_vk): I=83
   * KEY=000000000000000000002000000000000000000000000000
   * CT=2E66AB15773F3D32FB6C697509460DF4
   */
  private static final byte[] KAT_KEY =
      Util.toBytesFromString("000000000000000000002000000000000000000000000000");
  private static final byte[] KAT_CT =
      Util.toBytesFromString("2E66AB15773F3D32FB6C697509460DF4");
  /** caches the result of the correctness test, once executed. */
  private static Boolean valid;

  static
    {
      long time = System.currentTimeMillis();
      int ROOT = 0x11d; // para. 2.1 [ANUBIS]
      int i, s, s2, s4, s6, s8, t;
      char c;
      for (i = 0; i < 256; i++)
        {
          c = Sd.charAt(i >>> 1);
          s = ((i & 1) == 0 ? c >>> 8 : c) & 0xFF;
          S[i] = (byte) s;
          s2 = s << 1;
          if (s2 > 0xFF)
            s2 ^= ROOT;
          s4 = s2 << 1;
          if (s4 > 0xFF)
            s4 ^= ROOT;
          s6 = s4 ^ s2;
          s8 = s4 << 1;
          if (s8 > 0xFF)
            s8 ^= ROOT;
          T0[i] = s  << 24 | s2 << 16 | s4 << 8 | s6;
          T1[i] = s2 << 24 | s  << 16 | s6 << 8 | s4;
          T2[i] = s4 << 24 | s6 << 16 | s  << 8 | s2;
          T3[i] = s6 << 24 | s4 << 16 | s2 << 8 | s;
          T4[i] = s  << 24 | s  << 16 | s  << 8 | s;
          T5[s] = s  << 24 | s2 << 16 | s6 << 8 | s8;
        }
      // compute round constant
      for (i = 0, s = 0; i < 18;)
        rc[i++] =  S[(s++) & 0xFF]         << 24
                | (S[(s++) & 0xFF] & 0xFF) << 16
                | (S[(s++) & 0xFF] & 0xFF) << 8
                | (S[(s++) & 0xFF] & 0xFF);
      time = System.currentTimeMillis() - time;
      if (Configuration.DEBUG)
        {
          log.fine("Static data");
          log.fine("T0[]:");
          StringBuilder sb;
          for (i = 0; i < 64; i++)
            {
              sb = new StringBuilder();
              for (t = 0; t < 4; t++)
                sb.append("0x").append(Util.toString(T0[i * 4 + t])).append(", ");
              log.fine(sb.toString());
            }
          log.fine("T1[]:");
          for (i = 0; i < 64; i++)
            {
              sb = new StringBuilder();
              for (t = 0; t < 4; t++)
                sb.append("0x").append(Util.toString(T1[i * 4 + t])).append(", ");
              log.fine(sb.toString());
            }
          log.fine("T2[]:");
          for (i = 0; i < 64; i++)
            {
              sb = new StringBuilder();
              for (t = 0; t < 4; t++)
                sb.append("0x").append(Util.toString(T2[i * 4 + t])).append(", ");
              log.fine(sb.toString());
            }
          log.fine("T3[]:");
          for (i = 0; i < 64; i++)
            {
              sb = new StringBuilder();
              for (t = 0; t < 4; t++)
                sb.append("0x").append(Util.toString(T3[i * 4 + t])).append(", ");
              log.fine(sb.toString());
            }
          log.fine("T4[]:");
          for (i = 0; i < 64; i++)
            {
              sb = new StringBuilder();
              for (t = 0; t < 4; t++)
                sb.append("0x").append(Util.toString(T4[i * 4 + t])).append(", ");
              log.fine(sb.toString());
            }
          log.fine("T5[]:");
          for (i = 0; i < 64; i++)
            {
              sb = new StringBuilder();
              for (t = 0; t < 4; t++)
                sb.append("0x").append(Util.toString(T5[i * 4 + t])).append(", ");
              log.fine(sb.toString());
            }
          log.fine("rc[]:");
          for (i = 0; i < 18; i++)
            log.fine("0x" + Util.toString(rc[i]));
          log.fine("Total initialization time: " + time + " ms.");
        }
    }

  /** Trivial 0-arguments constructor. */
  public Anubis()
  {
    super(Registry.ANUBIS_CIPHER, DEFAULT_BLOCK_SIZE, DEFAULT_KEY_SIZE);
  }

  private static void anubis(byte[] in, int i, byte[] out, int j, int[][] K)
  {
    // extract encryption round keys
    int R = K.length - 1;
    int[] Ker = K[0];
    // mu function + affine key addition
    int a0 = (in[i++]         << 24
           | (in[i++] & 0xFF) << 16
           | (in[i++] & 0xFF) <<  8
           | (in[i++] & 0xFF)      ) ^ Ker[0];
    int a1 = (in[i++]         << 24
           | (in[i++] & 0xFF) << 16
           | (in[i++] & 0xFF) <<  8
           | (in[i++] & 0xFF)      ) ^ Ker[1];
    int a2 = (in[i++]         << 24
           | (in[i++] & 0xFF) << 16
           | (in[i++] & 0xFF) <<  8
           | (in[i++] & 0xFF)      ) ^ Ker[2];
    int a3 = (in[i++]         << 24
           | (in[i++] & 0xFF) << 16
           | (in[i++] & 0xFF) <<  8
           | (in[i] & 0xFF)        ) ^ Ker[3];
    int b0, b1, b2, b3;
    // round function
    for (int r = 1; r < R; r++)
      {
        Ker = K[r];
        b0 = T0[ a0 >>> 24        ]
           ^ T1[ a1 >>> 24        ]
           ^ T2[ a2 >>> 24        ]
           ^ T3[ a3 >>> 24        ] ^ Ker[0];
        b1 = T0[(a0 >>> 16) & 0xFF]
           ^ T1[(a1 >>> 16) & 0xFF]
           ^ T2[(a2 >>> 16) & 0xFF]
           ^ T3[(a3 >>> 16) & 0xFF] ^ Ker[1];
        b2 = T0[(a0 >>>  8) & 0xFF]
           ^ T1[(a1 >>>  8) & 0xFF]
           ^ T2[(a2 >>>  8) & 0xFF]
           ^ T3[(a3 >>>  8) & 0xFF] ^ Ker[2];
        b3 = T0[ a0         & 0xFF]
           ^ T1[ a1         & 0xFF]
           ^ T2[ a2         & 0xFF]
           ^ T3[ a3         & 0xFF] ^ Ker[3];
        a0 = b0;
        a1 = b1;
        a2 = b2;
        a3 = b3;
        if (Configuration.DEBUG)
          log.fine("T" + r + "=" + Util.toString(a0) + Util.toString(a1)
                   + Util.toString(a2) + Util.toString(a3));
      }
    // last round function
    Ker = K[R];
    int tt = Ker[0];
    out[j++] = (byte)(S[ a0 >>> 24        ] ^ (tt >>> 24));
    out[j++] = (byte)(S[ a1 >>> 24        ] ^ (tt >>> 16));
    out[j++] = (byte)(S[ a2 >>> 24        ] ^ (tt >>> 8));
    out[j++] = (byte)(S[ a3 >>> 24        ] ^  tt);
    tt = Ker[1];
    out[j++] = (byte)(S[(a0 >>> 16) & 0xFF] ^ (tt >>> 24));
    out[j++] = (byte)(S[(a1 >>> 16) & 0xFF] ^ (tt >>> 16));
    out[j++] = (byte)(S[(a2 >>> 16) & 0xFF] ^ (tt >>> 8));
    out[j++] = (byte)(S[(a3 >>> 16) & 0xFF] ^  tt);
    tt = Ker[2];
    out[j++] = (byte)(S[(a0 >>>  8) & 0xFF] ^ (tt >>> 24));
    out[j++] = (byte)(S[(a1 >>>  8) & 0xFF] ^ (tt >>> 16));
    out[j++] = (byte)(S[(a2 >>>  8) & 0xFF] ^ (tt >>> 8));
    out[j++] = (byte)(S[(a3 >>>  8) & 0xFF] ^  tt);
    tt = Ker[3];
    out[j++] = (byte)(S[ a0         & 0xFF] ^ (tt >>> 24));
    out[j++] = (byte)(S[ a1         & 0xFF] ^ (tt >>> 16));
    out[j++] = (byte)(S[ a2         & 0xFF] ^ (tt >>> 8));
    out[j  ] = (byte)(S[ a3         & 0xFF] ^  tt);
    if (Configuration.DEBUG)
      log.fine("T=" + Util.toString(out, j - 15, 16) + "\n");
  }

  public Object clone()
  {
    Anubis result = new Anubis();
    result.currentBlockSize = this.currentBlockSize;

    return result;
  }

  public Iterator blockSizes()
  {
    ArrayList al = new ArrayList();
    al.add(Integer.valueOf(DEFAULT_BLOCK_SIZE));

    return Collections.unmodifiableList(al).iterator();
  }

  public Iterator keySizes()
  {
    ArrayList al = new ArrayList();
    for (int n = 4; n < 10; n++)
      al.add(Integer.valueOf(n * 32 / 8));
    return Collections.unmodifiableList(al).iterator();
  }

  /**
   * Expands a user-supplied key material into a session key for a designated
   * <i>block size</i>.
   * 
   * @param uk the 32N-bit user-supplied key material; 4 &lt;= N &lt;= 10.
   * @param bs the desired block size in bytes.
   * @return an Object encapsulating the session key.
   * @exception IllegalArgumentException if the block size is not 16 (128-bit).
   * @exception InvalidKeyException if the key data is invalid.
   */
  public Object makeKey(byte[] uk, int bs) throws InvalidKeyException
  {
    if (bs != DEFAULT_BLOCK_SIZE)
      throw new IllegalArgumentException();
    if (uk == null)
      throw new InvalidKeyException("Empty key");
    if ((uk.length % 4) != 0)
      throw new InvalidKeyException("Key is not multiple of 32-bit.");
    int N = uk.length / 4;
    if (N < 4 || N > 10)
      throw new InvalidKeyException("Key is not 32N; 4 <= N <= 10");
    int R = 8 + N;
    int[][] Ke = new int[R + 1][4]; // encryption round keys
    int[][] Kd = new int[R + 1][4]; // decryption round keys
    int[] tk = new int[N];
    int[] kk = new int[N];
    int r, i, j, k, k0, k1, k2, k3, tt;
    // apply mu to k0
    for (r = 0, i = 0; r < N;)
      tk[r++] =  uk[i++]         << 24
              | (uk[i++] & 0xFF) << 16
              | (uk[i++] & 0xFF) << 8
              | (uk[i++] & 0xFF);
    for (r = 0; r <= R; r++)
      {
        if (r > 0)
          {
            // psi = key evolution function
            kk[0] = T0[(tk[0    ] >>> 24)       ]
                  ^ T1[(tk[N - 1] >>> 16) & 0xFF]
                  ^ T2[(tk[N - 2] >>>  8) & 0xFF]
                  ^ T3[ tk[N - 3]         & 0xFF];
            kk[1] = T0[(tk[1    ] >>> 24)       ]
                  ^ T1[(tk[0    ] >>> 16) & 0xFF]
                  ^ T2[(tk[N - 1] >>>  8) & 0xFF]
                  ^ T3[ tk[N - 2]         & 0xFF];
            kk[2] = T0[(tk[2    ] >>> 24)       ]
                  ^ T1[(tk[1    ] >>> 16) & 0xFF]
                  ^ T2[(tk[0    ] >>>  8) & 0xFF]
                  ^ T3[ tk[N - 1]         & 0xFF];
            kk[3] = T0[(tk[3    ] >>> 24)       ]
                  ^ T1[(tk[2    ] >>> 16) & 0xFF]
                  ^ T2[(tk[1    ] >>>  8) & 0xFF]
                  ^ T3[ tk[0    ]         & 0xFF];
            for (i = 4; i < N; i++)
              kk[i] = T0[ tk[i    ] >>> 24        ]
                    ^ T1[(tk[i - 1] >>> 16) & 0xFF]
                    ^ T2[(tk[i - 2] >>>  8) & 0xFF]
                    ^ T3[ tk[i - 3]         & 0xFF];
            // apply sigma (affine addition) to round constant
            tk[0] = rc[r - 1] ^ kk[0];
            for (i = 1; i < N; i++)
              tk[i] = kk[i];
          }
        // phi = key selection function
        tt = tk[N - 1];
        k0 = T4[ tt >>> 24        ];
        k1 = T4[(tt >>> 16) & 0xFF];
        k2 = T4[(tt >>>  8) & 0xFF];
        k3 = T4[ tt         & 0xFF];
        for (k = N - 2; k >= 0; k--)
          {
            tt = tk[k];
            k0 =  T4[ tt >>> 24        ]
               ^ (T5[(k0 >>> 24) & 0xFF] & 0xFF000000)
               ^ (T5[(k0 >>> 16) & 0xFF] & 0x00FF0000)
               ^ (T5[(k0 >>>  8) & 0xFF] & 0x0000FF00)
               ^ (T5 [k0         & 0xFF] & 0x000000FF);
            k1 =  T4[(tt >>> 16) & 0xFF]
               ^ (T5[(k1 >>> 24) & 0xFF] & 0xFF000000)
               ^ (T5[(k1 >>> 16) & 0xFF] & 0x00FF0000)
               ^ (T5[(k1 >>>  8) & 0xFF] & 0x0000FF00)
               ^ (T5[ k1         & 0xFF] & 0x000000FF);
            k2 =  T4[(tt >>>  8) & 0xFF]
               ^ (T5[(k2 >>> 24) & 0xFF] & 0xFF000000)
               ^ (T5[(k2 >>> 16) & 0xFF] & 0x00FF0000)
               ^ (T5[(k2 >>>  8) & 0xFF] & 0x0000FF00)
               ^ (T5[ k2         & 0xFF] & 0x000000FF);
            k3 =  T4[ tt         & 0xFF]
               ^ (T5[(k3 >>> 24) & 0xFF] & 0xFF000000)
               ^ (T5[(k3 >>> 16) & 0xFF] & 0x00FF0000)
               ^ (T5[(k3 >>>  8) & 0xFF] & 0x0000FF00)
               ^ (T5[ k3         & 0xFF] & 0x000000FF);
          }
        Ke[r][0] = k0;
        Ke[r][1] = k1;
        Ke[r][2] = k2;
        Ke[r][3] = k3;
        if (r == 0 || r == R)
          {
            Kd[R - r][0] = k0;
            Kd[R - r][1] = k1;
            Kd[R - r][2] = k2;
            Kd[R - r][3] = k3;
          }
        else
          {
            Kd[R - r][0] = T0[S[ k0 >>> 24        ] & 0xFF]
                         ^ T1[S[(k0 >>> 16) & 0xFF] & 0xFF]
                         ^ T2[S[(k0 >>>  8) & 0xFF] & 0xFF]
                         ^ T3[S[ k0         & 0xFF] & 0xFF];
            Kd[R - r][1] = T0[S[ k1 >>> 24        ] & 0xFF]
                         ^ T1[S[(k1 >>> 16) & 0xFF] & 0xFF]
                         ^ T2[S[(k1 >>>  8) & 0xFF] & 0xFF]
                         ^ T3[S[ k1         & 0xFF] & 0xFF];
            Kd[R - r][2] = T0[S[ k2 >>> 24        ] & 0xFF]
                         ^ T1[S[(k2 >>> 16) & 0xFF] & 0xFF]
                         ^ T2[S[(k2 >>>  8) & 0xFF] & 0xFF]
                         ^ T3[S[ k2         & 0xFF] & 0xFF];
            Kd[R - r][3] = T0[S[ k3 >>> 24        ] & 0xFF]
                         ^ T1[S[(k3 >>> 16) & 0xFF] & 0xFF]
                         ^ T2[S[(k3 >>>  8) & 0xFF] & 0xFF]
                         ^ T3[S[ k3         & 0xFF] & 0xFF];
          }
      }
    if (Configuration.DEBUG)
      {
        log.fine("Key schedule");
        log.fine("Ke[]:");
        StringBuilder sb;
        for (r = 0; r < R + 1; r++)
          {
            sb = new StringBuilder("#").append(r).append(": ");
            for (j = 0; j < 4; j++)
              sb.append("0x").append(Util.toString(Ke[r][j])).append(", ");
            log.fine(sb.toString());
          }
        log.fine("Kd[]:");
        for (r = 0; r < R + 1; r++)
          {
            sb = new StringBuilder("#").append(r).append(": ");
            for (j = 0; j < 4; j++)
              sb.append("0x").append(Util.toString(Kd[r][j])).append(", ");
            log.fine(sb.toString());
          }
      }
    return new Object[] { Ke, Kd };
  }

  public void encrypt(byte[] in, int i, byte[] out, int j, Object k, int bs)
  {
    if (bs != DEFAULT_BLOCK_SIZE)
      throw new IllegalArgumentException();
    int[][] K = (int[][])((Object[]) k)[0];
    anubis(in, i, out, j, K);
  }

  public void decrypt(byte[] in, int i, byte[] out, int j, Object k, int bs)
  {
    if (bs != DEFAULT_BLOCK_SIZE)
      throw new IllegalArgumentException();
    int[][] K = (int[][])((Object[]) k)[1];
    anubis(in, i, out, j, K);
  }

  public boolean selfTest()
  {
    if (valid == null)
      {
        boolean result = super.selfTest(); // do symmetry tests
        if (result)
          result = testKat(KAT_KEY, KAT_CT);
        valid = Boolean.valueOf(result);
      }
    return valid.booleanValue();
  }
}
