Files
EWF/library/crypto/eel/aes/aes_engine.e
jvelilla c9343688f3 Added eel and eapml in EWF libraries.
Removed them from gitmodule
2011-10-27 08:29:01 -03:00

532 lines
16 KiB
Plaintext

note
description: "Tagging class for various size/speed tradeoffs of AES"
author: "Colin LeMahieu"
date: "$Date$"
revision: "$Revision$"
quote: "Talk is cheap - except when Congress does it. - Cullen Hightower"
deferred class
AES_ENGINE
inherit
AES_COMMON
BYTE_FACILITIES
feature
make_tables
do
two_table := multiply_table (0x2)
three_table := multiply_table (0x3)
nine_table := multiply_table (0x9)
eleven_table := multiply_table (0xb)
thirteen_table := multiply_table (0xd)
fourteen_table := multiply_table (0xe)
end
block_size: INTEGER = 16
feature
mcol (x: NATURAL_32): NATURAL_32
local
f2: NATURAL_32
do
f2 := FFmulX (x)
result := f2.bit_xor (rotate_right_32 (x.bit_xor (f2), 8)).bit_xor (rotate_right_32 (x, 16)).bit_xor (rotate_right_32 (x, 24))
end
-- State matrix columns
column_0: NATURAL_32
column_1: NATURAL_32
column_2: NATURAL_32
column_3: NATURAL_32
feature --Prepare input blocks for processing and return
unpack (bytes: SPECIAL [NATURAL_8] offset: INTEGER)
require
bytes.valid_index (offset)
bytes.valid_index (offset + 15)
local
index: INTEGER
do
index := bytes.lower
column_0 := as_natural_32_be (bytes, offset + index)
column_1 := as_natural_32_be (bytes, offset + index + 4)
column_2 := as_natural_32_be (bytes, offset + index + 8)
column_3 := as_natural_32_be (bytes, offset + index + 12)
ensure
bytes_match_blocks (bytes)
end
pack (bytes: SPECIAL [NATURAL_8] offset: INTEGER)
require
bytes.valid_index (offset)
bytes.valid_index (offset + 15)
local
index: INTEGER
do
index := bytes.lower
from_natural_32_be (column_0, bytes, offset + index)
from_natural_32_be (column_1, bytes, offset + index + 4)
from_natural_32_be (column_2, bytes, offset + index + 8)
from_natural_32_be (column_3, bytes, offset + index + 12)
ensure
bytes_match_blocks (bytes)
end
bytes_match_blocks (bytes: SPECIAL [NATURAL_8]): BOOLEAN
do
result := true
result := result and bytes [0] = (column_0 |>> 24 & 0xff).to_natural_8
result := result and bytes [1] = (column_0 |>> 16 & 0xff).to_natural_8
result := result and bytes [2] = (column_0 |>> 8 & 0xff).to_natural_8
result := result and bytes [3] = (column_0 & 0xff).to_natural_8
result := result and bytes [4] = (column_1 |>> 24 & 0xff).to_natural_8
result := result and bytes [5] = (column_1 |>> 16 & 0xff).to_natural_8
result := result and bytes [6] = (column_1 |>> 8 & 0xff).to_natural_8
result := result and bytes [7] = (column_1 & 0xff).to_natural_8
result := result and bytes [8] = (column_2 |>> 24 & 0xff).to_natural_8
result := result and bytes [9] = (column_2 |>> 16 & 0xff).to_natural_8
result := result and bytes [10] = (column_2 |>> 8 & 0xff).to_natural_8
result := result and bytes [11] = (column_2 & 0xff).to_natural_8
result := result and bytes [12] = (column_3 |>> 24 & 0xff).to_natural_8
result := result and bytes [13] = (column_3 |>> 16 & 0xff).to_natural_8
result := result and bytes [14] = (column_3 |>> 8 & 0xff).to_natural_8
result := result and bytes [15] = (column_3 & 0xff).to_natural_8
ensure
bytes [0] = (column_0 & 0xff).to_natural_8
bytes [1] = (column_0 |>> 8 & 0xff).to_natural_8
bytes [2] = (column_0 |>> 16 & 0xff).to_natural_8
bytes [3] = (column_0 |>> 24 & 0xff).to_natural_8
bytes [4] = (column_1 & 0xff).to_natural_8
bytes [5] = (column_1 |>> 8 & 0xff).to_natural_8
bytes [6] = (column_1 |>> 16 & 0xff).to_natural_8
bytes [7] = (column_1 |>> 24 & 0xff).to_natural_8
bytes [8] = (column_2 & 0xff).to_natural_8
bytes [9] = (column_2 |>> 8 & 0xff).to_natural_8
bytes [10] = (column_2 |>> 16 & 0xff).to_natural_8
bytes [11] = (column_2 |>> 24 & 0xff).to_natural_8
bytes [12] = (column_3 & 0xff).to_natural_8
bytes [13] = (column_3 |>> 8 & 0xff).to_natural_8
bytes [14] = (column_3 |>> 16 & 0xff).to_natural_8
bytes [15] = (column_3 |>> 24 & 0xff).to_natural_8
end
feature
encrypt_work (max_index: INTEGER)
local
index: INTEGER
do
add_round_key (index)
from
index := 4
until
index >= max_index - 4
loop
sub_columns
shift_rows
mix_columns
add_round_key (index)
index := index + 4
variant
max_index - index + 2
end
sub_columns
shift_rows
add_round_key (index)
end
decrypt_work (max_index: INTEGER)
local
index: INTEGER
do
index := max_index - 3
add_round_key (index)
from
index := index - 4
until
index = 0
loop
inv_shift_rows
inv_sub_columns
add_round_key (index)
inv_mix_columns
index := index - 4
variant
index + 1
end
inv_shift_rows
inv_sub_columns
add_round_key (index)
end
inv_sub_columns
do
column_0 := inv_sub_bytes (column_0)
column_1 := inv_sub_bytes (column_1)
column_2 := inv_sub_bytes (column_2)
column_3 := inv_sub_bytes (column_3)
end
inv_mix_columns
do
column_0 := inv_mix_column (column_0)
column_1 := inv_mix_column (column_1)
column_2 := inv_mix_column (column_2)
column_3 := inv_mix_column (column_3)
end
mix_columns
do
column_0 := mix_column (column_0)
column_1 := mix_column (column_1)
column_2 := mix_column (column_2)
column_3 := mix_column (column_3)
end
inv_mix_column (in: NATURAL_32): NATURAL_32
do
result := inv_mix_0 (in)
result := result | inv_mix_1 (in)
result := result | inv_mix_2 (in)
result := result | inv_mix_3 (in)
end
inv_mix_0 (in: NATURAL_32): NATURAL_32
local
part_0: NATURAL_32
part_1: NATURAL_32
part_2: NATURAL_32
part_3: NATURAL_32
do
part_0 := multiply_and_reduce ((in |>> 24 & 0xff).to_natural_8, 0xe)
part_1 := multiply_and_reduce ((in |>> 16 & 0xff).to_natural_8, 0xb)
part_2 := multiply_and_reduce ((in |>> 8 & 0xff).to_natural_8, 0xd)
part_3 := multiply_and_reduce ((in & 0xff).to_natural_8, 0x9)
result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) |<< 24
end
inv_mix_1 (in: NATURAL_32): NATURAL_32
local
part_0: NATURAL_32
part_1: NATURAL_32
part_2: NATURAL_32
part_3: NATURAL_32
do
part_0 := multiply_and_reduce ((in |>> 24 & 0xff).to_natural_8, 0x9)
part_1 := multiply_and_reduce ((in |>> 16 & 0xff).to_natural_8, 0xe)
part_2 := multiply_and_reduce ((in |>> 8 & 0xff).to_natural_8, 0xb)
part_3 := multiply_and_reduce ((in & 0xff).to_natural_8, 0xd)
result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) |<< 16
end
inv_mix_2 (in: NATURAL_32): NATURAL_32
local
part_0: NATURAL_32
part_1: NATURAL_32
part_2: NATURAL_32
part_3: NATURAL_32
do
part_0 := multiply_and_reduce ((in |>> 24 & 0xff).to_natural_8, 0xd)
part_1 := multiply_and_reduce ((in |>> 16 & 0xff).to_natural_8, 0x9)
part_2 := multiply_and_reduce ((in |>> 8 & 0xff).to_natural_8, 0xe)
part_3 := multiply_and_reduce ((in & 0xff).to_natural_8, 0xb)
result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) |<< 8
end
inv_mix_3 (in: NATURAL_32): NATURAL_32
local
part_0: NATURAL_32
part_1: NATURAL_32
part_2: NATURAL_32
part_3: NATURAL_32
do
part_0 := multiply_and_reduce ((in |>> 24 & 0xff).to_natural_8, 0xb)
part_1 := multiply_and_reduce ((in |>> 16 & 0xff).to_natural_8, 0xd)
part_2 := multiply_and_reduce ((in |>> 8 & 0xff).to_natural_8, 0x9)
part_3 := multiply_and_reduce ((in & 0xff).to_natural_8, 0xe)
result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3)
end
mix_column (in: NATURAL_32): NATURAL_32
do
result := mix_0 (in)
result := result | mix_1 (in)
result := result | mix_2 (in)
result := result | mix_3 (in)
end
mix_0 (in: NATURAL_32): NATURAL_32
local
part_0: NATURAL_32
part_1: NATURAL_32
part_2: NATURAL_32
part_3: NATURAL_32
do
part_0 := multiply_and_reduce ((in |>> 24 & 0xff).to_natural_8, 0x2)
part_1 := multiply_and_reduce ((in |>> 16 & 0xff).to_natural_8, 0x3)
part_2 := in |>> 8 & 0xff
part_3 := in & 0xff
result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) |<< 24
end
mix_1 (in: NATURAL_32): NATURAL_32
local
part_0: NATURAL_32
part_1: NATURAL_32
part_2: NATURAL_32
part_3: NATURAL_32
do
part_0 := (in |>> 24 & 0xff)
part_1 := multiply_and_reduce ((in |>> 16 & 0xff).to_natural_8, 0x2)
part_2 := multiply_and_reduce ((in |>> 8 & 0xff).to_natural_8, 0x3)
part_3 := in & 0xff
result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) |<< 16
end
mix_2 (in: NATURAL_32): NATURAL_32
local
part_0: NATURAL_32
part_1: NATURAL_32
part_2: NATURAL_32
part_3: NATURAL_32
do
part_0 := in |>> 24 & 0xff
part_1 := in |>> 16 & 0xff
part_2 := multiply_and_reduce ((in |>> 8 & 0xff).to_natural_8, 0x2)
part_3 := multiply_and_reduce ((in & 0xff).to_natural_8, 0x3)
result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) |<< 8
end
mix_3 (in: NATURAL_32): NATURAL_32
local
part_0: NATURAL_32
part_1: NATURAL_32
part_2: NATURAL_32
part_3: NATURAL_32
do
part_0 := multiply_and_reduce ((in |>> 24 & 0xff).to_natural_8, 0x3)
part_1 := in |>> 16 & 0xff
part_2 := in |>> 8 & 0xff
part_3 := multiply_and_reduce ((in & 0xff).to_natural_8, 0x2)
result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3)
end
sub_columns
do
column_0 := sub_bytes (column_0)
column_1 := sub_bytes (column_1)
column_2 := sub_bytes (column_2)
column_3 := sub_bytes (column_3)
end
inv_shift_rows
local
column_0_new: NATURAL_32
column_1_new: NATURAL_32
column_2_new: NATURAL_32
column_3_new: NATURAL_32
do
column_0_new := column_0 & 0xff000000
column_0_new := column_0_new | (column_3 & 0x00ff0000)
column_0_new := column_0_new | (column_2 & 0x0000ff00)
column_0_new := column_0_new | (column_1 & 0x000000ff)
column_1_new := column_1 & 0xff000000
column_1_new := column_1_new | (column_0 & 0x00ff0000)
column_1_new := column_1_new | (column_3 & 0x0000ff00)
column_1_new := column_1_new | (column_2 & 0x000000ff)
column_2_new := column_2 & 0xff000000
column_2_new := column_2_new | (column_1 & 0x00ff0000)
column_2_new := column_2_new | (column_0 & 0x0000ff00)
column_2_new := column_2_new | (column_3 & 0x000000ff)
column_3_new := column_3 & 0xff000000
column_3_new := column_3_new | (column_2 & 0x00ff0000)
column_3_new := column_3_new | (column_1 & 0x0000ff00)
column_3_new := column_3_new | (column_0 & 0x000000ff)
column_0 := column_0_new
column_1 := column_1_new
column_2 := column_2_new
column_3 := column_3_new
ensure
column_0 |>> 24 & 0xff = old column_0 |>> 24 & 0xff
column_0 |>> 16 & 0xff = old column_3 |>> 16 & 0xff
column_0 |>> 8 & 0xff = old column_2 |>> 8 & 0xff
column_0 & 0xff = old column_1 & 0xff
column_1 |>> 24 & 0xff = old column_1 |>> 24 & 0xff
column_1 |>> 16 & 0xff = old column_0 |>> 16 & 0xff
column_1 |>> 8 & 0xff = old column_3 |>> 8 & 0xff
column_1 & 0xff = old column_2 & 0xff
column_2 |>> 24 & 0xff = old column_2 |>> 24& 0xff
column_2 |>> 16 & 0xff = old column_1 |>> 16 & 0xff
column_2 |>> 8 & 0xff = old column_0 |>> 8 & 0xff
column_2 & 0xff = old column_3 & 0xff
column_3 |>> 24& 0xff = old column_3 |>> 24 & 0xff
column_3 |>> 16 & 0xff = old column_2 |>> 16 & 0xff
column_3 |>> 8 & 0xff = old column_1 |>> 8 & 0xff
column_3 & 0xff = old column_0 & 0xff
end
shift_rows
local
column_0_new: NATURAL_32
column_1_new: NATURAL_32
column_2_new: NATURAL_32
column_3_new: NATURAL_32
do
column_0_new := column_0 & 0xff000000
column_0_new := column_0_new | (column_1 & 0x00ff0000)
column_0_new := column_0_new | (column_2 & 0x0000ff00)
column_0_new := column_0_new | (column_3 & 0x000000ff)
column_1_new := column_1 & 0xff000000
column_1_new := column_1_new | (column_2 & 0x00ff0000)
column_1_new := column_1_new | (column_3 & 0x0000ff00)
column_1_new := column_1_new | (column_0 & 0x000000ff)
column_2_new := column_2 & 0xff000000
column_2_new := column_2_new | (column_3 & 0x00ff0000)
column_2_new := column_2_new | (column_0 & 0x0000ff00)
column_2_new := column_2_new | (column_1 & 0x000000ff)
column_3_new := column_3 & 0xff000000
column_3_new := column_3_new | (column_0 & 0x00ff0000)
column_3_new := column_3_new | (column_1 & 0x0000ff00)
column_3_new := column_3_new | (column_2 & 0x000000ff)
column_0 := column_0_new
column_1 := column_1_new
column_2 := column_2_new
column_3 := column_3_new
ensure
column_0 |>> 24 & 0xff = old column_0 |>> 24 & 0xff
column_0 |>> 16 & 0xff = old column_1 |>> 16 & 0xff
column_0 |>> 8 & 0xff = old column_2 |>> 8 & 0xff
column_0 & 0xff = old column_3 & 0xff
column_1 |>> 24 & 0xff = old column_1 |>> 24 & 0xff
column_1 |>> 16 & 0xff = old column_2 |>> 16 & 0xff
column_1 |>> 8 & 0xff = old column_3 |>> 8 & 0xff
column_1 & 0xff = old column_0 & 0xff
column_2 |>> 24 & 0xff = old column_2 |>> 24 & 0xff
column_2 |>> 16 & 0xff = old column_3 |>> 16 & 0xff
column_2 |>> 8 & 0xff = old column_0 |>> 8 & 0xff
column_2 & 0xff = old column_1 & 0xff
column_3 |>> 24 & 0xff = old column_3 |>> 24 & 0xff
column_3 |>> 16 & 0xff = old column_0 |>> 16 & 0xff
column_3 |>> 8 & 0xff = old column_1 |>> 8 & 0xff
column_3 & 0xff = old column_2 & 0xff
end
add_round_key (schedule_index: INTEGER)
do
column_0 := column_0.bit_xor (key_schedule [schedule_index])
column_1 := column_1.bit_xor (key_schedule [schedule_index + 1])
column_2 := column_2.bit_xor (key_schedule [schedule_index + 2])
column_3 := column_3.bit_xor (key_schedule [schedule_index + 3])
end
feature -- GF(2^8) arithmetic
add (one: INTEGER two: INTEGER): INTEGER
do
result := one.bit_xor (two)
end
multiply_and_reduce (field: NATURAL_8 multiplier: NATURAL_8): NATURAL_8
local
field_expanded: NATURAL_32
do
field_expanded := multiply (field, multiplier)
result := reduce (field_expanded)
end
multiply (field: NATURAL_8 multiplier: NATURAL_8): NATURAL_32
local
counter: INTEGER
field_expanded: NATURAL_32
do
field_expanded := field
from
counter := 0
until
counter > 7
loop
if
multiplier.bit_test (counter)
then
result := result.bit_xor (field_expanded.bit_shift_left (counter))
end
counter := counter + 1
end
end
reduce (in: NATURAL_32): NATURAL_8
local
counter: INTEGER
result_expanded: NATURAL_32
do
from
counter := 31
result_expanded := in
until
counter = 7
loop
if
result_expanded.bit_test (counter)
then
result_expanded := result_expanded.bit_xor (reducer.bit_shift_right (31 - counter))
end
counter := counter - 1
end
check
result_expanded <= result.max_value
end
result := result_expanded.to_natural_8
end
s_box (in: NATURAL_8): NATURAL_8
do
result := s [in.to_integer_32]
end
two_table: SPECIAL [NATURAL_8]
-- Table of {02} * x in GF(2^8)
three_table: SPECIAL [NATURAL_8]
-- Table of {03} * x in GF(2^8)
nine_table: SPECIAL [NATURAL_8]
-- Table of {09} * x in GF(2^8)
eleven_table: SPECIAL [NATURAL_8]
-- Table of {0b} * x in GF(2^8)
thirteen_table: SPECIAL [NATURAL_8]
-- Table of {0d} * x in GF(2^8)
fourteen_table: SPECIAL [NATURAL_8]
-- Table of {0E} * x in GF(2^8)
multiply_table (multiplier: NATURAL_8): SPECIAL [NATURAL_8]
local
counter: INTEGER
do
create result.make_filled (0, 256)
from
counter := 0
until
counter = 256
loop
result [counter] := multiply_and_reduce (counter.to_natural_8, multiplier)
counter := counter + 1
variant
256 - counter + 1
end
end
reducer: NATURAL_32 = 0x8d800000
feature {NONE}
byte_sink (in: NATURAL_8)
do
do_nothing
end
key_schedule: SPECIAL [NATURAL_32]
deferred
end
end