/*
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 AES-GCM Encryption/Authentication
*
* Some restrictions..
* 1. Only for use with AES
* 2. Returned tag is always 128-bits. Truncate at your own risk.
* 3. The order of function calls must follow some rules
*
* Typical sequence of calls..
* 1. call GCM_init
* 2. call GCM_add_header any number of times, as long as length of header is multiple of 16 bytes (block size)
* 3. call GCM_add_header one last time with any length of header
* 4. call GCM_add_cipher any number of times, as long as length of cipher/plaintext is multiple of 16 bytes
* 5. call GCM_add_cipher one last time with any length of cipher/plaintext
* 6. call GCM_finish to extract the tag.
*
* See http://www.mindspring.com/~dmcgrew/gcm-nist-6.pdf
 */

package amcl

import (
	//	"fmt"
	"strconv"
)

const gcm_NB int = 4
const GCM_ACCEPTING_HEADER int = 0
const GCM_ACCEPTING_CIPHER int = 1
const GCM_NOT_ACCEPTING_MORE int = 2
const GCM_FINISHED int = 3
const GCM_ENCRYPTING int = 0
const GCM_DECRYPTING int = 1

type GCM struct {
	table   [128][4]uint32 /* 2k bytes */
	stateX  [16]byte
	Y_0     [16]byte
	counter int
	lenA    [2]uint32
	lenC    [2]uint32
	status  int
	a       *AES
}

func gcm_pack(b [4]byte) uint32 { /* pack bytes into a 32-bit Word */
	return ((uint32(b[0]) & 0xff) << 24) | ((uint32(b[1]) & 0xff) << 16) | ((uint32(b[2]) & 0xff) << 8) | (uint32(b[3]) & 0xff)
}

func gcm_unpack(a uint32) [4]byte { /* unpack bytes from a word */
	var b = [4]byte{byte((a >> 24) & 0xff), byte((a >> 16) & 0xff), byte((a >> 8) & 0xff), byte(a & 0xff)}
	return b
}

func (G *GCM) precompute(H []byte) {
	var b [4]byte
	j := 0
	for i := 0; i < gcm_NB; i++ {
		b[0] = H[j]
		b[1] = H[j+1]
		b[2] = H[j+2]
		b[3] = H[j+3]
		G.table[0][i] = gcm_pack(b)
		j += 4
	}
	for i := 1; i < 128; i++ {
		c := uint32(0)
		for j := 0; j < gcm_NB; j++ {
			G.table[i][j] = c | (G.table[i-1][j])>>1
			c = G.table[i-1][j] << 31
		}
		if c != 0 {
			G.table[i][0] ^= 0xE1000000
		} /* irreducible polynomial */
	}
}

func (G *GCM) gf2mul() { /* gf2m mul - Z=H*X mod 2^128 */
	var P [4]uint32

	for i := 0; i < 4; i++ {
		P[i] = 0
	}
	j := uint(8)
	m := 0
	for i := 0; i < 128; i++ {
		j--
		c := uint32((G.stateX[m] >> j) & 1)
		c = ^c + 1
		for k := 0; k < gcm_NB; k++ {
			P[k] ^= (G.table[i][k] & c)
		}
		if j == 0 {
			j = 8
			m++
			if m == 16 {
				break
			}
		}
	}
	j = 0
	for i := 0; i < gcm_NB; i++ {
		b := gcm_unpack(P[i])
		G.stateX[j] = b[0]
		G.stateX[j+1] = b[1]
		G.stateX[j+2] = b[2]
		G.stateX[j+3] = b[3]
		j += 4
	}
}

func (G *GCM) wrap() { /* Finish off GHASH */
	var F [4]uint32
	var L [16]byte

	/* convert lengths from bytes to bits */
	F[0] = (G.lenA[0] << 3) | (G.lenA[1]&0xE0000000)>>29
	F[1] = G.lenA[1] << 3
	F[2] = (G.lenC[0] << 3) | (G.lenC[1]&0xE0000000)>>29
	F[3] = G.lenC[1] << 3
	j := 0
	for i := 0; i < gcm_NB; i++ {
		b := gcm_unpack(F[i])
		L[j] = b[0]
		L[j+1] = b[1]
		L[j+2] = b[2]
		L[j+3] = b[3]
		j += 4
	}
	for i := 0; i < 16; i++ {
		G.stateX[i] ^= L[i]
	}
	G.gf2mul()
}

