func TestRecoverEncodings(t *testing.T) { constr, key := testConstruction() fastConstr := fastTestConstruction() baseConstr := saes.Construction{key} roundKeys := baseConstr.StretchedKey() outAff := getOutputAffineEncoding(constr, fastConstr, 1, 0) // Manually recover the output encoding. Q, Ps := RecoverEncodings(fastConstr, 1, 0) if fmt.Sprintf("%x %v", outAff.Linear, outAff.Constant) != fmt.Sprintf("%x %v", Q.Linear, Q.Constant) { t.Fatalf("RecoverEncodings recovered the wrong output encoding!") } // Verify that all Ps composed with their corresponding output encoding equals XOR by a key byte. id := matrix.GenerateIdentity(8) for pos, P := range Ps { outAff := getOutputAffineEncoding(constr, fastConstr, 0, unshiftRows(pos)) A, b := DecomposeAffineEncoding(encoding.ComposedBytes{outAff, P}) if fmt.Sprintf("%x", id) != fmt.Sprintf("%x", A) { t.Fatalf("Linear part of encoding was not identity!") } if roundKeys[1][unshiftRows(pos)] != b { t.Fatalf("Constant part of encoding was not key byte!") } } }
// FindPartialEncoding takes an affine encoded F and finds the values that strip its output encoding. It returns the // parameters it finds and the input encoding of f up to a key byte. func FindPartialEncoding(constr *chow.Construction, f table.Byte, L, AtildeInv matrix.Matrix) (number.ByteFieldElem, byte, encoding.ByteAffine) { fInv := table.Invert(f) id := encoding.ByteLinear(matrix.GenerateIdentity(8)) SInv := table.InvertibleTable(chow.InvTBox{saes.Construction{}, 0x00, 0x00}) S := table.Invert(SInv) // Brute force the constant part of the output encoding and the beta in Atilde = A_i <- D(beta) for c := 0; c < 256; c++ { for d := 1; d < 256; d++ { cand := encoding.ComposedBytes{ TableAsEncoding{f, fInv}, encoding.ByteAffine{id, byte(c)}, encoding.ByteLinear(AtildeInv), encoding.ByteMultiplication(byte(d)), // D below TableAsEncoding{SInv, S}, } if isAffine(cand) { a, b := DecomposeAffineEncoding(cand) return number.ByteFieldElem(d), byte(c), encoding.ByteAffine{encoding.ByteLinear(a), byte(b)} } } } panic("Failed to strip output encodings!") }
func generateMask(rs *RandomSource, maskType MaskType, surface Surface) matrix.Matrix { if maskType == RandomMask { label := make([]byte, 16) if surface == Inside { copy(label[:], []byte("MASK Inside")) return rs.Matrix(label, 128) } else { copy(label[:], []byte("MASK Outside")) return rs.Matrix(label, 128) } } else { // Identity mask. return matrix.GenerateIdentity(128) } }