// 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.pdfpackage aesimport// Encrypt one block from src into dst, using the expanded key xk.func encryptBlockGo( []uint32, , []byte) { _ = [15] // early bounds check := byteorder.BeUint32([0:4]) := byteorder.BeUint32([4:8]) := byteorder.BeUint32([8:12]) := byteorder.BeUint32([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 := 4var , , , uint32for := 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 checkbyteorder.BePutUint32([0:4], )byteorder.BePutUint32([4:8], )byteorder.BePutUint32([8:12], )byteorder.BePutUint32([12:16], )}// Decrypt one block from src into dst, using the expanded key xk.func decryptBlockGo( []uint32, , []byte) { _ = [15] // early bounds check := byteorder.BeUint32([0:4]) := byteorder.BeUint32([4:8]) := byteorder.BeUint32([8:12]) := byteorder.BeUint32([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 := 4var , , , uint32for := 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 checkbyteorder.BePutUint32([0:4], )byteorder.BePutUint32([4:8], )byteorder.BePutUint32([8:12], )byteorder.BePutUint32([12:16], )}// Apply sbox0 to each byte in w.func subw( uint32) uint32 {returnuint32(sbox0[>>24])<<24 |uint32(sbox0[>>16&0xff])<<16 |uint32(sbox0[>>8&0xff])<<8 |uint32(sbox0[&0xff])}// Rotatefunc rotw( uint32) uint32 { return <<8 | >>24 }// Key expansion algorithm. See FIPS-197, Figure 11.// Their rcon[i] is our powx[i-1] << 24.func expandKeyGo( []byte, , []uint32) {// Encryption key setup.varint := len() / 4for = 0; < ; ++ { [] = byteorder.BeUint32([4*:]) }for ; < len(); ++ { := [-1]if % == 0 { = subw(rotw()) ^ (uint32(powx[/-1]) << 24) } elseif > 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 { := - - 4for := 0; < 4; ++ { := [+]if > 0 && +4 < { = td0[sbox0[>>24]] ^ td1[sbox0[>>16&0xff]] ^ td2[sbox0[>>8&0xff]] ^ td3[sbox0[&0xff]] } [+] = } }}
The pages are generated with Goldsv0.7.0-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.