// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//+build !gccgo,!appengine

package sha3

// This file contains code for using the 'compute intermediate
// message digest' (KIMD) and 'compute last message digest' (KLMD)
// instructions to compute SHA-3 and SHAKE hashes on IBM Z.

import (
	"hash"
)

// codes represent 7-bit KIMD/KLMD function codes as defined in
// the Principles of Operation.
type code uint64

const (
	// function codes for KIMD/KLMD
	sha3_224  code = 32
	sha3_256       = 33
	sha3_384       = 34
	sha3_512       = 35
	shake_128      = 36
	shake_256      = 37
	nopad          = 0x100
)

// hasMSA6 reports whether the machine supports the SHA-3 and SHAKE function
// codes, as defined in message-security-assist extension 6.
func hasMSA6() bool

// hasAsm caches the result of hasMSA6 (which might be expensive to call).
var hasAsm = hasMSA6()

// kimd is a wrapper for the 'compute intermediate message digest' instruction.
// src must be a multiple of the rate for the given function code.
//go:noescape
func kimd(function code, chain *[200]byte, src []byte)

// klmd is a wrapper for the 'compute last message digest' instruction.
// src padding is handled by the instruction.
//go:noescape
func klmd(function code, chain *[200]byte, dst, src []byte)

type asmState struct {
	a         [200]byte       // 1600 bit state
	buf       []byte          // care must be taken to ensure cap(buf) is a multiple of rate
	rate      int             // equivalent to block size
	storage   [3072]byte      // underlying storage for buf
	outputLen int             // output length if fixed, 0 if not
	function  code            // KIMD/KLMD function code
	state     spongeDirection // whether the sponge is absorbing or squeezing
}

func newAsmState(function code) *asmState {
	var s asmState
	s.function = function
	switch function {
	case sha3_224:
		s.rate = 144
		s.outputLen = 28
	case sha3_256:
		s.rate = 136
		s.outputLen = 32
	case sha3_384:
		s.rate = 104
		s.outputLen = 48
	case sha3_512:
		s.rate = 72
		s.outputLen = 64
	case shake_128:
		s.rate = 168
	case shake_256:
		s.rate = 136
	default:
		panic("sha3: unrecognized function code")
	}

	// limit s.buf size to a multiple of s.rate
	s.resetBuf()
	return &s
}

func (s *asmState) clone() *asmState {
	c := *s
	c.buf = c.storage[:len(s.buf):cap(s.buf)]
	return &c
}

// copyIntoBuf copies b into buf. It will panic if there is not enough space to
// store all of b.
func (s *asmState) copyIntoBuf(b []byte) {
	bufLen := len(s.buf)
	s.buf = s.buf[:len(s.buf)+len(b)]
	copy(s.buf[bufLen:], b)
}

// resetBuf points buf at storage, sets the length to 0 and sets cap to be a
// multiple of the rate.
func (s *asmState) resetBuf() {
	max := (cap(s.storage) / s.rate) * s.rate
	s.buf = s.storage[:0:max]
}

// Write (via the embedded io.Writer interface) adds more data to the running hash.
// It never returns an error.
func (s *asmState) Write(b []byte) (int, error) {
	if s.state != spongeAbsorbing {
		panic("sha3: write to sponge after read")
	}
	length := len(b)
	for len(b) > 0 {
		if len(s.buf) == 0 && len(b) >= cap(s.buf) {
			// Hash the data directly and push any remaining bytes
			// into the buffer.
			remainder := len(s.buf) % s.rate
			kimd(s.function, &s.a, b[:len(b)-remainder])
			if remainder != 0 {
				s.copyIntoBuf(b[len(b)-remainder:])
			}
			return length, nil
		}

		if len(s.buf) == cap(s.buf) {
			// flush the buffer
			kimd(s.function, &s.a, s.buf)
			s.buf = s.buf[:0]
		}

		// copy as much as we can into the buffer
		n := len(b)
		if len(b) > cap(s.buf)-len(s.buf) {
			n = cap(s.buf) - len(s.buf)
		}
		s.copyIntoBuf(b[:n])
		b = b[n:]
	}
	return length, nil
}

