func TestMatchedEncrypt(t *testing.T) { cand, real := make([]byte, 16), make([]byte, 16) // Calculate the candidate output. constr, inputMask, outputMask := GenerateEncryptionKeys(key, seed, MatchingMasks{}) inputInv, _ := inputMask.Invert() outputInv, _ := outputMask.Invert() in := make([]byte, 16) copy(in, inputInv.Mul(matrix.Row(input))) // Apply input encoding. constr.Encrypt(cand, in) constr.Encrypt(cand, cand) copy(cand, outputInv.Mul(matrix.Row(cand))) // Remove output encoding. // Calculate the real output. c, _ := aes.NewCipher(key) c.Encrypt(real, input) c.Encrypt(real, real) if !bytes.Equal(real, cand) { t.Fatalf("Real disagrees with result! %x != %x", real, cand) } }
func (constr *Construction) crypt(dst, src []byte) { copy(dst, src) for round := 0; round < 10; round++ { // ShiftRows and re-encoding step. copy(dst, constr.ShiftRows[round].Mul(matrix.Row(dst))) // Apply T-Boxes and MixColumns for pos := 0; pos < 16; pos += 4 { stretched := constr.ExpandWord(constr.TBoxMixCol[round][pos/2:(pos+4)/2], dst[pos:pos+4]) constr.SquashWords(stretched, dst[pos:pos+4]) } } copy(dst, constr.FinalMask.Mul(matrix.Row(dst))) }
func TestEncrypt(t *testing.T) { for n, vec := range test_vectors.AESVectors { constr, inputMask, outputMask := GenerateEncryptionKeys(vec.Key, vec.Key, IndependentMasks{RandomMask, RandomMask}) inputInv, _ := inputMask.Invert() outputInv, _ := outputMask.Invert() in, out := make([]byte, 16), make([]byte, 16) copy(in, inputInv.Mul(matrix.Row(vec.In))) // Apply input encoding. constr.Encrypt(out, in) copy(out, outputInv.Mul(matrix.Row(out))) // Remove output encoding. if !bytes.Equal(vec.Out, out) { t.Fatalf("Real disagrees with result in test vector %v! %x != %x", n, vec.Out, out) } } }
func (bl BlockLinear) Decode(i [16]byte) (out [16]byte) { inv, ok := matrix.Matrix(bl).Invert() if !ok { panic("Matrix wasn't invertible!") } res := inv.Mul(matrix.Row(i[:])) copy(out[:], res) return }
func (wl WordLinear) Decode(i [4]byte) (out [4]byte) { inv, ok := matrix.Matrix(wl).Invert() // Performance bottleneck. if !ok { panic("Matrix wasn't invertible!") } res := inv.Mul(matrix.Row(i[:])) copy(out[:], res) return }
func (bm BlockMatrix) Get(i byte) (out [16]byte) { r := make([]byte, 16) r[bm.Position] = i res := bm.Linear.Mul(matrix.Row(r)) copy(out[:], res) for i, c := range bm.Constant { out[i] ^= c } return }
func (bl BlockLinear) Encode(i [16]byte) (out [16]byte) { res := matrix.Matrix(bl).Mul(matrix.Row(i[:])) copy(out[:], res) return }
func (wl WordLinear) Encode(i [4]byte) (out [4]byte) { res := matrix.Matrix(wl).Mul(matrix.Row(i[:])) copy(out[:], res) return }
func matrixMul(m *matrix.Matrix, dst, src []byte) { res := m.Mul(matrix.Row(src[:])) copy(dst, res) }