/*
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-3

 * Generates a 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 SHA3 {
	private long length;
	private int rate,len;
	private long[][] S=new long[5][5];

/* Constructor */
	public SHA3(int olen)
	{
		init(olen);
	}

	public static final int HASH224=28; 
	public static final int HASH256=32;
	public static final int HASH384=48;
	public static final int HASH512=64;

	public static final int SHAKE128=16; 
	public static final int SHAKE256=32; 

	public static final long[] RC={
		0x0000000000000001L,0x0000000000008082L,0x800000000000808AL,0x8000000080008000L,
		0x000000000000808BL,0x0000000080000001L,0x8000000080008081L,0x8000000000008009L,
		0x000000000000008AL,0x0000000000000088L,0x0000000080008009L,0x000000008000000AL,
		0x000000008000808BL,0x800000000000008BL,0x8000000000008089L,0x8000000000008003L,
		0x8000000000008002L,0x8000000000000080L,0x000000000000800AL,0x800000008000000AL,
		0x8000000080008081L,0x8000000000008080L,0x0000000080000001L,0x8000000080008008L};

	private static final int ROUNDS=24;


	private static long rotl(long x,int n)
	{
		return (((x)<<n) | ((x)>>>(64-n)));
	}

	private void transform()
	{ /* basic transformation step */
		int i,j,k;
		long[] C=new long[5];
		long[] D=new long[5];
		long[][] B=new long[5][5];

		for (k=0;k<ROUNDS;k++)
		{
			C[0]=S[0][0]^S[0][1]^S[0][2]^S[0][3]^S[0][4];
			C[1]=S[1][0]^S[1][1]^S[1][2]^S[1][3]^S[1][4];
			C[2]=S[2][0]^S[2][1]^S[2][2]^S[2][3]^S[2][4];
			C[3]=S[3][0]^S[3][1]^S[3][2]^S[3][3]^S[3][4];
			C[4]=S[4][0]^S[4][1]^S[4][2]^S[4][3]^S[4][4];

			D[0]=C[4]^rotl(C[1],1);
			D[1]=C[0]^rotl(C[2],1);
			D[2]=C[1]^rotl(C[3],1);
			D[3]=C[2]^rotl(C[4],1);
			D[4]=C[3]^rotl(C[0],1);

			for (i=0;i<5;i++)
				for (j=0;j<5;j++)
					S[i][j]^=D[i];  

			B[0][0]=S[0][0];
			B[1][3]=rotl(S[0][1],36);
			B[2][1]=rotl(S[0][2],3);
			B[3][4]=rotl(S[0][3],41);
			B[4][2]=rotl(S[0][4],18);

			B[0][2]=rotl(S[1][0],1);
			B[1][0]=rotl(S[1][1],44);
			B[2][3]=rotl(S[1][2],10);
			B[3][1]=rotl(S[1][3],45);
			B[4][4]=rotl(S[1][4],2);

			B[0][4]=rotl(S[2][0],62);
			B[1][2]=rotl(S[2][1],6);
			B[2][0]=rotl(S[2][2],43);
			B[3][3]=rotl(S[2][3],15);
			B[4][1]=rotl(S[2][4],61);

			B[0][1]=rotl(S[3][0],28);
			B[1][4]=rotl(S[3][1],55);
			B[2][2]=rotl(S[3][2],25);
			B[3][0]=rotl(S[3][3],21);
			B[4][3]=rotl(S[3][4],56);

			B[0][3]=rotl(S[4][0],27);
			B[1][1]=rotl(S[4][1],20);
			B[2][4]=rotl(S[4][2],39);
			B[3][2]=rotl(S[4][3],8);
			B[4][0]=rotl(S[4][4],14);

			for (i=0;i<5;i++)
				for (j=0;j<5;j++)
					S[i][j]=B[i][j]^(~B[(i+1)%5][j]&B[(i+2)%5][j]);

			S[0][0]^=RC[k];
		}
	} 

/* Re-Initialize. olen is output length in bytes - 
   should be 28, 32, 48 or 64 (224, 256, 384, 512 bits resp.) */


/* Initialise Hash function */
	public void init(int olen)
	{ /* initialise */
		int i,j;
		for (i=0;i<5;i++) 
			for (j=0;j<5;j++)
				S[i][j]=0;    /* 5x5x8 bytes = 200 bytes of state */
		length=0;
		len=olen;
		rate=200-2*olen; /* number of bytes consumed in one gulp. Note that some bytes in the 
	                        state ("capacity") are not touched. Gulps are smaller for larger digests. 
							Important that olen<rate */
	}

/* process a single byte */
	public void process(int byt)
	{ /* process the next message byte */
		int i,j,b,cnt;
		cnt=(int)(length%rate);
		b=cnt%8;
		cnt/=8;
		i=cnt%5; j=cnt/5;  /* process by columns! */
		S[i][j]^=((long)(byt&0xff)<<(8*b));
		length++;
		if ((length%rate)==0) transform();
	}

/* squeeze the sponge */
	public byte[] squeeze(byte[] buff,int olen)
	{
		boolean done;
		int i,j,k,m=0;
		long el;
/* extract by columns */
		done=false;
		for (;;)
		{
			for (j=0;j<5;j++)
			{
				for (i=0;i<5;i++)
				{
					el=S[i][j];
					for (k=0;k<8;k++)
					{
						buff[m++]=(byte)(el&0xff);
						if (m>=olen || (m%rate)==0) {done=true; break;} 
						el>>>=8;
					}
					if (done) break;
				}
				if (done) break;
			}
			if (m>=olen) break;
			done=false;
			transform();
		}
		return buff;
	}

	public void hash(byte[] digest)
	{ /* generate a SHA3 hash of appropriate size */
		int q=rate-(int)(length%rate);
		if (q==1) process(0x86); 
		else
		{
			process(0x06);   /* 0x06 for SHA-3 */
			while (length%rate!=rate-1) process(0x00);
			process(0x80); /* this will force a final transform */
		}
		squeeze(digest,len);
	}

	public void shake(byte[] digest,int olen)
	{ /* SHAKE out a buffer of variable length olen */
		int q=rate-(int)(length%rate);
		if (q==1) process(0x9f); 
		else
		{
			process(0x1f);   // 0x06 for SHA-3 !!!!
			while (length%rate!=rate-1) process(0x00);
			process(0x80); /* this will force a final transform */
		}
		squeeze(digest,olen);
	}

/* test program: should produce digests */

//916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18
//afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185
//98be04516c04cc73593fef3ed0352ea9f6443942d6950e29a372a681c3deaf4535423709b02843948684e029010badcc0acd8303fc85fdad3eabf4f78cae165635f57afd28810fc2

/*
	public static void main(String[] args) {

		byte[] test="abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".getBytes();
		byte[] digest=new byte[100];
		int i;

		SHA3 sh256=new SHA3(SHA3.HASH256);
		for (i=0;i<test.length;i++)
			sh256.process(test[i]);
		sh256.hash(digest);    
		for (i=0;i<32;i++) System.out.format("%02x",digest[i]);
		System.out.println("");

		SHA3 sh512=new SHA3(SHA3.HASH512);
		for (i=0;i<test.length;i++)
			sh512.process(test[i]);
		sh512.hash(digest);    
		for (i=0;i<64;i++) System.out.format("%02x",digest[i]);
		System.out.println("");

		SHA3 sk256=new SHA3(SHA3.SHAKE256);
		for (i=0;i<test.length;i++)
			sk256.process(test[i]);
		sk256.shake(digest,72);    
		for (i=0;i<72;i++) System.out.format("%02x",digest[i]);
		System.out.println("");

	}  
*/
}