mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			243 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			243 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Java
		
	
	
	
/* SHA.java -- Class implementing the SHA-1 algorithm as specified in [1].
 | 
						|
   Copyright (C) 1999, 2000, 2002 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.
 | 
						|
 | 
						|
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.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 20;
 | 
						|
  }
 | 
						|
 | 
						|
  public void engineUpdate (byte b)
 | 
						|
  {
 | 
						|
    int i = ((int)bytecount) & 0x3f; //wgs
 | 
						|
    int shift = (3 - i % 4) << 3;
 | 
						|
    int idx = i / 4;
 | 
						|
 | 
						|
    i = (int)b;
 | 
						|
    W[idx] = (W[idx] & ~(0xff << shift)) | ((i & 0xff) << shift);
 | 
						|
 | 
						|
    // if we've filled up a block, then process it
 | 
						|
    if (((++bytecount) & 0x3f) == 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 << 3;
 | 
						|
    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 ((bytecount & 0x3f) != 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;
 | 
						|
}
 |