/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

/*
 * Implementation of the Secure Hashing Algorithm (SHA-512)
 *
 * Generates a 512 bit message digest. It should be impossible to come
 * come up with two messages that hash to the same value ("collision free").
 *
 * For use with byte-oriented messages only. 
 */

package org.apache.milagro.amcl;

public class HASH384 {
	private long[] length=new long[2];
	private long[] h=new long[8];
	private long[] w=new long[80];

	public static final long H0=0xcbbb9d5dc1059ed8L;
	public static final long H1=0x629a292a367cd507L;
	public static final long H2=0x9159015a3070dd17L;
	public static final long H3=0x152fecd8f70e5939L;
	public static final long H4=0x67332667ffc00b31L;
	public static final long H5=0x8eb44a8768581511L;
	public static final long H6=0xdb0c2e0d64f98fa7L;
	public static final long H7=0x47b5481dbefa4fa4L;

	public static final int len=48;

	public static final long[] K=
	{0x428a2f98d728ae22L,0x7137449123ef65cdL,0xb5c0fbcfec4d3b2fL,0xe9b5dba58189dbbcL,
	0x3956c25bf348b538L,0x59f111f1b605d019L,0x923f82a4af194f9bL,0xab1c5ed5da6d8118L,
	0xd807aa98a3030242L,0x12835b0145706fbeL,0x243185be4ee4b28cL,0x550c7dc3d5ffb4e2L,
	0x72be5d74f27b896fL,0x80deb1fe3b1696b1L,0x9bdc06a725c71235L,0xc19bf174cf692694L,
	0xe49b69c19ef14ad2L,0xefbe4786384f25e3L,0x0fc19dc68b8cd5b5L,0x240ca1cc77ac9c65L,
	0x2de92c6f592b0275L,0x4a7484aa6ea6e483L,0x5cb0a9dcbd41fbd4L,0x76f988da831153b5L,
	0x983e5152ee66dfabL,0xa831c66d2db43210L,0xb00327c898fb213fL,0xbf597fc7beef0ee4L,
	0xc6e00bf33da88fc2L,0xd5a79147930aa725L,0x06ca6351e003826fL,0x142929670a0e6e70L,
	0x27b70a8546d22ffcL,0x2e1b21385c26c926L,0x4d2c6dfc5ac42aedL,0x53380d139d95b3dfL,
	0x650a73548baf63deL,0x766a0abb3c77b2a8L,0x81c2c92e47edaee6L,0x92722c851482353bL,
	0xa2bfe8a14cf10364L,0xa81a664bbc423001L,0xc24b8b70d0f89791L,0xc76c51a30654be30L,
	0xd192e819d6ef5218L,0xd69906245565a910L,0xf40e35855771202aL,0x106aa07032bbd1b8L,
	0x19a4c116b8d2d0c8L,0x1e376c085141ab53L,0x2748774cdf8eeb99L,0x34b0bcb5e19b48a8L,
	0x391c0cb3c5c95a63L,0x4ed8aa4ae3418acbL,0x5b9cca4f7763e373L,0x682e6ff3d6b2b8a3L,
	0x748f82ee5defb2fcL,0x78a5636f43172f60L,0x84c87814a1f0ab72L,0x8cc702081a6439ecL,
	0x90befffa23631e28L,0xa4506cebde82bde9L,0xbef9a3f7b2c67915L,0xc67178f2e372532bL,
	0xca273eceea26619cL,0xd186b8c721c0c207L,0xeada7dd6cde0eb1eL,0xf57d4f7fee6ed178L,
	0x06f067aa72176fbaL,0x0a637dc5a2c898a6L,0x113f9804bef90daeL,0x1b710b35131c471bL,
	0x28db77f523047d84L,0x32caab7b40c72493L,0x3c9ebe0a15c9bebcL,0x431d67c49c100d4cL,
	0x4cc5d4becb3e42b6L,0x597f299cfc657e2aL,0x5fcb6fab3ad6faecL,0x6c44198c4a475817L};

/* functions */
	private static long S(int n,long x)
	{
		return (((x)>>>n) | ((x)<<(64-n)));
	}

