/*
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-256)
 *
 * Generates a 256 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 amcl

//import "fmt"

const hash_H0 uint32 = 0x6A09E667
const hash_H1 uint32 = 0xBB67AE85
const hash_H2 uint32 = 0x3C6EF372
const hash_H3 uint32 = 0xA54FF53A
const hash_H4 uint32 = 0x510E527F
const hash_H5 uint32 = 0x9B05688C
const hash_H6 uint32 = 0x1F83D9AB
const hash_H7 uint32 = 0x5BE0CD19

var hash_K = [...]uint32{
	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}

type HASH struct {
	length [2]uint32
	h      [8]uint32
	w      [64]uint32
}

/* functions */
func hash_S(n uint32, x uint32) uint32 {
	return (((x) >> n) | ((x) << (32 - n)))
}

func hash_R(n uint32, x uint32) uint32 {
	return ((x) >> n)
}

func hash_Ch(x, y, z uint32) uint32 {
	return ((x & y) ^ (^(x) & z))
}

func hash_Maj(x, y, z uint32) uint32 {
	return ((x & y) ^ (x & z) ^ (y & z))
}

func hash_Sig0(x uint32) uint32 {
	return (hash_S(2, x) ^ hash_S(13, x) ^ hash_S(22, x))
}

func hash_Sig1(x uint32) uint32 {
	return (hash_S(6, x) ^ hash_S(11, x) ^ hash_S(25, x))
}

func hash_theta0(x uint32) uint32 {
	return (hash_S(7, x) ^ hash_S(18, x) ^ hash_R(3, x))
}

func hash_theta1(x uint32) uint32 {
	return (hash_S(17, x) ^ hash_S(19, x) ^ hash_R(10, x))
}

func (H *HASH) transform() { /* basic transformation step */
	for j := 16; j < 64; j++ {
		H.w[j] = hash_theta1(H.w[j-2]) + H.w[j-7] + hash_theta0(H.w[j-15]) + H.w[j-16]
	}
	a := H.h[0]
	b := H.h[1]
	c := H.h[2]
	d := H.h[3]
	e := H.h[4]
	f := H.h[5]
	g := H.h[6]
	hh := H.h[7]
	for j := 0; j < 64; j++ { /* 64 times - mush it up */
		t1 := hh + hash_Sig1(e) + hash_Ch(e, f, g) + hash_K[j] + H.w[j]
		t2 := hash_Sig0(a) + hash_Maj(a, b, c)
		hh = g
		g = f
		f = e
		e = d + t1
		d = c
		c = b
		b = a
		a = t1 + t2
	}
	H.h[0] += a
	H.h[1] += b
	H.h[2] += c
	H.h[3] += d
	H.h[4] += e
	H.h[5] += f
	H.h[6] += g
	H.h[7] += hh
}

/* Initialise Hash function */
func (H *HASH) Init() { /* initialise */
	for i := 0; i < 64; i++ {
		H.w[i] = 0
	}
	H.length[0] = 0
	H.length[1] = 0
	H.h[0] = hash_H0
	H.h[1] = hash_H1
	H.h[2] = hash_H2
	H.h[3] = hash_H3
	H.h[4] = hash_H4
	H.h[5] = hash_H5
	H.h[6] = hash_H6
	H.h[7] = hash_H7
}

func NewHASH() *HASH {
	H := new(HASH)
	H.Init()
	return H
}

/* process a single byte */
func (H *HASH) Process(byt byte) { /* process the next message byte */
	cnt := (H.length[0] / 32) % 16

	H.w[cnt] <<= 8
	H.w[cnt] |= uint32(byt & 0xFF)
	H.length[0] += 8
	if H.length[0] == 0 {
		H.length[1]++
		H.length[0] = 0
	}
	if (H.length[0] % 512) == 0 {
		H.transform()
	}
}

/* process an array of bytes */
func (H *HASH) Process_array(b []byte) {
	for i := 0; i < len(b); i++ {
		H.Process((b[i]))
	}
}

/* process a 32-bit integer */
func (H *HASH) Process_num(n int32) {
	H.Process(byte((n >> 24) & 0xff))
	H.Process(byte((n >> 16) & 0xff))
	H.Process(byte((n >> 8) & 0xff))
	H.Process(byte(n & 0xff))
}

/* Generate 32-byte Hash */
func (H *HASH) Hash() [32]byte { /* pad message and finish - supply digest */
	var digest [32]byte
	len0 := H.length[0]
	len1 := H.length[1]
	H.Process(0x80)
	for (H.length[0] % 512) != 448 {
		H.Process(0)
	}
	H.w[14] = len1
	H.w[15] = len0
	H.transform()
	for i := 0; i < 32; i++ { /* convert to bytes */
		digest[i] = byte((H.h[i/4] >> uint(8*(3-i%4))) & 0xff)
	}
	H.Init()
	return digest
}

/* test program: should produce digest */

//248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
/*
func main() {

	test := []byte("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
	sh:=NewHASH()

	for i:=0;i<len(test);i++ {
		sh.Process(test[i])
	}

	digest:=sh.Hash()
	for i:=0;i<32;i++ {fmt.Printf("%02x",digest[i])}

}
*/
