updated eel and eapml from more recent versions.

This commit is contained in:
Jocelyn Fiat
2012-06-15 14:57:12 +02:00
parent 0203e0fdc7
commit 5f3749e463
166 changed files with 396 additions and 578 deletions

View File

@@ -0,0 +1,150 @@
note
description: "Objects that ..."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
quote: "Reader, suppose you were an idiot. And suppose you were a member of Congress. But I repeat myself. - Mark Twain"
deferred class
AES_COMMON
inherit
ROTATE_FACILITIES
feature
S: SPECIAL [NATURAL_8]
-- The S box
once
create result.make_filled (0, 256)
result [0x00] := 0x63 result [0x01] := 0x7c result [0x02] := 0x77 result [0x03] := 0x7b result [0x04] := 0xf2 result [0x05] := 0x6b result [0x06] := 0x6f result [0x07] := 0xc5
result [0x08] := 0x30 result [0x09] := 0x01 result [0x0a] := 0x67 result [0x0b] := 0x2b result [0x0c] := 0xfe result [0x0d] := 0xd7 result [0x0e] := 0xab result [0x0f] := 0x76
result [0x10] := 0xca result [0x11] := 0x82 result [0x12] := 0xc9 result [0x13] := 0x7d result [0x14] := 0xfa result [0x15] := 0x59 result [0x16] := 0x47 result [0x17] := 0xf0
result [0x18] := 0xad result [0x19] := 0xd4 result [0x1a] := 0xa2 result [0x1b] := 0xaf result [0x1c] := 0x9c result [0x1d] := 0xa4 result [0x1e] := 0x72 result [0x1f] := 0xc0
result [0x20] := 0xb7 result [0x21] := 0xfd result [0x22] := 0x93 result [0x23] := 0x26 result [0x24] := 0x36 result [0x25] := 0x3f result [0x26] := 0xf7 result [0x27] := 0xcc
result [0x28] := 0x34 result [0x29] := 0xa5 result [0x2a] := 0xe5 result [0x2b] := 0xf1 result [0x2c] := 0x71 result [0x2d] := 0xd8 result [0x2e] := 0x31 result [0x2f] := 0x15
result [0x30] := 0x04 result [0x31] := 0xc7 result [0x32] := 0x23 result [0x33] := 0xc3 result [0x34] := 0x18 result [0x35] := 0x96 result [0x36] := 0x05 result [0x37] := 0x9a
result [0x38] := 0x07 result [0x39] := 0x12 result [0x3a] := 0x80 result [0x3b] := 0xe2 result [0x3c] := 0xeb result [0x3d] := 0x27 result [0x3e] := 0xb2 result [0x3f] := 0x75
result [0x40] := 0x09 result [0x41] := 0x83 result [0x42] := 0x2c result [0x43] := 0x1a result [0x44] := 0x1b result [0x45] := 0x6e result [0x46] := 0x5a result [0x47] := 0xa0
result [0x48] := 0x52 result [0x49] := 0x3b result [0x4a] := 0xd6 result [0x4b] := 0xb3 result [0x4c] := 0x29 result [0x4d] := 0xe3 result [0x4e] := 0x2f result [0x4f] := 0x84
result [0x50] := 0x53 result [0x51] := 0xd1 result [0x52] := 0x00 result [0x53] := 0xed result [0x54] := 0x20 result [0x55] := 0xfc result [0x56] := 0xb1 result [0x57] := 0x5b
result [0x58] := 0x6a result [0x59] := 0xcb result [0x5a] := 0xbe result [0x5b] := 0x39 result [0x5c] := 0x4a result [0x5d] := 0x4c result [0x5e] := 0x58 result [0x5f] := 0xcf
result [0x60] := 0xd0 result [0x61] := 0xef result [0x62] := 0xaa result [0x63] := 0xfb result [0x64] := 0x43 result [0x65] := 0x4d result [0x66] := 0x33 result [0x67] := 0x85
result [0x68] := 0x45 result [0x69] := 0xf9 result [0x6a] := 0x02 result [0x6b] := 0x7f result [0x6c] := 0x50 result [0x6d] := 0x3c result [0x6e] := 0x9f result [0x6f] := 0xa8
result [0x70] := 0x51 result [0x71] := 0xa3 result [0x72] := 0x40 result [0x73] := 0x8f result [0x74] := 0x92 result [0x75] := 0x9d result [0x76] := 0x38 result [0x77] := 0xf5
result [0x78] := 0xbc result [0x79] := 0xb6 result [0x7a] := 0xda result [0x7b] := 0x21 result [0x7c] := 0x10 result [0x7d] := 0xff result [0x7e] := 0xf3 result [0x7f] := 0xd2
result [0x80] := 0xcd result [0x81] := 0x0c result [0x82] := 0x13 result [0x83] := 0xec result [0x84] := 0x5f result [0x85] := 0x97 result [0x86] := 0x44 result [0x87] := 0x17
result [0x88] := 0xc4 result [0x89] := 0xa7 result [0x8a] := 0x7e result [0x8b] := 0x3d result [0x8c] := 0x64 result [0x8d] := 0x5d result [0x8e] := 0x19 result [0x8f] := 0x73
result [0x90] := 0x60 result [0x91] := 0x81 result [0x92] := 0x4f result [0x93] := 0xdc result [0x94] := 0x22 result [0x95] := 0x2a result [0x96] := 0x90 result [0x97] := 0x88
result [0x98] := 0x46 result [0x99] := 0xee result [0x9a] := 0xb8 result [0x9b] := 0x14 result [0x9c] := 0xde result [0x9d] := 0x5e result [0x9e] := 0x0b result [0x9f] := 0xdb
result [0xa0] := 0xe0 result [0xa1] := 0x32 result [0xa2] := 0x3a result [0xa3] := 0x0a result [0xa4] := 0x49 result [0xa5] := 0x06 result [0xa6] := 0x24 result [0xa7] := 0x5c
result [0xa8] := 0xc2 result [0xa9] := 0xd3 result [0xaa] := 0xac result [0xab] := 0x62 result [0xac] := 0x91 result [0xad] := 0x95 result [0xae] := 0xe4 result [0xaf] := 0x79
result [0xb0] := 0xe7 result [0xb1] := 0xc8 result [0xb2] := 0x37 result [0xb3] := 0x6d result [0xb4] := 0x8d result [0xb5] := 0xd5 result [0xb6] := 0x4e result [0xb7] := 0xa9
result [0xb8] := 0x6c result [0xb9] := 0x56 result [0xba] := 0xf4 result [0xbb] := 0xea result [0xbc] := 0x65 result [0xbd] := 0x7a result [0xbe] := 0xae result [0xbf] := 0x08
result [0xc0] := 0xba result [0xc1] := 0x78 result [0xc2] := 0x25 result [0xc3] := 0x2e result [0xc4] := 0x1c result [0xc5] := 0xa6 result [0xc6] := 0xb4 result [0xc7] := 0xc6
result [0xc8] := 0xe8 result [0xc9] := 0xdd result [0xca] := 0x74 result [0xcb] := 0x1f result [0xcc] := 0x4b result [0xcd] := 0xbd result [0xce] := 0x8b result [0xcf] := 0x8a
result [0xd0] := 0x70 result [0xd1] := 0x3e result [0xd2] := 0xb5 result [0xd3] := 0x66 result [0xd4] := 0x48 result [0xd5] := 0x03 result [0xd6] := 0xf6 result [0xd7] := 0x0e
result [0xd8] := 0x61 result [0xd9] := 0x35 result [0xda] := 0x57 result [0xdb] := 0xb9 result [0xdc] := 0x86 result [0xdd] := 0xc1 result [0xde] := 0x1d result [0xdf] := 0x9e
result [0xe0] := 0xe1 result [0xe1] := 0xf8 result [0xe2] := 0x98 result [0xe3] := 0x11 result [0xe4] := 0x69 result [0xe5] := 0xd9 result [0xe6] := 0x8e result [0xe7] := 0x94
result [0xe8] := 0x9b result [0xe9] := 0x1e result [0xea] := 0x87 result [0xeb] := 0xe9 result [0xec] := 0xce result [0xed] := 0x55 result [0xee] := 0x28 result [0xef] := 0xdf
result [0xf0] := 0x8c result [0xf1] := 0xa1 result [0xf2] := 0x89 result [0xf3] := 0x0d result [0xf4] := 0xbf result [0xf5] := 0xe6 result [0xf6] := 0x42 result [0xf7] := 0x68
result [0xf8] := 0x41 result [0xf9] := 0x99 result [0xfa] := 0x2d result [0xfb] := 0x0f result [0xfc] := 0xb0 result [0xfd] := 0x54 result [0xfe] := 0xbb result [0xff] := 0x16
end
Si: SPECIAL [NATURAL_8]
-- S inverse box
once
create result.make_filled (0, 256)
result [0x00] := 0x52 result [0x01] := 0x09 result [0x02] := 0x6a result [0x03] := 0xd5 result [0x04] := 0x30 result [0x05] := 0x36 result [0x06] := 0xa5 result [0x07] := 0x38
result [0x08] := 0xbf result [0x09] := 0x40 result [0x0a] := 0xa3 result [0x0b] := 0x9e result [0x0c] := 0x81 result [0x0d] := 0xf3 result [0x0e] := 0xd7 result [0x0f] := 0xfb
result [0x10] := 0x7c result [0x11] := 0xe3 result [0x12] := 0x39 result [0x13] := 0x82 result [0x14] := 0x9b result [0x15] := 0x2f result [0x16] := 0xff result [0x17] := 0x87
result [0x18] := 0x34 result [0x19] := 0x8e result [0x1a] := 0x43 result [0x1b] := 0x44 result [0x1c] := 0xc4 result [0x1d] := 0xde result [0x1e] := 0xe9 result [0x1f] := 0xcb
result [0x20] := 0x54 result [0x21] := 0x7b result [0x22] := 0x94 result [0x23] := 0x32 result [0x24] := 0xa6 result [0x25] := 0xc2 result [0x26] := 0x23 result [0x27] := 0x3d
result [0x28] := 0xee result [0x29] := 0x4c result [0x2a] := 0x95 result [0x2b] := 0x0b result [0x2c] := 0x42 result [0x2d] := 0xfa result [0x2e] := 0xc3 result [0x2f] := 0x4e
result [0x30] := 0x08 result [0x31] := 0x2e result [0x32] := 0xa1 result [0x33] := 0x66 result [0x34] := 0x28 result [0x35] := 0xd9 result [0x36] := 0x24 result [0x37] := 0xb2
result [0x38] := 0x76 result [0x39] := 0x5b result [0x3a] := 0xa2 result [0x3b] := 0x49 result [0x3c] := 0x6d result [0x3d] := 0x8b result [0x3e] := 0xd1 result [0x3f] := 0x25
result [0x40] := 0x72 result [0x41] := 0xf8 result [0x42] := 0xf6 result [0x43] := 0x64 result [0x44] := 0x86 result [0x45] := 0x68 result [0x46] := 0x98 result [0x47] := 0x16
result [0x48] := 0xd4 result [0x49] := 0xa4 result [0x4a] := 0x5c result [0x4b] := 0xcc result [0x4c] := 0x5d result [0x4d] := 0x65 result [0x4e] := 0xb6 result [0x4f] := 0x92
result [0x50] := 0x6c result [0x51] := 0x70 result [0x52] := 0x48 result [0x53] := 0x50 result [0x54] := 0xfd result [0x55] := 0xed result [0x56] := 0xb9 result [0x57] := 0xda
result [0x58] := 0x5e result [0x59] := 0x15 result [0x5a] := 0x46 result [0x5b] := 0x57 result [0x5c] := 0xa7 result [0x5d] := 0x8d result [0x5e] := 0x9d result [0x5f] := 0x84
result [0x60] := 0x90 result [0x61] := 0xd8 result [0x62] := 0xab result [0x63] := 0x00 result [0x64] := 0x8c result [0x65] := 0xbc result [0x66] := 0xd3 result [0x67] := 0x0a
result [0x68] := 0xf7 result [0x69] := 0xe4 result [0x6a] := 0x58 result [0x6b] := 0x05 result [0x6c] := 0xb8 result [0x6d] := 0xb3 result [0x6e] := 0x45 result [0x6f] := 0x06
result [0x70] := 0xd0 result [0x71] := 0x2c result [0x72] := 0x1e result [0x73] := 0x8f result [0x74] := 0xca result [0x75] := 0x3f result [0x76] := 0x0f result [0x77] := 0x02
result [0x78] := 0xc1 result [0x79] := 0xaf result [0x7a] := 0xbd result [0x7b] := 0x03 result [0x7c] := 0x01 result [0x7d] := 0x13 result [0x7e] := 0x8a result [0x7f] := 0x6b
result [0x80] := 0x3a result [0x81] := 0x91 result [0x82] := 0x11 result [0x83] := 0x41 result [0x84] := 0x4f result [0x85] := 0x67 result [0x86] := 0xdc result [0x87] := 0xea
result [0x88] := 0x97 result [0x89] := 0xf2 result [0x8a] := 0xcf result [0x8b] := 0xce result [0x8c] := 0xf0 result [0x8d] := 0xb4 result [0x8e] := 0xe6 result [0x8f] := 0x73
result [0x90] := 0x96 result [0x91] := 0xac result [0x92] := 0x74 result [0x93] := 0x22 result [0x94] := 0xe7 result [0x95] := 0xad result [0x96] := 0x35 result [0x97] := 0x85
result [0x98] := 0xe2 result [0x99] := 0xf9 result [0x9a] := 0x37 result [0x9b] := 0xe8 result [0x9c] := 0x1c result [0x9d] := 0x75 result [0x9e] := 0xdf result [0x9f] := 0x6e
result [0xa0] := 0x47 result [0xa1] := 0xf1 result [0xa2] := 0x1a result [0xa3] := 0x71 result [0xa4] := 0x1d result [0xa5] := 0x29 result [0xa6] := 0xc5 result [0xa7] := 0x89
result [0xa8] := 0x6f result [0xa9] := 0xb7 result [0xaa] := 0x62 result [0xab] := 0x0e result [0xac] := 0xaa result [0xad] := 0x18 result [0xae] := 0xbe result [0xaf] := 0x1b
result [0xb0] := 0xfc result [0xb1] := 0x56 result [0xb2] := 0x3e result [0xb3] := 0x4b result [0xb4] := 0xc6 result [0xb5] := 0xd2 result [0xb6] := 0x79 result [0xb7] := 0x20
result [0xb8] := 0x9a result [0xb9] := 0xdb result [0xba] := 0xc0 result [0xbb] := 0xfe result [0xbc] := 0x78 result [0xbd] := 0xcd result [0xbe] := 0x5a result [0xbf] := 0xf4
result [0xc0] := 0x1f result [0xc1] := 0xdd result [0xc2] := 0xa8 result [0xc3] := 0x33 result [0xc4] := 0x88 result [0xc5] := 0x07 result [0xc6] := 0xc7 result [0xc7] := 0x31
result [0xc8] := 0xb1 result [0xc9] := 0x12 result [0xca] := 0x10 result [0xcb] := 0x59 result [0xcc] := 0x27 result [0xcd] := 0x80 result [0xce] := 0xec result [0xcf] := 0x5f
result [0xd0] := 0x60 result [0xd1] := 0x51 result [0xd2] := 0x7f result [0xd3] := 0xa9 result [0xd4] := 0x19 result [0xd5] := 0xb5 result [0xd6] := 0x4a result [0xd7] := 0x0d
result [0xd8] := 0x2d result [0xd9] := 0xe5 result [0xda] := 0x7a result [0xdb] := 0x9f result [0xdc] := 0x93 result [0xdd] := 0xc9 result [0xde] := 0x9c result [0xdf] := 0xef
result [0xe0] := 0xa0 result [0xe1] := 0xe0 result [0xe2] := 0x3b result [0xe3] := 0x4d result [0xe4] := 0xae result [0xe5] := 0x2a result [0xe6] := 0xf5 result [0xe7] := 0xb0
result [0xe8] := 0xc8 result [0xe9] := 0xeb result [0xea] := 0xbb result [0xeb] := 0x3c result [0xec] := 0x83 result [0xed] := 0x53 result [0xee] := 0x99 result [0xef] := 0x61
result [0xf0] := 0x17 result [0xf1] := 0x2b result [0xf2] := 0x04 result [0xf3] := 0x7e result [0xf4] := 0xba result [0xf5] := 0x77 result [0xf6] := 0xd6 result [0xf7] := 0x26
result [0xf8] := 0xe1 result [0xf9] := 0x69 result [0xfa] := 0x14 result [0xfb] := 0x63 result [0xfc] := 0x55 result [0xfd] := 0x21 result [0xfe] := 0x0c result [0xff] := 0x7d
end
inv_sub_bytes (in: NATURAL_32): NATURAL_32
do
result := si [((in |>> 24) & 0xff).to_integer_32].to_natural_32 |<< 24
result := result | (si [((in |>> 16) & 0xff).to_integer_32].to_natural_32 |<< 16)
result := result | (si [((in |>> 8) & 0xff).to_integer_32].to_natural_32 |<< 8)
result := result | (si [(in & 0xff).to_integer_32]).to_natural_32
ensure
(result & 0xff).to_natural_8 = si [(in & 0xff).to_integer_32]
((result |>> 8) & 0xff).to_natural_8 = si [((in |>> 8) & 0xff).to_integer_32]
((result |>> 16) & 0xff).to_natural_8 = si [((in |>> 16) & 0xff).to_integer_32]
(result |>> 24).to_natural_8 = si [((in |>> 24) & 0xff).to_integer_32]
end
sub_bytes (in: NATURAL_32): NATURAL_32
do
result := s [((in |>> 24) & 0xff).to_integer_32].to_natural_32 |<< 24
result := result | (s [((in |>> 16) & 0xff).to_integer_32].to_natural_32 |<< 16)
result := result | (s [((in |>> 8) & 0xff).to_integer_32].to_natural_32 |<< 8)
result := result | (s [(in & 0xff).to_integer_32])
ensure
(result & 0xff).to_natural_8 = s [(in & 0xff).to_integer_32]
((result |>> 8) & 0xff).to_natural_8 = s [((in |>> 8) & 0xff).to_integer_32]
((result |>> 16) & 0xff).to_natural_8 = s [((in |>> 16) & 0xff).to_integer_32]
(result |>> 24).to_natural_8 = s [((in |>> 24) & 0xff).to_integer_32]
end
FFmulX (x: NATURAL_32): NATURAL_32
do
result := ((x & m2) |<< 1).bit_xor (((x & m1) |>> 7) * m3)
end
m1: NATURAL_32 = 0x80808080
m2: NATURAL_32 = 0x7f7f7f7f
m3: NATURAL_32 = 0x0000001b
feature
s_box_inverse: BOOLEAN
local
counter: INTEGER
do
from
counter := 0
result := true
until
counter > 255 or not result
loop
result := si [s [counter].to_integer_32].to_integer_32 = counter
counter := counter + 1
end
end
s_box_inverse_once: BOOLEAN
-- Is the s-box correct as long as nothing modifies it
once
result := s_box_inverse
end
invariant
s_box_inverse: s_box_inverse_once
end