func (G *GCM) ghash(plain []byte, len int) bool {
	if G.status == GCM_ACCEPTING_HEADER {
		G.status = GCM_ACCEPTING_CIPHER
	}
	if G.status != GCM_ACCEPTING_CIPHER {
		return false
	}

	j := 0
	for j < len {
		for i := 0; i < 16 && j < len; i++ {
			G.stateX[i] ^= plain[j]
			j++
			G.lenC[1]++
			if G.lenC[1] == 0 {
				G.lenC[0]++
			}
		}
		G.gf2mul()
	}
	if len%16 != 0 {
		G.status = GCM_NOT_ACCEPTING_MORE
	}
	return true
}

/* Initialize GCM mode */
func (G *GCM) Init(nk int, key []byte, niv int, iv []byte) { /* iv size niv is usually 12 bytes (96 bits). AES key size nk can be 16,24 or 32 bytes */
	var H [16]byte

	for i := 0; i < 16; i++ {
		H[i] = 0
		G.stateX[i] = 0
	}

	G.a = new(AES)

	G.a.Init(AES_ECB, nk, key, iv)
	G.a.ecb_encrypt(H[:]) /* E(K,0) */
	G.precompute(H[:])

	G.lenA[0] = 0
	G.lenC[0] = 0
	G.lenA[1] = 0
	G.lenC[1] = 0
	if niv == 12 {
		for i := 0; i < 12; i++ {
			G.a.f[i] = iv[i]
		}
		b := gcm_unpack(uint32(1))
		G.a.f[12] = b[0]
		G.a.f[13] = b[1]
		G.a.f[14] = b[2]
		G.a.f[15] = b[3] /* initialise IV */
		for i := 0; i < 16; i++ {
			G.Y_0[i] = G.a.f[i]
		}
	} else {
		G.status = GCM_ACCEPTING_CIPHER
		G.ghash(iv, niv) /* GHASH(H,0,IV) */
		G.wrap()
		for i := 0; i < 16; i++ {
			G.a.f[i] = G.stateX[i]
			G.Y_0[i] = G.a.f[i]
			G.stateX[i] = 0
		}
		G.lenA[0] = 0
		G.lenC[0] = 0
		G.lenA[1] = 0
		G.lenC[1] = 0
	}
	G.status = GCM_ACCEPTING_HEADER
}

/* Add Header data - included but not encrypted */
func (G *GCM) Add_header(header []byte, len int) bool { /* Add some header. Won't be encrypted, but will be authenticated. len is length of header */
	if G.status != GCM_ACCEPTING_HEADER {
		return false
	}

	j := 0
	for j < len {
		for i := 0; i < 16 && j < len; i++ {
			G.stateX[i] ^= header[j]
			j++
			G.lenA[1]++
			if G.lenA[1] == 0 {
				G.lenA[0]++
			}
		}
		G.gf2mul()
	}
	if len%16 != 0 {
		G.status = GCM_ACCEPTING_CIPHER
	}

	return true
}

/* Add Plaintext - included and encrypted */
func (G *GCM) Add_plain(plain []byte, len int) []byte {
	var B [16]byte
	var b [4]byte

	cipher := make([]byte, len)
	var counter uint32 = 0
	if G.status == GCM_ACCEPTING_HEADER {
		G.status = GCM_ACCEPTING_CIPHER
	}
	if G.status != GCM_ACCEPTING_CIPHER {
		return nil
	}

	j := 0
	for j < len {

		b[0] = G.a.f[12]
		b[1] = G.a.f[13]
		b[2] = G.a.f[14]
		b[3] = G.a.f[15]
		counter = gcm_pack(b)
		counter++
		b = gcm_unpack(counter)
		G.a.f[12] = b[0]
		G.a.f[13] = b[1]
		G.a.f[14] = b[2]
		G.a.f[15] = b[3] /* increment counter */
		for i := 0; i < 16; i++ {
			B[i] = G.a.f[i]
		}
		G.a.ecb_encrypt(B[:]) /* encrypt it  */

		for i := 0; i < 16 && j < len; i++ {
			cipher[j] = (plain[j] ^ B[i])
			G.stateX[i] ^= cipher[j]
			j++
			G.lenC[1]++
			if G.lenC[1] == 0 {
				G.lenC[0]++
			}
		}
		G.gf2mul()
	}
	if len%16 != 0 {
		G.status = GCM_NOT_ACCEPTING_MORE
	}
	return cipher
}