// Read squeezes an arbitrary number of bytes from the sponge.
func (s *asmState) Read(out []byte) (n int, err error) {
	n = len(out)

	// need to pad if we were absorbing
	if s.state == spongeAbsorbing {
		s.state = spongeSqueezing

		// write hash directly into out if possible
		if len(out)%s.rate == 0 {
			klmd(s.function, &s.a, out, s.buf) // len(out) may be 0
			s.buf = s.buf[:0]
			return
		}

		// write hash into buffer
		max := cap(s.buf)
		if max > len(out) {
			max = (len(out)/s.rate)*s.rate + s.rate
		}
		klmd(s.function, &s.a, s.buf[:max], s.buf)
		s.buf = s.buf[:max]
	}

	for len(out) > 0 {
		// flush the buffer
		if len(s.buf) != 0 {
			c := copy(out, s.buf)
			out = out[c:]
			s.buf = s.buf[c:]
			continue
		}

		// write hash directly into out if possible
		if len(out)%s.rate == 0 {
			klmd(s.function|nopad, &s.a, out, nil)
			return
		}

		// write hash into buffer
		s.resetBuf()
		if cap(s.buf) > len(out) {
			s.buf = s.buf[:(len(out)/s.rate)*s.rate+s.rate]
		}
		klmd(s.function|nopad, &s.a, s.buf, nil)
	}
	return
}

// Sum appends the current hash to b and returns the resulting slice.
// It does not change the underlying hash state.
func (s *asmState) Sum(b []byte) []byte {
	if s.outputLen == 0 {
		panic("sha3: cannot call Sum on SHAKE functions")
	}

	// Copy the state to preserve the original.
	a := s.a

	// Hash the buffer. Note that we don't clear it because we
	// aren't updating the state.
	klmd(s.function, &a, nil, s.buf)
	return append(b, a[:s.outputLen]...)
}

// Reset resets the Hash to its initial state.
func (s *asmState) Reset() {
	for i := range s.a {
		s.a[i] = 0
	}
	s.resetBuf()
	s.state = spongeAbsorbing
}

// Size returns the number of bytes Sum will return.
func (s *asmState) Size() int {
	return s.outputLen
}

// BlockSize returns the hash's underlying block size.
// The Write method must be able to accept any amount
// of data, but it may operate more efficiently if all writes
// are a multiple of the block size.
func (s *asmState) BlockSize() int {
	return s.rate
}

// Clone returns a copy of the ShakeHash in its current state.
func (s *asmState) Clone() ShakeHash {
	return s.clone()
}

// new224Asm returns an assembly implementation of SHA3-224 if available,
// otherwise it returns nil.
func new224Asm() hash.Hash {
	if hasAsm {
		return newAsmState(sha3_224)
	}
	return nil
}

// new256Asm returns an assembly implementation of SHA3-256 if available,
// otherwise it returns nil.
func new256Asm() hash.Hash {
	if hasAsm {
		return newAsmState(sha3_256)
	}
	return nil
}

// new384Asm returns an assembly implementation of SHA3-384 if available,
// otherwise it returns nil.
func new384Asm() hash.Hash {
	if hasAsm {
		return newAsmState(sha3_384)
	}
	return nil
}

// new512Asm returns an assembly implementation of SHA3-512 if available,
// otherwise it returns nil.
func new512Asm() hash.Hash {
	if hasAsm {
		return newAsmState(sha3_512)
	}
	return nil
}

// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
// otherwise it returns nil.
func newShake128Asm() ShakeHash {
	if hasAsm {
		return newAsmState(shake_128)
	}
	return nil
}

// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
// otherwise it returns nil.
func newShake256Asm() ShakeHash {
	if hasAsm {
		return newAsmState(shake_256)
	}
	return nil
}
