Copyright 2009 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.
This Go implementation is derived in part from the reference ANSI C implementation, which carries the following notice: rijndael-alg-fst.c @version 3.0 (December 2000) Optimised ANSI C code for the Rijndael cipher (now AES) @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> @author Paulo Barreto <paulo.barreto@terra.com.br> This code is hereby placed in the public domain. THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. See FIPS 197 for specification, and see Daemen and Rijmen's Rijndael submission for implementation details. https://csrc.nist.gov/csrc/media/publications/fips/197/final/documents/fips-197.pdf https://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf

package aes

import (
	
)
Encrypt one block from src into dst, using the expanded key xk.
func ( []uint32, ,  []byte) {
	_ = [15] // early bounds check
	 := binary.BigEndian.Uint32([0:4])
	 := binary.BigEndian.Uint32([4:8])
	 := binary.BigEndian.Uint32([8:12])
	 := binary.BigEndian.Uint32([12:16])
First round just XORs input with key.
	 ^= [0]
	 ^= [1]
	 ^= [2]
	 ^= [3]
Middle rounds shuffle using tables. Number of rounds is set by length of expanded key.
	 := len()/4 - 2 // - 2: one above, one more below
	 := 4
	var , , ,  uint32
	for  := 0;  < ; ++ {
		 = [+0] ^ te0[uint8(>>24)] ^ te1[uint8(>>16)] ^ te2[uint8(>>8)] ^ te3[uint8()]
		 = [+1] ^ te0[uint8(>>24)] ^ te1[uint8(>>16)] ^ te2[uint8(>>8)] ^ te3[uint8()]
		 = [+2] ^ te0[uint8(>>24)] ^ te1[uint8(>>16)] ^ te2[uint8(>>8)] ^ te3[uint8()]
		 = [+3] ^ te0[uint8(>>24)] ^ te1[uint8(>>16)] ^ te2[uint8(>>8)] ^ te3[uint8()]
		 += 4
		, , ,  = , , , 
	}
Last round uses s-box directly and XORs to produce output.
	 = uint32(sbox0[>>24])<<24 | uint32(sbox0[>>16&0xff])<<16 | uint32(sbox0[>>8&0xff])<<8 | uint32(sbox0[&0xff])
	 = uint32(sbox0[>>24])<<24 | uint32(sbox0[>>16&0xff])<<16 | uint32(sbox0[>>8&0xff])<<8 | uint32(sbox0[&0xff])
	 = uint32(sbox0[>>24])<<24 | uint32(sbox0[>>16&0xff])<<16 | uint32(sbox0[>>8&0xff])<<8 | uint32(sbox0[&0xff])
	 = uint32(sbox0[>>24])<<24 | uint32(sbox0[>>16&0xff])<<16 | uint32(sbox0[>>8&0xff])<<8 | uint32(sbox0[&0xff])

	 ^= [+0]
	 ^= [+1]
	 ^= [+2]
	 ^= [+3]

	_ = [15] // early bounds check
	binary.BigEndian.PutUint32([0:4], )
	binary.BigEndian.PutUint32([4:8], )
	binary.BigEndian.PutUint32([8:12], )
	binary.BigEndian.PutUint32([12:16], )
}
Decrypt one block from src into dst, using the expanded key xk.
func ( []uint32, ,  []byte) {
	_ = [15] // early bounds check
	 := binary.BigEndian.Uint32([0:4])
	 := binary.BigEndian.Uint32([4:8])
	 := binary.BigEndian.Uint32([8:12])
	 := binary.BigEndian.Uint32([12:16])
First round just XORs input with key.
	 ^= [0]
	 ^= [1]
	 ^= [2]
	 ^= [3]
Middle rounds shuffle using tables. Number of rounds is set by length of expanded key.
	 := len()/4 - 2 // - 2: one above, one more below
	 := 4
	var , , ,  uint32
	for  := 0;  < ; ++ {
		 = [+0] ^ td0[uint8(>>24)] ^ td1[uint8(>>16)] ^ td2[uint8(>>8)] ^ td3[uint8()]
		 = [+1] ^ td0[uint8(>>24)] ^ td1[uint8(>>16)] ^ td2[uint8(>>8)] ^ td3[uint8()]
		 = [+2] ^ td0[uint8(>>24)] ^ td1[uint8(>>16)] ^ td2[uint8(>>8)] ^ td3[uint8()]
		 = [+3] ^ td0[uint8(>>24)] ^ td1[uint8(>>16)] ^ td2[uint8(>>8)] ^ td3[uint8()]
		 += 4
		, , ,  = , , , 
	}
Last round uses s-box directly and XORs to produce output.
	 = uint32(sbox1[>>24])<<24 | uint32(sbox1[>>16&0xff])<<16 | uint32(sbox1[>>8&0xff])<<8 | uint32(sbox1[&0xff])
	 = uint32(sbox1[>>24])<<24 | uint32(sbox1[>>16&0xff])<<16 | uint32(sbox1[>>8&0xff])<<8 | uint32(sbox1[&0xff])
	 = uint32(sbox1[>>24])<<24 | uint32(sbox1[>>16&0xff])<<16 | uint32(sbox1[>>8&0xff])<<8 | uint32(sbox1[&0xff])
	 = uint32(sbox1[>>24])<<24 | uint32(sbox1[>>16&0xff])<<16 | uint32(sbox1[>>8&0xff])<<8 | uint32(sbox1[&0xff])

	 ^= [+0]
	 ^= [+1]
	 ^= [+2]
	 ^= [+3]

	_ = [15] // early bounds check
	binary.BigEndian.PutUint32([0:4], )
	binary.BigEndian.PutUint32([4:8], )
	binary.BigEndian.PutUint32([8:12], )
	binary.BigEndian.PutUint32([12:16], )
}
Apply sbox0 to each byte in w.
func ( uint32) uint32 {
	return uint32(sbox0[>>24])<<24 |
		uint32(sbox0[>>16&0xff])<<16 |
		uint32(sbox0[>>8&0xff])<<8 |
		uint32(sbox0[&0xff])
}
Rotate
func ( uint32) uint32 { return <<8 | >>24 }
Key expansion algorithm. See FIPS-197, Figure 11. Their rcon[i] is our powx[i-1] << 24.
Encryption key setup.
	var  int
	 := len() / 4
	for  = 0;  < ; ++ {
		[] = binary.BigEndian.Uint32([4*:])
	}
	for ;  < len(); ++ {
		 := [-1]
		if % == 0 {
			 = subw(rotw()) ^ (uint32(powx[/-1]) << 24)
		} else if  > 6 && % == 4 {
			 = subw()
		}
		[] = [-] ^ 
	}
Derive decryption key from encryption key. Reverse the 4-word round key sets from enc to produce dec. All sets but the first and last get the MixColumn transform applied.
	if  == nil {
		return
	}
	 := len()
	for  := 0;  < ;  += 4 {
		 :=  -  - 4
		for  := 0;  < 4; ++ {
			 := [+]
			if  > 0 && +4 <  {
				 = td0[sbox0[>>24]] ^ td1[sbox0[>>16&0xff]] ^ td2[sbox0[>>8&0xff]] ^ td3[sbox0[&0xff]]
			}
			[+] = 
		}
	}