Example #1
0
// generateRoundMaterial creates the TMC (TBox + MixColumns) tables.
func generateRoundMaterial(rs *random.Source, out *Construction, hidden func(int, int) table.DoubleToWord) {
	for round := 0; round < 10; round++ {
		for pos := 0; pos < 16; pos += 2 {
			out.TBoxMixCol[round][pos/2] = encoding.DoubleToWordTable{
				encoding.NewDoubleLinear(common.MixingBijection(rs, 16, round, pos/2)),
				encoding.InverseWord{
					encoding.NewWordLinear(common.MixingBijection(rs, 32, round, pos/4)),
				},
				hidden(round, pos),
			}
		}
	}
}
Example #2
0
// generateRoundMaterial creates the TMC (TBox + MixColumns) tables.
func generateRoundMaterial(rs *common.RandomSource, out *Construction, hidden func(int, int) table.DoubleToWord) {
	for round := 0; round < 10; round++ {
		for pos := 0; pos < 16; pos += 2 {
			inEnc := common.MixingBijection(rs, 16, round, pos/2)
			outEnc := common.MixingBijection(rs, 32, round, pos/4)

			inInv, _ := inEnc.Invert()
			outInv, _ := outEnc.Invert()

			out.TBoxMixCol[round][pos/2] = encoding.DoubleToWordTable{
				encoding.DoubleLinear{inEnc, inInv},
				encoding.WordLinear{outInv, outEnc},
				hidden(round, pos),
			}
		}
	}
}
Example #3
0
func maskSwap(rs *random.Source, size, round int) (out matrix.Matrix) {
	out = matrix.GenerateEmpty(128, 128)

	for row := 0; row < 128; row += size {
		col := row / 8
		m := common.MixingBijection(rs, size, round, row/size)

		for subRow := 0; subRow < size; subRow++ {
			copy(out[row+subRow][col:], m[subRow])
		}
	}

	return
}
Example #4
0
// blockMaskEncoding concatenates all the mask encodings for InputMask or TBoxOutputMask into a block encoding, so that
// it can easily be put on the output of one of the Block tables.
//
// position is the index of the Block table and shift is the permutation that will be applied between this round and the
// next or noshift if this is an input encoding; the other parameters are explained in MaskEncoding documentation.
func blockMaskEncoding(rs *random.Source, position int, surface common.Surface, shift func(int) int) encoding.Block {
	out := encoding.ConcatenatedBlock{}

	for i := 0; i < 16; i++ {
		out[i] = encoding.ConcatenatedByte{
			maskEncoding(rs, surface)(position, 2*i+0),
			maskEncoding(rs, surface)(position, 2*i+1),
		}

		if surface == common.Inside {
			out[i] = encoding.ComposedBytes{
				encoding.NewByteLinear(common.MixingBijection(rs, 8, -1, shift(i))),
				out[i],
			}
		}
	}

	return out
}
Example #5
0
func generateKeys(rs *random.Source, opts common.KeyGenerationOpts, out *Construction, inputMask, outputMask *matrix.Matrix, shift func(int) int, skinny func(int) table.Byte, wide func(int, int) table.Word) {
	// Generate input and output encodings.
	common.GenerateMasks(rs, opts, inputMask, outputMask)

	// Generate the Input Mask slices and XOR tables.
	for pos := 0; pos < 16; pos++ {
		out.InputMask[pos] = encoding.BlockTable{
			encoding.IdentityByte{},
			blockMaskEncoding(rs, pos, common.Inside, shift),
			common.BlockMatrix{Linear: *inputMask, Position: pos},
		}
	}

	out.InputXORTables = common.BlockNibbleXORTables(
		maskEncoding(rs, common.Inside),
		xorEncoding(rs, 10, common.Inside),
		roundEncoding(rs, -1, common.Outside, shift),
	)

	// Generate round material.
	for round := 0; round < 9; round++ {
		for pos := 0; pos < 16; pos++ {
			// Generate a word-sized mixing bijection and stick it on the end of the T-Box/Tyi Table.
			mb := common.MixingBijection(rs, 32, round, pos/4)

			// Build the T-Box and Tyi Table for this round and position in the state matrix.
			out.TBoxTyiTable[round][pos] = encoding.WordTable{
				encoding.ComposedBytes{
					encoding.NewByteLinear(common.MixingBijection(rs, 8, round-1, pos)),
					byteRoundEncoding(rs, round-1, pos, common.Outside, common.NoShift),
				},
				encoding.ComposedWords{
					encoding.ConcatenatedWord{
						encoding.NewByteLinear(common.MixingBijection(rs, 8, round, shift(pos/4*4+0))),
						encoding.NewByteLinear(common.MixingBijection(rs, 8, round, shift(pos/4*4+1))),
						encoding.NewByteLinear(common.MixingBijection(rs, 8, round, shift(pos/4*4+2))),
						encoding.NewByteLinear(common.MixingBijection(rs, 8, round, shift(pos/4*4+3))),
					},
					encoding.NewWordLinear(mb),
					wordStepEncoding(rs, round, pos, common.Inside),
				},
				wide(round, pos),
			}

			// Encode the inverse of the mixing bijection from above in the MB^(-1) table for this round and position.
			mbInv, _ := mb.Invert()

			out.MBInverseTable[round][pos] = encoding.WordTable{
				byteRoundEncoding(rs, round, pos, common.Inside, common.NoShift),
				wordStepEncoding(rs, round, pos, common.Outside),
				mbInverseTable{mbInv, uint(pos) % 4},
			}
		}
	}

	// Generate the High and Low XOR Tables for reach round.
	out.HighXORTable = xorTables(rs, common.Inside, common.NoShift)
	out.LowXORTable = xorTables(rs, common.Outside, shift)

	// Generate the 10th T-Box/Output Mask slices and XOR tables.
	for pos := 0; pos < 16; pos++ {
		out.TBoxOutputMask[pos] = encoding.BlockTable{
			encoding.ComposedBytes{
				encoding.NewByteLinear(common.MixingBijection(rs, 8, 8, pos)),
				byteRoundEncoding(rs, 8, pos, common.Outside, common.NoShift),
			},
			blockMaskEncoding(rs, pos, common.Outside, shift),
			table.ComposedToBlock{
				Heads: skinny(pos),
				Tails: common.BlockMatrix{Linear: *outputMask, Position: pos},
			},
		}
	}

	out.OutputXORTables = common.BlockNibbleXORTables(
		maskEncoding(rs, common.Outside),
		xorEncoding(rs, 10, common.Outside),
		func(position int) encoding.Nibble { return encoding.IdentityByte{} },
	)
}