View File

@@ -0,0 +1,531 @@
note
description: "Tagging class for various size/speed tradeoffs of AES"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,758 @@
note
description: "Objects that ..."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
quote: "The single most exciting thing you encounter in government is competence, because it's so rare. - Daniel Patrick Moynihan (1976)"
class
AES_KEY
inherit
DEBUG_OUTPUT
ECB_TARGET
rename
encrypt_block as ecb_encrypt,
decrypt_block as ecb_decrypt
end
CBC_TARGET
rename
encrypt_block as cbc_encrypt,
decrypt_block as cbc_decrypt
end
CFB_TARGET
rename
encrypt_block as cfb_encrypt
end
OFB_TARGET
rename
encrypt_block as ofb_encrypt
end
CTR_TARGET
rename
encrypt_block as ctr_encrypt
end
AES_COMMON
AES_ENGINE
create
make,
make_spec_128,
make_spec_196,
make_spec_256,
make_vector_128,
make_vector_196,
make_vector_256
feature -- Key creation
make (key_a: SPECIAL [NATURAL_8])
require
valid_lengths: key_a.count = 16 or key_a.count = 24 or key_a.count = 32
do
make_tables
key := key_a
expand_key_to_schedule (key_a)
end
feature -- Spec and test vector keys
make_vector_128
local
vector_key: SPECIAL [NATURAL_8]
do
create vector_key.make_filled (0, 16)
vector_key [0] := 0x00
vector_key [1] := 0x01
vector_key [2] := 0x02
vector_key [3] := 0x03
vector_key [4] := 0x04
vector_key [5] := 0x05
vector_key [6] := 0x06
vector_key [7] := 0x07
vector_key [8] := 0x08
vector_key [9] := 0x09
vector_key [10] := 0x0a
vector_key [11] := 0x0b
vector_key [12] := 0x0c
vector_key [13] := 0x0d
vector_key [14] := 0x0e
vector_key [15] := 0x0f
make (vector_key)
ensure
vector_128
end
make_vector_196
local
vector_key: SPECIAL [NATURAL_8]
do
create vector_key.make_filled (0, 24)
vector_key [0] := 0x00
vector_key [1] := 0x01
vector_key [2] := 0x02
vector_key [3] := 0x03
vector_key [4] := 0x04
vector_key [5] := 0x05
vector_key [6] := 0x06
vector_key [7] := 0x07
vector_key [8] := 0x08
vector_key [9] := 0x09
vector_key [10] := 0x0a
vector_key [11] := 0x0b
vector_key [12] := 0x0c
vector_key [13] := 0x0d
vector_key [14] := 0x0e
vector_key [15] := 0x0f
vector_key [16] := 0x10
vector_key [17] := 0x11
vector_key [18] := 0x12
vector_key [19] := 0x13
vector_key [20] := 0x14
vector_key [21] := 0x15
vector_key [22] := 0x16
vector_key [23] := 0x17
make (vector_key)
ensure
vector_196
end
make_vector_256
local
vector_key: SPECIAL [NATURAL_8]
do
create vector_key.make_filled (0, 32)
vector_key [0] := 0x00
vector_key [1] := 0x01
vector_key [2] := 0x02
vector_key [3] := 0x03
vector_key [4] := 0x04
vector_key [5] := 0x05
vector_key [6] := 0x06
vector_key [7] := 0x07
vector_key [8] := 0x08
vector_key [9] := 0x09
vector_key [10] := 0x0a
vector_key [11] := 0x0b
vector_key [12] := 0x0c
vector_key [13] := 0x0d
vector_key [14] := 0x0e
vector_key [15] := 0x0f
vector_key [16] := 0x10
vector_key [17] := 0x11
vector_key [18] := 0x12
vector_key [19] := 0x13
vector_key [20] := 0x14
vector_key [21] := 0x15
vector_key [22] := 0x16
vector_key [23] := 0x17
vector_key [24] := 0x18
vector_key [25] := 0x19
vector_key [26] := 0x1a
vector_key [27] := 0x1b
vector_key [28] := 0x1c
vector_key [29] := 0x1d
vector_key [30] := 0x1e
vector_key [31] := 0x1f
make (vector_key)
ensure
vector_256
end
make_spec_128
-- Make the FIPS-197 spec 128-bit key
local
spec_key: SPECIAL [NATURAL_8]
do
create spec_key.make_filled (0, 16)
spec_key[0] := 0x2b
spec_key[1] := 0x7e
spec_key[2] := 0x15
spec_key[3] := 0x16
spec_key[4] := 0x28
spec_key[5] := 0xae
spec_key[6] := 0xd2
spec_key[7] := 0xa6
spec_key[8] := 0xab
spec_key[9] := 0xf7
spec_key[10] := 0x15
spec_key[11] := 0x88
spec_key[12] := 0x09
spec_key[13] := 0xcf
spec_key[14] := 0x4f
spec_key[15] := 0x3c
make (spec_key)
ensure
spec_schedule: spec_128
end
make_spec_196
-- Make the FIPS-197 spec 196-bit key
local
spec_key: SPECIAL [NATURAL_8]
do
create spec_key.make_filled (0, 24)
spec_key [0] := 0x8e
spec_key [1] := 0x73
spec_key [2] := 0xb0
spec_key [3] := 0xf7
spec_key [4] := 0xda
spec_key [5] := 0x0e
spec_key [6] := 0x64
spec_key [7] := 0x52
spec_key [8] := 0xc8
spec_key [9] := 0x10
spec_key [10] := 0xf3
spec_key [11] := 0x2b
spec_key [12] := 0x80
spec_key [13] := 0x90
spec_key [14] := 0x79
spec_key [15] := 0xe5
spec_key [16] := 0x62
spec_key [17] := 0xf8
spec_key [18] := 0xea
spec_key [19] := 0xd2
spec_key [20] := 0x52
spec_key [21] := 0x2c
spec_key [22] := 0x6b
spec_key [23] := 0x7b
make (spec_key)
ensure
spec_schedule: spec_196
end
make_spec_256
-- Make the FIPS-197 spec 256-bit key
local
spec_key: SPECIAL [NATURAL_8]
do
create spec_key.make_filled (0, 32)
spec_key [0] := 0x60
spec_key [1] := 0x3d
spec_key [2] := 0xeb
spec_key [3] := 0x10
spec_key [4] := 0x15
spec_key [5] := 0xca
spec_key [6] := 0x71
spec_key [7] := 0xbe
spec_key [8] := 0x2b
spec_key [9] := 0x73
spec_key [10] := 0xae
spec_key [11] := 0xf0
spec_key [12] := 0x85
spec_key [13] := 0x7d
spec_key [14] := 0x77
spec_key [15] := 0x81
spec_key [16] := 0x1f
spec_key [17] := 0x35
spec_key [18] := 0x2c
spec_key [19] := 0x07
spec_key [20] := 0x3b
spec_key [21] := 0x61
spec_key [22] := 0x08
spec_key [23] := 0xd7
spec_key [24] := 0x2d
spec_key [25] := 0x98
spec_key [26] := 0x10
spec_key [27] := 0xa3
spec_key [28] := 0x09
spec_key [29] := 0x14
spec_key [30] := 0xdf
spec_key [31] := 0xf4
make (spec_key)
ensure
spec_schedule: spec_256
end
feature {ECB_TARGET} -- ECB
ecb_ready: BOOLEAN
do
result := true
end
ecb_encrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER)
do
encrypt (in, in_offset, out_array, out_offset)
end
ecb_decrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER)
do
decrypt (in, in_offset, out_array, out_offset)
end
feature {CBC_TARGET} -- CBC
cbc_ready: BOOLEAN
do
result := true
end
cbc_encrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER)
do
encrypt (in, in_offset, out_array, out_offset)
end
cbc_decrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER)
do
decrypt (in, in_offset, out_array, out_offset)
end
feature {CFB_TARGET} -- CFB
cfb_ready: BOOLEAN
do
result := true
end
cfb_encrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER)
do
encrypt (in, in_offset, out_array, out_offset)
end
feature {OFB_TARGET} -- OFB
ofb_ready: BOOLEAN
do
result := true
end
ofb_encrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER)
do
encrypt (in, in_offset, out_array, out_offset)
end
feature {CTR_TARGET} -- CTR
ctr_ready: BOOLEAN
do
result := true
end
ctr_encrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER)
do
encrypt (in, in_offset, out_array, out_offset)
end
feature -- Operations
encrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER)
require
in.valid_index (in_offset)
out_array.valid_index (out_offset)
in.valid_index (in_offset + 15)
out_array.valid_index (out_offset + 15)
do
unpack (in, in_offset)
encrypt_work (key_schedule.upper)
pack (out_array, out_offset)
end
decrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER)
require
in.valid_index (in_offset)
out_array.valid_index (out_offset)
in.valid_index (in_offset + 15)
out_array.valid_index (out_offset + 15)
do
unpack (in, in_offset)
decrypt_work (key_schedule.upper)
pack (out_array, out_offset)
end
feature --Implementation
expand_key_to_schedule (key_a: SPECIAL [NATURAL_8])
require
valid_lengths: key_a.count = 16 or key_a.count = 24 or key_a.count = 32
do
copy_key_to_schedule (key_a)
end
copy_key_to_schedule (key_a: SPECIAL [NATURAL_8])
require
valid_lengths: key_a.count = 16 or key_a.count = 24 or key_a.count = 32
do
copy_key_to_made_schedule (key_a, 4 * (rounds + 1), key_a.count // 4)
end
copy_key_to_made_schedule (key_a: SPECIAL [NATURAL_8] schedule_count: INTEGER key_word_count: INTEGER)
require
valid_lengths: key_a.count = 16 or key_a.count = 24 or key_a.count = 32
local
i: INTEGER
t: INTEGER
sub1, sub2, sub3, sub4: NATURAL_32
temp: NATURAL_32
do
create key_schedule.make_filled (0, schedule_count)
from
t := 0
i := 0
until
i > key.upper
loop
sub1 := key [i].to_natural_32 |<< 24
i := i + 1
sub2 := key [i].to_natural_32 |<< 16
i := i + 1
sub3 := key [i].to_natural_32 |<< 8
i := i + 1
sub4 := key [i].to_natural_32
i := i + 1
key_schedule [t] := sub1 | sub2 | sub3 | sub4
t := t + 1
end
from
i := key_a.count.bit_shift_right (2)
until
i >= schedule_count
loop
temp := key_schedule [i - 1]
if
i \\ key_word_count = 0
then
temp := sub_word (rot_word (temp)).bit_xor (round_constant [i // key_word_count])
elseif
key_word_count = 8 and i \\ key_word_count = 4
then
temp := sub_word(temp)
end
key_schedule [i] := key_schedule [i - key_word_count].bit_xor (temp)
i := i + 1
end
end
inv_mcol (x: NATURAL_32): NATURAL_32
local
f2: NATURAL_32
f4: NATURAL_32
f8: NATURAL_32
f9: NATURAL_32
do
f2 := FFmulX (x)
f4 := FFmulX (f2)
f8 := FFmulX (f4)
f9 := x.bit_xor(f8)
result := f2.bit_xor (f4).bit_xor (f8).bit_xor (rotate_right_32 (f2.bit_xor (f9), 8)).bit_xor (rotate_right_32 (f4.bit_xor (f9), 16)).bit_xor (rotate_right_32 (f9, 24))
end
round_constant: SPECIAL [NATURAL_32]
-- rcon
once
create result.make_filled (0, 11)
result [0] := 0x00000000
result [1] := 0x01000000
result [2] := 0x02000000
result [3] := 0x04000000
result [4] := 0x08000000
result [5] := 0x10000000
result [6] := 0x20000000
result [7] := 0x40000000
result [8] := 0x80000000
result [9] := 0x1b000000
result [10] := 0x36000000
end
rounds: INTEGER
require
key.count = 16 or key.count = 24 or key.count = 32
do
result := key.count.bit_shift_right (2) + 6
ensure
result = key.count // 4 + 6
end
key: SPECIAL [NATURAL_8]
sub_word (x_a: NATURAL_32): NATURAL_32
-- S-box word substitution
local
x: INTEGER
do
x := x_a.to_integer_32
result := result + s [(x |>> 24).bit_and (0xff)]
result := result.bit_shift_left (8)
result := result + s [(x |>> 16).bit_and (0xff)]
result := result.bit_shift_left (8)
result := result + s [(x |>> 8).bit_and (0xff)]
result := result.bit_shift_left (8)
result := result + s [x & 0xff]
end
rot_word (x: NATURAL_32): NATURAL_32
-- Rotate left 4 bits
do
result := x.bit_shift_right (24) | x.bit_shift_left (8)
end
key_schedule: SPECIAL [NATURAL_32]
-- FIPS W
spec_128_bit_schedule: BOOLEAN
-- Is `key_schedule' the one defined for the 128-bit spec key in FIPS-197
do
result := key_schedule.count = 44
result := result and key_schedule [0] = 0x2b7e1516 and key_schedule [1] = 0x28aed2a6 and key_schedule [2] = 0xabf71588 and key_schedule [3] = 0x09cf4f3c
result := result and key_schedule [4] = 0xa0fafe17 and key_schedule [5] = 0x88542cb1 and key_schedule [6] = 0x23a33939 and key_schedule [7] = 0x2a6c7605
result := result and key_schedule [8] = 0xf2c295f2 and key_schedule [9] = 0x7a96b943 and key_schedule [10] = 0x5935807a and key_schedule [11] = 0x7359f67f
result := result and key_schedule [12] = 0x3d80477d and key_schedule [13] = 0x4716fe3e and key_schedule [14] = 0x1e237e44 and key_schedule [15] = 0x6d7a883b
result := result and key_schedule [16] = 0xef44a541 and key_schedule [17] = 0xa8525b7f and key_schedule [18] = 0xb671253b and key_schedule [19] = 0xdb0bad00
result := result and key_schedule [20] = 0xd4d1c6f8 and key_schedule [21] = 0x7c839d87 and key_schedule [22] = 0xcaf2b8bc and key_schedule [23] = 0x11f915bc
result := result and key_schedule [24] = 0x6d88a37a and key_schedule [25] = 0x110b3efd and key_schedule [26] = 0xdbf98641 and key_schedule [27] = 0xca0093fd
result := result and key_schedule [28] = 0x4e54f70e and key_schedule [29] = 0x5f5fc9f3 and key_schedule [30] = 0x84a64fb2 and key_schedule [31] = 0x4ea6dc4f
result := result and key_schedule [32] = 0xead27321 and key_schedule [33] = 0xb58dbad2 and key_schedule [34] = 0x312bf560 and key_schedule [35] = 0x7f8d292f
result := result and key_schedule [36] = 0xac7766f3 and key_schedule [37] = 0x19fadc21 and key_schedule [38] = 0x28d12941 and key_schedule [39] = 0x575c006e
result := result and key_schedule [40] = 0xd014f9a8 and key_schedule [41] = 0xc9ee2589 and key_schedule [42] = 0xe13f0cc8 and key_schedule [43] = 0xb6630ca6
end
spec_196_bit_schedule: BOOLEAN
-- Is `key_schedule' the one defined for the 196-bit spec key in FIPS-197
do
result := key_schedule.count = 52
result := result and key_schedule [0] = 0x8e73b0f7 and key_schedule [1] = 0xda0e6452 and key_schedule [2] = 0xc810f32b and key_schedule [3] = 0x809079e5
result := result and key_schedule [4] = 0x62f8ead2 and key_schedule [5] = 0x522c6b7b and key_schedule [6] = 0xfe0c91f7 and key_schedule [7] = 0x2402f5a5
result := result and key_schedule [8] = 0xec12068e and key_schedule [9] = 0x6c827f6b and key_schedule [10] = 0x0e7a95b9 and key_schedule [11] = 0x5c56fec2
result := result and key_schedule [12] = 0x4db7b4bd and key_schedule [13] = 0x69b54118 and key_schedule [14] = 0x85a74796 and key_schedule [15] = 0xe92538fd
result := result and key_schedule [16] = 0xe75fad44 and key_schedule [17] = 0xbb095386 and key_schedule [18] = 0x485af057 and key_schedule [19] = 0x21efb14f
result := result and key_schedule [20] = 0xa448f6d9 and key_schedule [21] = 0x4d6dce24 and key_schedule [22] = 0xaa326360 and key_schedule [23] = 0x113b30e6
result := result and key_schedule [24] = 0xa25e7ed5 and key_schedule [25] = 0x83b1cf9a and key_schedule [26] = 0x27f93943 and key_schedule [27] = 0x6a94f767
result := result and key_schedule [28] = 0xc0a69407 and key_schedule [29] = 0xd19da4e1 and key_schedule [30] = 0xec1786eb and key_schedule [31] = 0x6fa64971
result := result and key_schedule [32] = 0x485f7032 and key_schedule [33] = 0x22cb8755 and key_schedule [34] = 0xe26d1352 and key_schedule [35] = 0x33f0b7b3
result := result and key_schedule [36] = 0x40beeb28 and key_schedule [37] = 0x2f18a259 and key_schedule [38] = 0x6747d26b and key_schedule [39] = 0x458c553e
result := result and key_schedule [40] = 0xa7e1466c and key_schedule [41] = 0x9411f1df and key_schedule [42] = 0x821f750a and key_schedule [43] = 0xad07d753
result := result and key_schedule [44] = 0xca400538 and key_schedule [45] = 0x8fcc5006 and key_schedule [46] = 0x282d166a and key_schedule [47] = 0xbc3ce7b5
result := result and key_schedule [48] = 0xe98ba06f and key_schedule [49] = 0x448c773c and key_schedule [50] = 0x8ecc7204 and key_schedule [51] = 0x01002202
end
spec_256_bit_schedule: BOOLEAN
-- Is `key_schedule' the one defined for the 256-bit spec key in FIPS-197
do
result := key_schedule.count = 60
result := result and key_schedule [0] = 0x603deb10 and key_schedule [1] = 0x15ca71be and key_schedule [2] = 0x2b73aef0 and key_schedule [3] = 0x857d7781
result := result and key_schedule [4] = 0x1f352c07 and key_schedule [5] = 0x3b6108d7 and key_schedule [6] = 0x2d9810a3 and key_schedule [7] = 0x0914dff4
result := result and key_schedule [8] = 0x9ba35411 and key_schedule [9] = 0x8e6925af and key_schedule [10] = 0xa51a8b5f and key_schedule [11] = 0x2067fcde
result := result and key_schedule [12] = 0xa8b09c1a and key_schedule [13] = 0x93d194cd and key_schedule [14] = 0xbe49846e and key_schedule [15] = 0xb75d5b9a
result := result and key_schedule [16] = 0xd59aecb8 and key_schedule [17] = 0x5bf3c917 and key_schedule [18] = 0xfee94248 and key_schedule [19] = 0xde8ebe96
result := result and key_schedule [20] = 0xb5a9328a and key_schedule [21] = 0x2678a647 and key_schedule [22] = 0x98312229 and key_schedule [23] = 0x2f6c79b3
result := result and key_schedule [24] = 0x812c81ad and key_schedule [25] = 0xdadf48ba and key_schedule [26] = 0x24360af2 and key_schedule [27] = 0xfab8b464
result := result and key_schedule [28] = 0x98c5bfc9 and key_schedule [29] = 0xbebd198e and key_schedule [30] = 0x268c3ba7 and key_schedule [31] = 0x09e04214
result := result and key_schedule [32] = 0x68007bac and key_schedule [33] = 0xb2df3316 and key_schedule [34] = 0x96e939e4 and key_schedule [35] = 0x6c518d80
result := result and key_schedule [36] = 0xc814e204 and key_schedule [37] = 0x76a9fb8a and key_schedule [38] = 0x5025c02d and key_schedule [39] = 0x59c58239
result := result and key_schedule [40] = 0xde136967 and key_schedule [41] = 0x6ccc5a71 and key_schedule [42] = 0xfa256395 and key_schedule [43] = 0x9674ee15
result := result and key_schedule [44] = 0x5886ca5d and key_schedule [45] = 0x2e2f31d7 and key_schedule [46] = 0x7e0af1fa and key_schedule [47] = 0x27cf73c3
result := result and key_schedule [48] = 0x749c47ab and key_schedule [49] = 0x18501dda and key_schedule [50] = 0xe2757e4f and key_schedule [51] = 0x7401905a
result := result and key_schedule [52] = 0xcafaaae3 and key_schedule [53] = 0xe4d59b34 and key_schedule [54] = 0x9adf6ace and key_schedule [55] = 0xbd10190d
result := result and key_schedule [56] = 0xfe4890d1 and key_schedule [57] = 0xe6188d0b and key_schedule [58] = 0x046df344 and key_schedule [59] = 0x706c631e
end
valid_spec_keys: BOOLEAN
local
key128: AES_KEY
key196: AES_KEY
key256: AES_KEY
do
create key128.make_spec_128
create key196.make_spec_196
create key256.make_spec_256
result := key128.spec_128_bit_schedule and key196.spec_196_bit_schedule and key256.spec_256_bit_schedule
end
valid_spec_keys_once: BOOLEAN
once
result := valid_spec_keys
end
feature -- Test if the key is a spec key
spec_128: BOOLEAN
do
result := key.count = 16
result := result and key [0] = 0x2b
result := result and key [1] = 0x7e
result := result and key [2] = 0x15
result := result and key [3] = 0x16
result := result and key [4] = 0x28
result := result and key [5] = 0xae
result := result and key [6] = 0xd2
result := result and key [7] = 0xa6
result := result and key [8] = 0xab
result := result and key [9] = 0xf7
result := result and key [10] = 0x15
result := result and key [11] = 0x88
result := result and key [12] = 0x09
result := result and key [13] = 0xcf
result := result and key [14] = 0x4f
result := result and key [15] = 0x3c
ensure
result implies spec_128_bit_schedule
end
spec_196: BOOLEAN
do
result := key.count = 24
result := result and key [0] = 0x8e
result := result and key [1] = 0x73
result := result and key [2] = 0xb0
result := result and key [3] = 0xf7
result := result and key [4] = 0xda
result := result and key [5] = 0x0e
result := result and key [6] = 0x64
result := result and key [7] = 0x52
result := result and key [8] = 0xc8
result := result and key [9] = 0x10
result := result and key [10] = 0xf3
result := result and key [11] = 0x2b
result := result and key [12] = 0x80
result := result and key [13] = 0x90
result := result and key [14] = 0x79
result := result and key [15] = 0xe5
result := result and key [16] = 0x62
result := result and key [17] = 0xf8
result := result and key [18] = 0xea
result := result and key [19] = 0xd2
result := result and key [20] = 0x52
result := result and key [21] = 0x2c
result := result and key [22] = 0x6b
result := result and key [23] = 0x7b
ensure
result implies spec_196_bit_schedule
end
spec_256: BOOLEAN
do
result := key.count = 32
result := result and key [0] = 0x60
result := result and key [1] = 0x3d
result := result and key [2] = 0xeb
result := result and key [3] = 0x10
result := result and key [4] = 0x15
result := result and key [5] = 0xca
result := result and key [6] = 0x71
result := result and key [7] = 0xbe
result := result and key [8] = 0x2b
result := result and key [9] = 0x73
result := result and key [10] = 0xae
result := result and key [11] = 0xf0
result := result and key [12] = 0x85
result := result and key [13] = 0x7d
result := result and key [14] = 0x77
result := result and key [15] = 0x81
result := result and key [16] = 0x1f
result := result and key [17] = 0x35
result := result and key [18] = 0x2c
result := result and key [19] = 0x07
result := result and key [20] = 0x3b
result := result and key [21] = 0x61
result := result and key [22] = 0x08
result := result and key [23] = 0xd7
result := result and key [24] = 0x2d
result := result and key [25] = 0x98
result := result and key [26] = 0x10
result := result and key [27] = 0xa3
result := result and key [28] = 0x09
result := result and key [29] = 0x14
result := result and key [30] = 0xdf
result := result and key [31] = 0xf4
ensure
result implies spec_256_bit_schedule
end
vector_128: BOOLEAN
do
result := key.count = 16
result := result and key [0] = 0x00
result := result and key [1] = 0x01
result := result and key [2] = 0x02
result := result and key [3] = 0x03
result := result and key [4] = 0x04
result := result and key [5] = 0x05
result := result and key [6] = 0x06
result := result and key [7] = 0x07
result := result and key [8] = 0x08
result := result and key [9] = 0x09
result := result and key [10] = 0x0a
result := result and key [11] = 0x0b
result := result and key [12] = 0x0c
result := result and key [13] = 0x0d
result := result and key [14] = 0x0e
result := result and key [15] = 0x0f
end
vector_196: BOOLEAN
do
result := key.count = 24
result := result and key [0] = 0x00
result := result and key [1] = 0x01
result := result and key [2] = 0x02
result := result and key [3] = 0x03
result := result and key [4] = 0x04
result := result and key [5] = 0x05
result := result and key [6] = 0x06
result := result and key [7] = 0x07
result := result and key [8] = 0x08
result := result and key [9] = 0x09
result := result and key [10] = 0x0a
result := result and key [11] = 0x0b
result := result and key [12] = 0x0c
result := result and key [13] = 0x0d
result := result and key [14] = 0x0e
result := result and key [15] = 0x0f
result := result and key [16] = 0x10
result := result and key [17] = 0x11
result := result and key [18] = 0x12
result := result and key [19] = 0x13
result := result and key [20] = 0x14
result := result and key [21] = 0x15
result := result and key [22] = 0x16
result := result and key [23] = 0x17
end
vector_256: BOOLEAN
do
result := key.count = 32
result := result and key [0] = 0x00
result := result and key [1] = 0x01
result := result and key [2] = 0x02
result := result and key [3] = 0x03
result := result and key [4] = 0x04
result := result and key [5] = 0x05
result := result and key [6] = 0x06
result := result and key [7] = 0x07
result := result and key [8] = 0x08
result := result and key [9] = 0x09
result := result and key [10] = 0x0a
result := result and key [11] = 0x0b
result := result and key [12] = 0x0c
result := result and key [13] = 0x0d
result := result and key [14] = 0x0e
result := result and key [15] = 0x0f
result := result and key [16] = 0x10
result := result and key [17] = 0x11
result := result and key [18] = 0x12
result := result and key [19] = 0x13
result := result and key [20] = 0x14
result := result and key [21] = 0x15
result := result and key [22] = 0x16
result := result and key [23] = 0x17
result := result and key [24] = 0x18
result := result and key [25] = 0x19
result := result and key [26] = 0x1a
result := result and key [27] = 0x1b
result := result and key [28] = 0x1c
result := result and key [29] = 0x1d
result := result and key [30] = 0x1e
result := result and key [31] = 0x1f
end
feature -- {DEBUG_OUTPUT}
debug_output: STRING
local
index: INTEGER_32
do
Result := "0x"
from
index := key.lower
until
index > key.upper
loop
Result.append (key [index].to_hex_string)
index := index + 1
variant
key.upper - index + 2
end
end
invariant
valid_spec_keys_once: valid_spec_keys_once
end