/* Add Ciphertext - decrypts to plaintext */
func (G *GCM) Add_cipher(cipher []byte, len int) []byte {
	var B [16]byte
	var b [4]byte

	plain := make([]byte, len)
	var counter uint32 = 0

	if G.status == GCM_ACCEPTING_HEADER {
		G.status = GCM_ACCEPTING_CIPHER
	}
	if G.status != GCM_ACCEPTING_CIPHER {
		return nil
	}

	j := 0
	for j < len {
		b[0] = G.a.f[12]
		b[1] = G.a.f[13]
		b[2] = G.a.f[14]
		b[3] = G.a.f[15]
		counter = gcm_pack(b)
		counter++
		b = gcm_unpack(counter)
		G.a.f[12] = b[0]
		G.a.f[13] = b[1]
		G.a.f[14] = b[2]
		G.a.f[15] = b[3] /* increment counter */
		for i := 0; i < 16; i++ {
			B[i] = G.a.f[i]
		}
		G.a.ecb_encrypt(B[:]) /* encrypt it  */
		for i := 0; i < 16 && j < len; i++ {
			oc := cipher[j]
			plain[j] = (cipher[j] ^ B[i])
			G.stateX[i] ^= oc
			j++
			G.lenC[1]++
			if G.lenC[1] == 0 {
				G.lenC[0]++
			}
		}
		G.gf2mul()
	}
	if len%16 != 0 {
		G.status = GCM_NOT_ACCEPTING_MORE
	}
	return plain
}

/* Finish and extract Tag */
func (G *GCM) Finish(extract bool) [16]byte { /* Finish off GHASH and extract tag (MAC) */
	var tag [16]byte

	G.wrap()
	/* extract tag */
	if extract {
		G.a.ecb_encrypt(G.Y_0[:]) /* E(K,Y0) */
		for i := 0; i < 16; i++ {
			G.Y_0[i] ^= G.stateX[i]
		}
		for i := 0; i < 16; i++ {
			tag[i] = G.Y_0[i]
			G.Y_0[i] = 0
			G.stateX[i] = 0
		}
	}
	G.status = GCM_FINISHED
	G.a.End()
	return tag
}

func hex2bytes(s string) []byte {
	lgh := len(s)
	data := make([]byte, lgh/2)

	for i := 0; i < lgh; i += 2 {
		a, _ := strconv.ParseInt(s[i:i+2], 16, 32)
		data[i/2] = byte(a)
	}
	return data
}

/*
func main() {

	KT:="feffe9928665731c6d6a8f9467308308"
	MT:="d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39"
	HT:="feedfacedeadbeeffeedfacedeadbeefabaddad2"

	NT:="9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b";
// Tag should be 619cc5aefffe0bfa462af43c1699d050

	g:=new(GCM)

	M:=hex2bytes(MT)
	H:=hex2bytes(HT)
	N:=hex2bytes(NT)
	K:=hex2bytes(KT)

	lenM:=len(M)
	lenH:=len(H)
	lenK:=len(K)
	lenIV:=len(N)

 	fmt.Printf("Plaintext=\n");
	for i:=0;i<lenM;i++ {fmt.Printf("%02x",M[i])}
	fmt.Printf("\n")

	g.Init(lenK,K,lenIV,N)
	g.Add_header(H,lenH)
	C:=g.Add_plain(M,lenM)
	T:=g.Finish(true)

	fmt.Printf("Ciphertext=\n")
	for i:=0;i<lenM;i++ {fmt.Printf("%02x",C[i])}
	fmt.Printf("\n")

	fmt.Printf("Tag=\n")
	for i:=0;i<16;i++ {fmt.Printf("%02x",T[i])}
	fmt.Printf("\n")

	g.Init(lenK,K,lenIV,N)
	g.Add_header(H,lenH)
	P:=g.Add_cipher(C,lenM)
	T=g.Finish(true)

 	fmt.Printf("Plaintext=\n");
	for i:=0;i<lenM;i++ {fmt.Printf("%02x",P[i])}
	fmt.Printf("\n")

	fmt.Printf("Tag=\n");
	for i:=0;i<16;i++ {fmt.Printf("%02x",T[i])}
	fmt.Printf("\n")
}
*/
