blob: 35046389135c44e0ef65ae6a64ed2f2f030fc492 [file] [log] [blame] [edit]
// 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.
package aes
import "testing"
// See const.go for overview of math here.
// Test that powx is initialized correctly.
// (Can adapt this code to generate it too.)
func TestPowx(t *testing.T) {
p := 1
for i := 0; i < len(powx); i++ {
if powx[i] != byte(p) {
t.Errorf("powx[%d] = %#x, want %#x", i, powx[i], p)
}
p <<= 1
if p&0x100 != 0 {
p ^= poly
}
}
}
// Multiply b and c as GF(2) polynomials modulo poly
func mul(b, c uint32) uint32 {
i := b
j := c
s := uint32(0)
for k := uint32(1); k < 0x100 && j != 0; k <<= 1 {
// Invariant: k == 1<<n, i == b * xⁿ
if j&k != 0 {
// s += i in GF(2); xor in binary
s ^= i
j ^= k // turn off bit to end loop early
}
// i *= x in GF(2) modulo the polynomial
i <<= 1
if i&0x100 != 0 {
i ^= poly
}
}
return s
}
// Test all mul inputs against bit-by-bit n² algorithm.
func TestMul(t *testing.T) {
for i := uint32(0); i < 256; i++ {
for j := uint32(0); j < 256; j++ {
// Multiply i, j bit by bit.
s := uint8(0)
for k := uint(0); k < 8; k++ {
for l := uint(0); l < 8; l++ {
if i&(1<<k) != 0 && j&(1<<l) != 0 {
s ^= powx[k+l]
}
}
}
if x := mul(i, j); x != uint32(s) {
t.Fatalf("mul(%#x, %#x) = %#x, want %#x", i, j, x, s)
}
}
}
}
// Check that S-boxes are inverses of each other.
// They have more structure that we could test,
// but if this sanity check passes, we'll assume
// the cut and paste from the FIPS PDF worked.
func TestSboxes(t *testing.T) {
for i := 0; i < 256; i++ {
if j := sbox0[sbox1[i]]; j != byte(i) {
t.Errorf("sbox0[sbox1[%#x]] = %#x", i, j)
}
if j := sbox1[sbox0[i]]; j != byte(i) {
t.Errorf("sbox1[sbox0[%#x]] = %#x", i, j)
}
}
}
// Test that encryption tables are correct.
// (Can adapt this code to generate them too.)
func TestTe(t *testing.T) {
for i := 0; i < 256; i++ {
s := uint32(sbox0[i])
s2 := mul(s, 2)
s3 := mul(s, 3)
w := s2<<24 | s<<16 | s<<8 | s3
te := [][256]uint32{te0, te1, te2, te3}
for j := 0; j < 4; j++ {
if x := te[j][i]; x != w {
t.Fatalf("te[%d][%d] = %#x, want %#x", j, i, x, w)
}
w = w<<24 | w>>8
}
}
}
// Test that decryption tables are correct.
// (Can adapt this code to generate them too.)
func TestTd(t *testing.T) {
for i := 0; i < 256; i++ {
s := uint32(sbox1[i])
s9 := mul(s, 0x9)
sb := mul(s, 0xb)
sd := mul(s, 0xd)
se := mul(s, 0xe)
w := se<<24 | s9<<16 | sd<<8 | sb
td := [][256]uint32{td0, td1, td2, td3}
for j := 0; j < 4; j++ {
if x := td[j][i]; x != w {
t.Fatalf("td[%d][%d] = %#x, want %#x", j, i, x, w)
}
w = w<<24 | w>>8
}
}
}