// rightCompose composes a Block encoding on the right. func (al *affineLayer) rightCompose(right encoding.Block) { temp, _ := encoding.DecomposeBlockAffine(encoding.ComposedBlocks{ encoding.BlockAffine(*al), right, }) *al = affineLayer(temp) }
// leftCompose composes a Block encoding on the left. func (al *affineLayer) leftCompose(left encoding.Block) { temp, _ := encoding.DecomposeBlockAffine(encoding.ComposedBlocks{ left, encoding.BlockAffine(*al), }) *al = affineLayer(temp) }
// adjust fixes the affine layer for two block encodings which will be moved somewhere else. func (al *affineLayer) adjust(input, output encoding.Block) { temp, _ := encoding.DecomposeBlockAffine(encoding.ComposedBlocks{ encoding.InverseBlock{input}, encoding.BlockAffine(*al), encoding.InverseBlock{output}, }) *al = affineLayer(temp) }
// GenerateKeys creates a white-boxed version of the AES key `key`, with any non-determinism generated by `seed`. func GenerateKeys(key, seed []byte) (out Construction, inputMask, outputMask encoding.BlockAffine) { rs := random.NewSource("Toy Construction", seed) // Generate two completely random affine transformations, to be put on input and output of SPN. inputMask, outputMask = generateAffineMasks(&rs) // Steal key schedule logic from the standard AES construction. constr := saes.Construction{key} roundKeys := constr.StretchedKey() // Generate an SPN which has the input and output masks, but is otherwise un-obfuscated. out[0] = inputMask encoding.XOR(out[0].BlockAdditive[:], out[0].BlockAdditive[:], roundKeys[0]) for i := 1; i < 10; i++ { out[i] = encoding.BlockAffine{ BlockLinear: encoding.BlockLinear{round, unRound}, BlockAdditive: shiftRoundKey(roundKeys[i]), } } out[10] = encoding.BlockAffine{ BlockLinear: encoding.BlockLinear{lastRound, firstRound}, BlockAdditive: shiftRoundKey(roundKeys[10]), } out[10], _ = encoding.DecomposeBlockAffine(encoding.ComposedBlocks{out[10], outputMask}) // Sample a self-equivalences of the S-box layer and mix them into adjacent affine layers. label := make([]byte, 16) copy(label, []byte("Self-Eq")) r := rs.Stream(label) for i := 1; i < 11; i++ { a, bInv := generateSelfEquivalence(r) out[i-1], _ = encoding.DecomposeBlockAffine(encoding.ComposedBlocks{out[i-1], a}) out[i], _ = encoding.DecomposeBlockAffine(encoding.ComposedBlocks{bInv, out[i]}) } return }