	private static long R(int n,long x)
	{
		return ((x)>>>n);
	}

	private static long Ch(long x,long y,long z)
	{
		return ((x&y)^(~(x)&z));
	}

	private static long Maj(long x,long y,long z)
	{
		return ((x&y)^(x&z)^(y&z));
	}

	private static long Sig0(long x)
	{
		return (S(28,x)^S(34,x)^S(39,x));
	}

	private static long Sig1(long x)
	{
		return (S(14,x)^S(18,x)^S(41,x));
	}

	private static long theta0(long x)
	{
		return (S(1,x)^S(8,x)^R(7,x));
	}

	private static long theta1(long x)
	{
		return (S(19,x)^S(61,x)^R(6,x));
	}

	private void transform()
	{ /* basic transformation step */
		long a,b,c,d,e,f,g,hh,t1,t2;
		int j;
		for (j=16;j<80;j++) 
			w[j]=theta1(w[j-2])+w[j-7]+theta0(w[j-15])+w[j-16];
		a=h[0]; b=h[1]; c=h[2]; d=h[3]; 
		e=h[4]; f=h[5]; g=h[6]; hh=h[7];

		for (j=0;j<80;j++)
		{ /* 80 times - mush it up */
			t1=hh+Sig1(e)+Ch(e,f,g)+K[j]+w[j];
			t2=Sig0(a)+Maj(a,b,c);
			hh=g; g=f; f=e;
			e=d+t1;
			d=c;
			c=b;
			b=a;
			a=t1+t2;   
		
		}
		h[0]+=a; h[1]+=b; h[2]+=c; h[3]+=d; 
		h[4]+=e; h[5]+=f; h[6]+=g; h[7]+=hh; 
	} 

/* Initialise Hash function */
	public void init()
	{ /* initialise */
		int i;
		for (i=0;i<80;i++) w[i]=0L;
		length[0]=length[1]=0L;
		h[0]=H0;
		h[1]=H1;
		h[2]=H2;
		h[3]=H3;
		h[4]=H4;
		h[5]=H5;
		h[6]=H6;
		h[7]=H7;
	}

/* Constructor */
	public HASH384()
	{
		init();
	}

/* process a single byte */
	public void process(int byt)
	{ /* process the next message byte */
		int cnt;
		cnt=(int)(length[0]/64)%16;
    
		w[cnt]<<=8;
		w[cnt]|=(byt&0xFF);
		length[0]+=8;
		if (length[0]==0L) { length[1]++; length[0]=0L; }
		if ((length[0]%1024)==0) transform();
	}

/* process an array of bytes */	
	public void process_array(byte[] b)
	{
		for (int i=0;i<b.length;i++) process((int)b[i]);
	}

/* process a 32-bit integer */
	public void process_num(int n)
	{
		process((n>>24)&0xff);
		process((n>>16)&0xff);
		process((n>>8)&0xff);
		process(n&0xff);
	}

/* Generate 48-byte Hash */
	public byte[] hash()
	{ /* pad message and finish - supply digest */
		int i;
		byte[] digest=new byte[48];
		long len0,len1;
		len0=length[0];
		len1=length[1];
		process(0x80);
		while ((length[0]%1024)!=896) process(0);
		w[14]=len1;
		w[15]=len0;    
		transform();
		for (i=0;i<len;i++)
		{ /* convert to bytes */
			digest[i]=(byte)((h[i/8]>>(8*(7-i%8))) & 0xffL);
		}
		init();
		return digest;
	}

/* test program: should produce digest */

//09330c33f71147e8 3d192fc782cd1b47 53111b173b3b05d2 2fa08086e3b0f712 fcc7c71a557e2db9 66c3e9fa91746039

	public static void main(String[] args) {

		byte[] test="abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".getBytes();
		byte[] digest;
		int i;
		HASH384 sh=new HASH384();
  
		for (i=0;i<test.length;i++)
			sh.process(test[i]);
		
		digest=sh.hash();    
		for (i=0;i<48;i++) System.out.format("%02x",digest[i]);

	//	for (i=0;i<32;i++) System.out.format("%d ",digest[i]);

		System.out.println("");

	} 
}

