Example #1
0
// generateAffineMasks creates the random external masks for the construction.
func generateAffineMasks(rs *random.Source) (inputMask, outputMask encoding.BlockAffine) {
	var inputLinear, outputLinear matrix.Matrix
	common.GenerateMasks(rs, common.IndependentMasks{common.RandomMask, common.RandomMask}, &inputLinear, &outputLinear)

	reader := rs.Stream(make([]byte, 16))

	var inputConstant, outputConstant [16]byte
	reader.Read(inputConstant[:])
	reader.Read(outputConstant[:])

	inputMask = encoding.NewBlockAffine(inputLinear, inputConstant)
	outputMask = encoding.NewBlockAffine(outputLinear, outputConstant)

	return
}
Example #2
0
// generateAffineMasks creates the random external masks for the construction.
func generateAffineMasks(rs *random.Source) (inputMask, outputMask *blockAffine) {
	var inputLinear, outputLinear matrix.Matrix
	common.GenerateMasks(rs, common.IndependentMasks{common.RandomMask, common.RandomMask}, &inputLinear, &outputLinear)

	reader := rs.Stream(make([]byte, 16))

	inputConstant, outputConstant := matrix.NewRow(128), matrix.NewRow(128)
	reader.Read(inputConstant[:])
	reader.Read(outputConstant[:])

	inputMask = &blockAffine{linear: inputLinear, constant: inputConstant}
	outputMask = &blockAffine{linear: outputLinear, constant: outputConstant}

	return
}
Example #3
0
// GenerateDecryptionKeys creates a white-boxed version of the AES key `key` for decryption, with any non-determinism
// generated by `seed`.
func GenerateDecryptionKeys(key, seed []byte, opts common.KeyGenerationOpts) (out Construction, inputMask, outputMask matrix.Matrix) {
	rs := random.NewSource("Xiao Decryption", seed)

	constr := saes.Construction{key}
	roundKeys := constr.StretchedKey()

	// Apply UnShiftRows to round keys 10.
	constr.UnShiftRows(roundKeys[10])

	hidden := func(round, pos int) table.DoubleToWord {
		if round == 0 {
			return tBoxMixCol{
				[2]table.Byte{
					common.InvTBox{constr, roundKeys[10][pos+0], roundKeys[9][pos+0]},
					common.InvTBox{constr, roundKeys[10][pos+1], roundKeys[9][pos+1]},
				},
				unMixColumns,
				sideFromPos(pos),
			}
		} else if 0 < round && round < 9 {
			return tBoxMixCol{
				[2]table.Byte{
					common.InvTBox{constr, 0x00, roundKeys[9-round][pos+0]},
					common.InvTBox{constr, 0x00, roundKeys[9-round][pos+1]},
				},
				unMixColumns,
				sideFromPos(pos),
			}
		} else {
			return tBox{
				[2]table.Byte{
					common.InvTBox{constr, 0x00, roundKeys[0][pos+0]},
					common.InvTBox{constr, 0x00, roundKeys[0][pos+1]},
				},
				sideFromPos(pos),
			}
		}
	}

	common.GenerateMasks(&rs, opts, &inputMask, &outputMask)
	generateRoundMaterial(&rs, &out, hidden)
	generateBarriers(&rs, &out, &inputMask, &outputMask, &unShiftRows)

	return out, inputMask, outputMask
}
Example #4
0
// GenerateEncryptionKeys creates a white-boxed version of the AES key `key` for encryption, with any non-determinism
// generated by `seed`.
func GenerateEncryptionKeys(key, seed []byte, opts common.KeyGenerationOpts) (out Construction, inputMask, outputMask matrix.Matrix) {
	rs := random.NewSource("Xiao Encryption", seed)

	constr := saes.Construction{key}
	roundKeys := constr.StretchedKey()

	// Apply ShiftRows to round keys 0 to 9.
	for k := 0; k < 10; k++ {
		constr.ShiftRows(roundKeys[k])
	}

	hidden := func(round, pos int) table.DoubleToWord {
		if round == 9 {
			return tBox{
				[2]table.Byte{
					common.TBox{constr, roundKeys[9][pos+0], roundKeys[10][pos+0]},
					common.TBox{constr, roundKeys[9][pos+1], roundKeys[10][pos+1]},
				},
				sideFromPos(pos),
			}
		} else {
			return tBoxMixCol{
				[2]table.Byte{
					common.TBox{constr, roundKeys[round][pos+0], 0x00},
					common.TBox{constr, roundKeys[round][pos+1], 0x00},
				},
				mixColumns,
				sideFromPos(pos),
			}
		}
	}

	common.GenerateMasks(&rs, opts, &inputMask, &outputMask)
	generateRoundMaterial(&rs, &out, hidden)
	generateBarriers(&rs, &out, &inputMask, &outputMask, &shiftRows)

	return out, inputMask, outputMask
}
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{} },
	)
}