Beispiel #1
0
// stripScalars gets rid of unknown scalars in each block of the affine layer. It leaves it exactly equal to MixColumns,
// but there is an unknown scalar in each block that will move into the S-box layers.
func (al *affineLayer) stripScalars() (encoding.ConcatenatedBlock, encoding.ConcatenatedBlock) {
	input, output := [16]encoding.ByteLinear{}, [16]encoding.ByteLinear{}

	for pos := 0; pos < 16; pos += 4 {
		found := false

		for guess := 1; guess < 256 && !found; guess++ { // Take a guess for the input scalar on the first column.
			input[pos], _ = encoding.DecomposeByteLinear(encoding.NewByteMultiplication(number.ByteFieldElem(guess)))

			// Given input scalar on first column, calculate output scalars on all rows.
			for i := pos; i < pos+4; i++ {
				mc, _ := mixColumns[i%4][0].Invert()
				output[i] = encoding.NewByteLinear(
					al.getBlock(i, pos).Compose(input[pos].Backwards).Compose(mc),
				)
			}

			// Given output scalar on each row, calculate input scalars on all columns.
			for i := pos + 1; i < pos+4; i++ {
				mc, _ := mixColumns[0][i%4].Invert()
				input[i] = encoding.NewByteLinear(
					al.getBlock(pos, i).Compose(output[pos].Backwards).Compose(mc),
				)
			}

			// Verify that guess is consistent.
			found = true

			for i := pos; i < pos+4 && found; i++ {
				for j := pos; j < pos+4 && found; j++ {
					cand := al.getBlock(i, j).Compose(output[i].Backwards).Compose(input[j].Backwards)
					real := mixColumns[i%4][j%4]

					if !cand.Equals(real) {
						found = false
					}
				}
			}
		}

		if !found {
			panic("Failed to disambiguate block affine layer!")
		}
	}

	in, out := encoding.ConcatenatedBlock{}, encoding.ConcatenatedBlock{}
	for pos := 0; pos < 16; pos++ {
		in[pos], out[pos] = input[pos], output[pos]
	}

	return in, out
}
Beispiel #2
0
// blockParasites returns the input parasite of the block at the given row and column of the linear part of al, or nil
// if the block is zero.
func (al *affineLayer) blockParasite(row, col int) (input *parasite) {
	block := al.getBlock(row, col)
	if toString(block) == "0000000000000000" {
		return nil
	}
	enc := encoding.NewByteLinear(block)

	for _, input = range parasites {
		cand, _ := encoding.DecomposeByteLinear(encoding.ComposedBytes{
			encoding.InverseByte{subBytes}, encoding.InverseByte{input}, enc,
		})
		_, ok := parasites[toString(cand.Forwards)]
		if ok {
			return
		}
	}

	panic("unable to determine input parasite")
}