// 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!") }
// RecoverAffineRel returns the affine relationship that maps y_i to y_j (instances of F with affine output encodings), // both taking input in the (inPos)th position and outputting in the (outPos1)th and (outPos2)th position, respectively. func RecoverAffineRel(constr *chow.Construction, round, inPos, outPos1, outPos2 int) encoding.ByteAffine { _, y_i := RecoverAffineEncoded(constr, encoding.IdentityByte{}, round, inPos, outPos1) _, y_j := RecoverAffineEncoded(constr, encoding.IdentityByte{}, round, inPos, outPos2) RelEnc := encoding.ComposedBytes{ TableAsEncoding{table.Invert(y_i), nil}, TableAsEncoding{y_j, nil}, } L, c := DecomposeAffineEncoding(RelEnc) return encoding.ByteAffine{encoding.ByteLinear(L), c} }
// GenerateS creates the set of elements S, of the form fXX(f00^(-1)(x)) = Q(Q^(-1)(x) + b) for indeterminate x is // isomorphic to the additive group (GF(2)^8, xor) under composition. func GenerateS(constr *chow.Construction, round, inPos, outPos int) [][256]byte { f00 := table.InvertibleTable(F{constr, round, inPos, outPos, 0x00}) f00Inv := table.Invert(f00) S := make([][256]byte, 256) for x := 0; x < 256; x++ { copy(S[x][:], table.SerializeByte(table.ComposedBytes{ f00Inv, F{constr, round, inPos, outPos, byte(x)}, })) } return S }