/* TMMH16.java -- 
   Copyright (C) 2001, 2002, 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.mac;

import gnu.java.security.Registry;
import gnu.java.security.prng.IRandom;
import gnu.java.security.prng.LimitReachedException;

import java.security.InvalidKeyException;
import java.util.Map;

/**
 * <i>TMMH</i> is a <i>universal</i> hash function suitable for message
 * authentication in the Wegman-Carter paradigm, as in the Stream Cipher
 * Security Transform. It is simple, quick, and especially appropriate for
 * Digital Signal Processors and other processors with a fast multiply
 * operation, though a straightforward implementation requires storage equal in
 * length to the largest message to be hashed.
 * <p>
 * <i>TMMH</i> is a simple hash function which maps a key and a message to a
 * hash value. There are two versions of TMMH: TMMH/16 and TMMH/32. <i>TMMH</i>
 * can be used as a message authentication code, as described in Section 5 (see
 * References).
 * <p>
 * The key, message, and hash value are all octet strings, and the lengths of
 * these quantities are denoted as <code>KEY_LENGTH</code>,
 * <code>MESSAGE_LENGTH</code>, and <code>TAG_LENGTH</code>, respectively.
 * The values of <code>KEY_LENGTH</code> and <code>TAG_LENGTH</code>
 * <bold>MUST</bold> be fixed for any particular fixed value of the key, and
 * must obey the alignment restrictions described below.
 * <p>
 * The parameter <code>MAX_HASH_LENGTH</code>, which denotes the maximum
 * value which <code>MESSAGE_LENGTH</code> may take, is equal to
 * <code>KEY_LENGTH - TAG_LENGTH</code>.
 * <p>
 * References:
 * <ol>
 * <li><a
 * href="http://www.ietf.org/internet-drafts/draft-mcgrew-saag-tmmh-01.txt"> The
 * Truncated Multi-Modular Hash Function (TMMH)</a>, David A. McGrew.</li>
 * </ol>
 */
public class TMMH16
    extends BaseMac
    implements Cloneable
{
  public static final String TAG_LENGTH = "gnu.crypto.mac.tmmh.tag.length";
  public static final String KEYSTREAM = "gnu.crypto.mac.tmmh.keystream";
  public static final String PREFIX = "gnu.crypto.mac.tmmh.prefix";
  private static final int P = (1 << 16) + 1; // the TMMH/16 prime
  /** caches the result of the correctness test, once executed. */
  private static Boolean valid;
  private int tagWords = 0; // the tagLength expressed in words
  private IRandom keystream = null; // the keystream generator
  private byte[] prefix; // mask to use when operating as an authentication f.
  private long keyWords; // key words counter
  private long msgLength; // in bytes
  private long msgWords; // should be = msgLength * WORD_LENGTH
  private int[] context; // the tmmh running context; length == TAG_WORDS
  private int[] K0; // the first TAG_WORDS words of the keystream
  private int[] Ki; // the sliding TAG_WORDS words of the keystream
  private int Mi; // current message word being constructed

  /** Trivial 0-arguments constructor. */
  public TMMH16()
  {
    super(Registry.TMMH16);
  }

  public int macSize()
  {
    return tagWords * 2;
  }

  public void init(Map attributes) throws InvalidKeyException,
      IllegalStateException
  {
    int wantTagLength = 0;
    Integer tagLength = (Integer) attributes.get(TAG_LENGTH); // get tag length
    if (tagLength == null)
      {
        if (tagWords == 0) // was never set
          throw new IllegalArgumentException(TAG_LENGTH);
        // else re-use
      }
    else // check if positive and is divisible by WORD_LENGTH
      {
        wantTagLength = tagLength.intValue();
        if (wantTagLength < 2 || (wantTagLength % 2 != 0))
          throw new IllegalArgumentException(TAG_LENGTH);
        else if (wantTagLength > (512 / 8)) // 512-bits is our maximum
          throw new IllegalArgumentException(TAG_LENGTH);

        tagWords = wantTagLength / 2; // init local vars
        K0 = new int[tagWords];
        Ki = new int[tagWords];
        context = new int[tagWords];
      }

    prefix = (byte[]) attributes.get(PREFIX);
    if (prefix == null) // default to all-zeroes
      prefix = new byte[tagWords * 2];
    else // ensure it's as long as it should
      {
        if (prefix.length != tagWords * 2)
          throw new IllegalArgumentException(PREFIX);
      }

    IRandom prng = (IRandom) attributes.get(KEYSTREAM); // get keystream
    if (prng == null)
      {
        if (keystream == null)
          throw new IllegalArgumentException(KEYSTREAM);
        // else reuse
      }
    else
      keystream = prng;

    reset(); // reset context variables
    for (int i = 0; i < tagWords; i++) // init starting key words
      Ki[i] = K0[i] = getNextKeyWord(keystream);
  }

  // The words of the key are denoted as K[1], K[2], ..., K[KEY_WORDS], and the
  // words of the message (after zero padding, if needed) are denoted as M[1],
  // M[2], ..., M[MSG_WORDS], where MSG_WORDS is the smallest number such that
  // 2 * MSG_WORDS is at least MESSAGE_LENGTH, and KEY_WORDS is KEY_LENGTH / 2.
  //
  // If MESSAGE_LENGTH is greater than MAX_HASH_LENGTH, then the value of
  // TMMH/16 is undefined. Implementations MUST indicate an error if asked to
  // hash a message with such a length. Otherwise, the hash value is defined
  // to be the length TAG_WORDS sequence of words in which the j-th word in the
  // sequence is defined as
  //
  // [ [ K[j] * MESSAGE_LENGTH +32 K[j+1] * M[1] +32 K[j+2] * M[2]
  // +32 ... K[j+MSG_WORDS] * M[MSG_WORDS] ] modulo p ] modulo 2^16
  //
  // where j ranges from 1 to TAG_WORDS.
  public void update(byte b)
  {
    this.update(b, keystream);
  }

  public void update(byte[] b, int offset, int len)
  {
    for (int i = 0; i < len; i++)
      this.update(b[offset + i], keystream);
  }

  // For TMMH/16, KEY_LENGTH and TAG_LENGTH MUST be a multiple of two. The key,
  // message, and hash value are treated as a sequence of unsigned sixteen bit
  // integers in network byte order. (In this section, we call such an integer
  // a word.) If MESSAGE_LENGTH is odd, then a zero byte is appended to the
  // message to align it on a word boundary, though this process does not
  // change the value of MESSAGE_LENGTH.
  //
  // ... Otherwise, the hash value is defined to be the length TAG_WORDS
  // sequence of words in which the j-th word in the sequence is defined as
  //
  // [ [ K[j] * MESSAGE_LENGTH +32 K[j+1] * M[1] +32 K[j+2] * M[2]
  // +32 ... K[j+MSG_WORDS] * M[MSG_WORDS] ] modulo p ] modulo 2^16
  //
  // where j ranges from 1 to TAG_WORDS.
  //
  // Here, TAG_WORDS is equal to TAG_LENGTH / 2, and p is equal to 2^16 + 1.
  // The symbol * denotes multiplication and the symbol +32 denotes addition
  // modulo 2^32.
  public byte[] digest()
  {
    return this.digest(keystream);
  }

  public void reset()
  {
    msgLength = msgWords = keyWords = 0L;
    Mi = 0;
    for (int i = 0; i < tagWords; i++)
      context[i] = 0;
  }

  public boolean selfTest()
  {
    if (valid == null)
      {
        // TODO: compute and test equality with one known vector
        valid = Boolean.TRUE;
      }
    return valid.booleanValue();
  }

  public Object clone() throws CloneNotSupportedException
  {
    TMMH16 result = (TMMH16) super.clone();
    if (this.keystream != null)
      result.keystream = (IRandom) this.keystream.clone();
    if (this.prefix != null)
      result.prefix = (byte[]) this.prefix.clone();
    if (this.context != null)
      result.context = (int[]) this.context.clone();
    if (this.K0 != null)
      result.K0 = (int[]) this.K0.clone();
    if (this.Ki != null)
      result.Ki = (int[]) this.Ki.clone();
    return result;
  }

  /**
   * Similar to the same method with one argument, but uses the designated
   * random number generator to compute needed keying material.
   * 
   * @param b the byte to process.
   * @param prng the source of randomness to use.
   */
  public void update(byte b, IRandom prng)
  {
    Mi <<= 8; // update message buffer
    Mi |= b & 0xFF;
    msgLength++; // update message length (bytes)
    if (msgLength % 2 == 0) // got a full word
      {
        msgWords++; // update message words counter
        System.arraycopy(Ki, 1, Ki, 0, tagWords - 1); // 1. shift Ki up by 1
        Ki[tagWords - 1] = getNextKeyWord(prng); // 2. fill last box of Ki
        long t; // temp var to allow working in modulo 2^32
        for (int i = 0; i < tagWords; i++) // 3. update context
          {
            t = context[i] & 0xFFFFFFFFL;
            t += Ki[i] * Mi;
            context[i] = (int) t;
          }
        Mi = 0; // reset message buffer
      }
  }

  /**
   * Similar to the same method with three arguments, but uses the designated
   * random number generator to compute needed keying material.
   * 
   * @param b the byte array to process.
   * @param offset the starting offset in <code>b</code> to start considering
   *          the bytes to process.
   * @param len the number of bytes in <code>b</code> starting from
   *          <code>offset</code> to process.
   * @param prng the source of randomness to use.
   */
  public void update(byte[] b, int offset, int len, IRandom prng)
  {
    for (int i = 0; i < len; i++)
      this.update(b[offset + i], prng);
  }

  /**
   * Similar to the same method with no arguments, but uses the designated
   * random number generator to compute needed keying material.
   * 
   * @param prng the source of randomness to use.
   * @return the final result of the algorithm.
   */
  public byte[] digest(IRandom prng)
  {
    doFinalRound(prng);
    byte[] result = new byte[tagWords * 2];
    for (int i = 0, j = 0; i < tagWords; i++)
      {
        result[j] = (byte)((context[i] >>> 8) ^ prefix[j]);
        j++;
        result[j] = (byte)(context[i] ^ prefix[j]);
        j++;
      }
    reset();
    return result;
  }

  private int getNextKeyWord(IRandom prng)
  {
    int result = 0;
    try
      {
        result = (prng.nextByte() & 0xFF) << 8 | (prng.nextByte() & 0xFF);
      }
    catch (LimitReachedException x)
      {
        throw new RuntimeException(String.valueOf(x));
      }
    keyWords++; // update key words counter
    return result;
  }

  private void doFinalRound(IRandom prng)
  {
    long limit = msgLength; // formula works on real message length
    while (msgLength % 2 != 0)
      update((byte) 0x00, prng);
    long t;
    for (int i = 0; i < tagWords; i++)
      {
        t = context[i] & 0xFFFFFFFFL;
        t += K0[i] * limit;
        t %= P;
        context[i] = (int) t;
      }
  }
}
