Commit 7cae31bb authored by Luc Libralesso's avatar Luc Libralesso
Browse files

add AES192 & AES256 options for the keyschedule + add unit tests

parent 42a2e126
......@@ -11,7 +11,8 @@ class AESKeyScheduleNode < CryptoDagNode
# @param subtable [Vec<u8> of size |u8|] byte substitution table
# @param rcon [u8]: round constant
def initialize(name:, input:, subtable:, rcon:)
raise "AESKeyScheduleNode: incorrect input size (#{input.dimensions} should be [4,4])" unless input.dimensions == [4,4]
raise "AESKeyScheduleNode: incorrect input size (#{input.dimensions} should be [4,X])" unless input.dimensions[0] == 4
nb_cols = input.dimensions[1] # computes nb_cols as it depends on the AES version (128,192,256)
output = DTable.new("#{name}", input.type, input.dimensions)
operators = []
@subtable = subtable
......@@ -57,14 +58,35 @@ class AESKeyScheduleNode < CryptoDagNode
output[i][0]
))
end
3.times do |i|
(nb_cols-1).times do |i|
index = i+1 # index in [1..3]
4.times do |j| # for each row of the column
operators.push(XorOperator.new(
input[j][index],
output[j][index-1],
output[j][index]
))
if nb_cols > 6 && index % nb_cols == 4 # if AES256 apply additional S-box
sub_vars = [
Variable.new("#{name}_sub_intermediate_0", 0..255),
Variable.new("#{name}_sub_intermediate_1", 0..255),
Variable.new("#{name}_sub_intermediate_2", 0..255),
Variable.new("#{name}_sub_intermediate_3", 0..255),
]
4.times do |j|
operators.push(SOperator.new(
output[j][index-1],
sub_vars[j],
@subtable
))
operators.push(XorOperator.new(
input[j][index],
sub_vars[j],
output[j][index]
))
end
else
4.times do |j| # for each row of the column
operators.push(XorOperator.new(
input[j][index],
output[j][index-1],
output[j][index]
))
end
end
end
super(inputs: [input], outputs: [output], operators: operators, name: name)
......
......@@ -103,4 +103,70 @@ class TestExecAesKeySchedule < Minitest::Unit::TestCase
0x9b, 0x98, 0x98, 0xc9, 0xf9, 0xfb, 0xfb, 0xaa, 0x9b, 0x98, 0x98, 0xc9, 0xf9, 0xfb, 0xfb, 0xaa
])
end
def test_aes192()
k = InputNode.new(name:"K0",dimensions:[4,6])
ks = AESKeyScheduleNode.new(name:"KS", input:k.outputs[0], subtable:@sbox, rcon:1)
computed_outputs = compute_set_of_operators(
[255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255],
[
k.outputs[0][0][0],k.outputs[0][1][0],k.outputs[0][2][0],k.outputs[0][3][0],
k.outputs[0][0][1],k.outputs[0][1][1],k.outputs[0][2][1],k.outputs[0][3][1],
k.outputs[0][0][2],k.outputs[0][1][2],k.outputs[0][2][2],k.outputs[0][3][2],
k.outputs[0][0][3],k.outputs[0][1][3],k.outputs[0][2][3],k.outputs[0][3][3],
k.outputs[0][0][4],k.outputs[0][1][4],k.outputs[0][2][4],k.outputs[0][3][4],
k.outputs[0][0][5],k.outputs[0][1][5],k.outputs[0][2][5],k.outputs[0][3][5],
],
[
ks.outputs[0][0][0],ks.outputs[0][1][0],ks.outputs[0][2][0],ks.outputs[0][3][0],
ks.outputs[0][0][1],ks.outputs[0][1][1],ks.outputs[0][2][1],ks.outputs[0][3][1],
ks.outputs[0][0][2],ks.outputs[0][1][2],ks.outputs[0][2][2],ks.outputs[0][3][2],
ks.outputs[0][0][3],ks.outputs[0][1][3],ks.outputs[0][2][3],ks.outputs[0][3][3],
ks.outputs[0][0][4],ks.outputs[0][1][4],ks.outputs[0][2][4],ks.outputs[0][3][4],
ks.outputs[0][0][5],ks.outputs[0][1][5],ks.outputs[0][2][5],ks.outputs[0][3][5],
],
ks.operators
)
assert_equal(computed_outputs, [
0xe8, 0xe9, 0xe9, 0xe9,
0x17, 0x16, 0x16, 0x16,
0xe8, 0xe9, 0xe9, 0xe9,
0x17, 0x16, 0x16, 0x16,
0xe8, 0xe9, 0xe9, 0xe9,
0x17, 0x16, 0x16, 0x16
])
end
def test_aes256()
k = InputNode.new(name:"K0",dimensions:[4,8])
ks = AESKeyScheduleNode.new(name:"KS", input:k.outputs[0], subtable:@sbox, rcon:1)
computed_outputs = compute_set_of_operators(
[255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255],
[
k.outputs[0][0][0],k.outputs[0][1][0],k.outputs[0][2][0],k.outputs[0][3][0],
k.outputs[0][0][1],k.outputs[0][1][1],k.outputs[0][2][1],k.outputs[0][3][1],
k.outputs[0][0][2],k.outputs[0][1][2],k.outputs[0][2][2],k.outputs[0][3][2],
k.outputs[0][0][3],k.outputs[0][1][3],k.outputs[0][2][3],k.outputs[0][3][3],
k.outputs[0][0][4],k.outputs[0][1][4],k.outputs[0][2][4],k.outputs[0][3][4],
k.outputs[0][0][5],k.outputs[0][1][5],k.outputs[0][2][5],k.outputs[0][3][5],
k.outputs[0][0][6],k.outputs[0][1][6],k.outputs[0][2][6],k.outputs[0][3][6],
k.outputs[0][0][7],k.outputs[0][1][7],k.outputs[0][2][7],k.outputs[0][3][7],
],
[
ks.outputs[0][0][0],ks.outputs[0][1][0],ks.outputs[0][2][0],ks.outputs[0][3][0],
ks.outputs[0][0][1],ks.outputs[0][1][1],ks.outputs[0][2][1],ks.outputs[0][3][1],
ks.outputs[0][0][2],ks.outputs[0][1][2],ks.outputs[0][2][2],ks.outputs[0][3][2],
ks.outputs[0][0][3],ks.outputs[0][1][3],ks.outputs[0][2][3],ks.outputs[0][3][3],
ks.outputs[0][0][4],ks.outputs[0][1][4],ks.outputs[0][2][4],ks.outputs[0][3][4],
ks.outputs[0][0][5],ks.outputs[0][1][5],ks.outputs[0][2][5],ks.outputs[0][3][5],
ks.outputs[0][0][6],ks.outputs[0][1][6],ks.outputs[0][2][6],ks.outputs[0][3][6],
ks.outputs[0][0][7],ks.outputs[0][1][7],ks.outputs[0][2][7],ks.outputs[0][3][7],
],
ks.operators
)
assert_equal(computed_outputs, [
0xe8, 0xe9, 0xe9, 0xe9, 0x17, 0x16, 0x16, 0x16, 0xe8, 0xe9, 0xe9, 0xe9, 0x17, 0x16, 0x16, 0x16,
0x0f, 0xb8, 0xb8, 0xb8, 0xf0, 0x47, 0x47, 0x47, 0x0f, 0xb8, 0xb8, 0xb8, 0xf0, 0x47, 0x47, 0x47,
])
end
end
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment