/* SHA.java -- Class implementing the SHA-1 algorithm as specified in [1].
   Copyright (C) 1999, 2000 Free Software Foundation, Inc.

This file is 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, 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; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License. */

  
package gnu.java.security.provider;

import java.security.MessageDigest;

/**
   This class implements the SHA-1 algorithm as described in [1].

   [1] Federal Information Processing Standards Publication 180-1.
   Specifications for the Secure Hash Standard.  April 17, 1995.

   @see java.security.MessageDigest
*/
public class SHA extends MessageDigest implements Cloneable
{
  public SHA ()
  {
    super("SHA");
    engineReset ();
  }

  public int engineGetDigestLength()
  {
    return 16;
  }

  public void engineUpdate (byte b)
  {
    int i = (int)bytecount % 64;
    int shift = (3 - i % 4) * 8;
    int idx = i / 4;

    // if you could index ints, this would be: W[idx][shift/8] = b
    W[idx] = (W[idx] & ~(0xff << shift)) | ((b & 0xff) << shift);

    // if we've filled up a block, then process it
    if ((++ bytecount) % 64 == 0)
      munch ();
  }

  // This could be optimized.
  public void engineUpdate (byte bytes[], int off, int len)
  {
    if (len < 0)
      throw new ArrayIndexOutOfBoundsException ();

    int end = off + len;
    while (off < end)
      engineUpdate (bytes[off++]);
  }

  public void engineReset ()
  {
    bytecount = 0;
    // magic numbers from [1] p. 10.
    H0 = 0x67452301;
    H1 = 0xefcdab89;
    H2 = 0x98badcfe;
    H3 = 0x10325476;
    H4 = 0xc3d2e1f0;
  }

  public byte[] engineDigest ()
  {
    long bitcount = bytecount * 8;
    engineUpdate ((byte)0x80); // 10000000 in binary; the start of the padding

    // add the rest of the padding to fill this block out, but leave 8
    // bytes to put in the original bytecount
    while ((int)bytecount % 64 != 56)
      engineUpdate ((byte)0);

    // add the length of the original, unpadded block to the end of
    // the padding
    W[14] = (int)(bitcount >>> 32);
    W[15] = (int)bitcount;
    bytecount += 8;

    // digest the fully padded block
    munch ();

    byte[] result
      = new byte[] {(byte)(H0 >>> 24), (byte)(H0 >>> 16),
		    (byte)(H0 >>> 8), (byte)H0,
		    (byte)(H1 >>> 24), (byte)(H1 >>> 16),
		    (byte)(H1 >>> 8), (byte)H1,
		    (byte)(H2 >>> 24), (byte)(H2 >>> 16),
		    (byte)(H2 >>> 8), (byte)H2,
		    (byte)(H3 >>> 24), (byte)(H3 >>> 16),
		    (byte)(H3 >>> 8), (byte)H3,
		    (byte)(H4 >>> 24), (byte)(H4 >>> 16),
		    (byte)(H4 >>> 8), (byte)H4};
    
    engineReset ();
    return result;
  }

  // Process a single block.  This is pretty much copied verbatim from
  // [1] pp. 9, 10.
  private void munch ()
  {
    for (int t = 16; t < 80; ++ t)
      {
	int Wt = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
	W[t] = Wt << 1 | Wt >>> 31;
      }

    int A = H0;
    int B = H1;
    int C = H2;
    int D = H3;
    int E = H4;

    for (int t = 0; t < 20; ++ t)
      {
	int TEMP = (A << 5 | A >>> 27) // S^5(A)
	  + ((B & C) | (~B & D))       // f_t(B,C,D)
	  + E + W[t]
	  + 0x5a827999;                // K_t

	E = D;
	D = C;
	C = B << 30 | B >>> 2;         // S^30(B)
	B = A;
	A = TEMP;
      }

    for (int t = 20; t < 40; ++ t)
      {
	int TEMP = (A << 5 | A >>> 27) // S^5(A)
	  + (B ^ C ^ D)                // f_t(B,C,D)
	  + E + W[t]                   
	  + 0x6ed9eba1;                // K_t

	E = D;
	D = C;
	C = B << 30 | B >>> 2;         // S^30(B)
	B = A;
	A = TEMP;
      }

    for (int t = 40; t < 60; ++ t)
      {
	int TEMP = (A << 5 | A >>> 27) // S^5(A)
	  + (B & C | B & D | C & D)    // f_t(B,C,D)
	  + E + W[t]
	  + 0x8f1bbcdc;                // K_t

	E = D;
	D = C;
	C = B << 30 | B >>> 2;         // S^30(B)
	B = A;
	A = TEMP;
      }

    for (int t = 60; t < 80; ++ t)
      {
	int TEMP = (A << 5 | A >>> 27) // S^5(A)
	  + (B ^ C ^ D)                // f_t(B,C,D)
	  + E + W[t]
	  + 0xca62c1d6;                // K_t

	E = D;
	D = C;
	C = B << 30 | B >>> 2;         // S^30(B)
	B = A;
	A = TEMP;
      }

    H0 += A;
    H1 += B;
    H2 += C;
    H3 += D;
    H4 += E;

    // Reset W by clearing it.
    for (int t = 0; t < 80; ++ t)
      W[t] = 0;
  }
  
  public Object clone ()
  {
    return new SHA (this);
  }

  private SHA (SHA copy)
  {
    this ();
    bytecount = copy.bytecount;
    H0 = copy.H0;
    H1 = copy.H1;
    H2 = copy.H2;
    H3 = copy.H3;
    H4 = copy.H4;
    System.arraycopy (copy.W, 0, W, 0, 80);
  }
  
  private final int W[] = new int[80];
  private long bytecount;
  private int H0;
  private int H1;
  private int H2;
  private int H3;
  private int H4;
}
