Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Luc Libralesso
cryptodag
Commits
997c5110
Commit
997c5110
authored
Dec 23, 2020
by
Luc Libralesso
Browse files
add AES keyschedule + tests keyschedule
parent
a6320b1c
Changes
4
Hide whitespace changes
Inline
Side-by-side
nodes/aeskeyschedule.rb
0 → 100644
View file @
997c5110
# AES Key Schedule operator. Takes as a parameter a key and expands it
require_relative
"../cryptodag.rb"
require_relative
"../operators/elementary.rb"
class
AESKeyScheduleNode
<
CryptoDagNode
##
# @param name [String]: name of the node
# @param input [DTable<Variable> of size 4x4] input variables
# @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
]
output
=
DTable
.
new
(
"
#{
name
}
"
,
input
.
type
,
input
.
dimensions
)
operators
=
[]
@subtable
=
subtable
# apply rotation (first byte becomes last, second first, ...)
rotated_bytes
=
[
Variable
.
new
(
"
#{
name
}
_rot_0"
,
0
..
255
),
Variable
.
new
(
"
#{
name
}
_rot_1"
,
0
..
255
),
Variable
.
new
(
"
#{
name
}
_rot_2"
,
0
..
255
),
Variable
.
new
(
"
#{
name
}
_rot_3"
,
0
..
255
),
]
4
.
times
do
|
i
|
operators
.
push
(
EqualityOperator
.
new
(
input
[(
i
+
1
)
%
4
][
3
],
# last column of the input
rotated_bytes
[
i
],
))
end
# apply substitution
sub_rotated_bytes
=
[
Variable
.
new
(
"
#{
name
}
_sub_rot_0"
,
0
..
255
),
Variable
.
new
(
"
#{
name
}
_sub_rot_1"
,
0
..
255
),
Variable
.
new
(
"
#{
name
}
_sub_rot_2"
,
0
..
255
),
Variable
.
new
(
"
#{
name
}
_sub_rot_3"
,
0
..
255
),
]
4
.
times
do
|
i
|
operators
.
push
(
SOperator
.
new
(
rotated_bytes
[
i
],
sub_rotated_bytes
[
i
],
@subtable
))
end
rcon_col
=
[
Variable
.
new
(
"rcon_
#{
name
}
_0"
,
0
..
256
,
value
=
rcon
),
Variable
.
new
(
"rcon_
#{
name
}
_0"
,
0
..
256
,
value
=
0
),
Variable
.
new
(
"rcon_
#{
name
}
_0"
,
0
..
256
,
value
=
0
),
Variable
.
new
(
"rcon_
#{
name
}
_0"
,
0
..
256
,
value
=
0
)
]
# construct first column of the output (sub_rotated_bytes XOR [first input col] XOR [Rcon,0,0,0])
4
.
times
do
|
i
|
operators
.
push
(
XorOperator
.
new
(
sub_rotated_bytes
[
i
],
input
[
i
][
0
],
rcon_col
[
i
],
output
[
i
][
0
]
))
end
3
.
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
]
))
end
end
super
(
inputs:
[
input
],
outputs:
[
output
],
operators:
operators
,
name:
name
)
end
end
operators/elementary.rb
View file @
997c5110
...
...
@@ -132,7 +132,6 @@ class MixColumnsOperator < CryptoOperator
@inputs
.
length
.
times
do
|
i
|
tmp
=
0
@inputs
.
length
.
times
do
|
j
|
# tmp = tmp ^ compute_galois_multiply(values[j], @m[i][j])
tmp
=
tmp
^
g_mul
(
values
[
j
],
@m
[
i
][
j
])
end
outputs
.
push
(
tmp
)
...
...
@@ -140,34 +139,23 @@ class MixColumnsOperator < CryptoOperator
check_outputs
(
outputs
)
return
outputs
end
end
def
g_mul
(
a
,
b
)
p
=
0
8
.
times
do
|
counter
|
if
(
b
&
1
)
!=
0
p
^=
a
;
end
hi_bit_set
=
(
a
&
0x80
)
!=
0
a
<<=
1
if
hi_bit_set
a
^=
0x1B
end
b
>>=
1
## Galois Field multiplication (a.b)
# @return a.b
def
g_mul
(
a
,
b
)
p
=
0
8
.
times
do
|
counter
|
if
(
b
&
1
)
!=
0
p
^=
a
;
end
return
p
%
256
hi_bit_set
=
(
a
&
0x80
)
!=
0
a
<<=
1
if
hi_bit_set
a
^=
0x1B
end
b
>>=
1
end
# def compute_galois_multiply(e, m)
# if m == 0
# return 0
# elsif m == 1
# return e
# elsif m == 2
# return (e*2) % 256
# elsif m == 3
# return ((e*2)^e) % 256
# else
# raise "compute_galois_multiply: m=#{m} not supported yet (for now, it should be <= 3)"
# end
# end
end
return
p
%
256
end
\ No newline at end of file
simulate_cryptodag.rb
View file @
997c5110
...
...
@@ -28,15 +28,24 @@ def compute_set_of_operators(input_values, input_variables, output_variables, op
end
end
dg
=
RGL
::
DirectedAdjacencyGraph
[
*
adj_list
]
sorted_vertices
=
dg
.
topsort_iterator
.
to_a
sorted_vertices
=
sorted_vertices
.
filter
{
|
v
|
v
.
class
<=
CryptoOperator
}
# feed a variable map with initial values
value_map
=
{}
# associates variables to their value
input_values
.
length
.
times
do
|
i
|
value_map
[
input_variables
[
i
]]
=
input_values
[
i
]
end
# register variables where a value is already registered
for
e
in
adj_list
if
e
.
class
<=
Variable
if
e
.
value
!=
nil
value_map
[
e
]
=
e
.
value
end
end
end
dg
=
RGL
::
DirectedAdjacencyGraph
[
*
adj_list
]
sorted_vertices
=
dg
.
topsort_iterator
.
to_a
sorted_vertices
=
sorted_vertices
.
filter
{
|
v
|
v
.
class
<=
CryptoOperator
}
# execute operators
sorted_vertices
.
each
do
|
op
|
raise
"compute_set_of_operators: should be a CryptoOperator (current
#{
op
.
class
}
)"
unless
op
.
class
<=
CryptoOperator
...
...
@@ -45,7 +54,7 @@ def compute_set_of_operators(input_values, input_variables, output_variables, op
if
value_map
.
include?
(
e
)
values
.
push
(
value_map
[
e
])
else
raise
"compute_set_of_operators: bad topological sort"
raise
"compute_set_of_operators: bad topological sort
(variable
#{
e
}
should be computed)
"
end
end
outputs
=
op
.
compute
(
values
)
...
...
tests/nodes/exec_aes_keyschedule.rb
0 → 100755
View file @
997c5110
#!/usr/bin/ruby
## test AESKeyScheduleNode
require_relative
"../../nodes/input.rb"
require_relative
"../../nodes/aeskeyschedule.rb"
require_relative
"../../simulate_cryptodag.rb"
require
"minitest/autorun"
require
"pry"
class
TestExecAesKeySchedule
<
Minitest
::
Unit
::
TestCase
def
setup
()
@sbox
=
[
0x63
,
0x7C
,
0x77
,
0x7B
,
0xF2
,
0x6B
,
0x6F
,
0xC5
,
0x30
,
0x01
,
0x67
,
0x2B
,
0xFE
,
0xD7
,
0xAB
,
0x76
,
0xCA
,
0x82
,
0xC9
,
0x7D
,
0xFA
,
0x59
,
0x47
,
0xF0
,
0xAD
,
0xD4
,
0xA2
,
0xAF
,
0x9C
,
0xA4
,
0x72
,
0xC0
,
0xB7
,
0xFD
,
0x93
,
0x26
,
0x36
,
0x3F
,
0xF7
,
0xCC
,
0x34
,
0xA5
,
0xE5
,
0xF1
,
0x71
,
0xD8
,
0x31
,
0x15
,
0x04
,
0xC7
,
0x23
,
0xC3
,
0x18
,
0x96
,
0x05
,
0x9A
,
0x07
,
0x12
,
0x80
,
0xE2
,
0xEB
,
0x27
,
0xB2
,
0x75
,
0x09
,
0x83
,
0x2C
,
0x1A
,
0x1B
,
0x6E
,
0x5A
,
0xA0
,
0x52
,
0x3B
,
0xD6
,
0xB3
,
0x29
,
0xE3
,
0x2F
,
0x84
,
0x53
,
0xD1
,
0x00
,
0xED
,
0x20
,
0xFC
,
0xB1
,
0x5B
,
0x6A
,
0xCB
,
0xBE
,
0x39
,
0x4A
,
0x4C
,
0x58
,
0xCF
,
0xD0
,
0xEF
,
0xAA
,
0xFB
,
0x43
,
0x4D
,
0x33
,
0x85
,
0x45
,
0xF9
,
0x02
,
0x7F
,
0x50
,
0x3C
,
0x9F
,
0xA8
,
0x51
,
0xA3
,
0x40
,
0x8F
,
0x92
,
0x9D
,
0x38
,
0xF5
,
0xBC
,
0xB6
,
0xDA
,
0x21
,
0x10
,
0xFF
,
0xF3
,
0xD2
,
0xCD
,
0x0C
,
0x13
,
0xEC
,
0x5F
,
0x97
,
0x44
,
0x17
,
0xC4
,
0xA7
,
0x7E
,
0x3D
,
0x64
,
0x5D
,
0x19
,
0x73
,
0x60
,
0x81
,
0x4F
,
0xDC
,
0x22
,
0x2A
,
0x90
,
0x88
,
0x46
,
0xEE
,
0xB8
,
0x14
,
0xDE
,
0x5E
,
0x0B
,
0xDB
,
0xE0
,
0x32
,
0x3A
,
0x0A
,
0x49
,
0x06
,
0x24
,
0x5C
,
0xC2
,
0xD3
,
0xAC
,
0x62
,
0x91
,
0x95
,
0xE4
,
0x79
,
0xE7
,
0xC8
,
0x37
,
0x6D
,
0x8D
,
0xD5
,
0x4E
,
0xA9
,
0x6C
,
0x56
,
0xF4
,
0xEA
,
0x65
,
0x7A
,
0xAE
,
0x08
,
0xBA
,
0x78
,
0x25
,
0x2E
,
0x1C
,
0xA6
,
0xB4
,
0xC6
,
0xE8
,
0xDD
,
0x74
,
0x1F
,
0x4B
,
0xBD
,
0x8B
,
0x8A
,
0x70
,
0x3E
,
0xB5
,
0x66
,
0x48
,
0x03
,
0xF6
,
0x0E
,
0x61
,
0x35
,
0x57
,
0xB9
,
0x86
,
0xC1
,
0x1D
,
0x9E
,
0xE1
,
0xF8
,
0x98
,
0x11
,
0x69
,
0xD9
,
0x8E
,
0x94
,
0x9B
,
0x1E
,
0x87
,
0xE9
,
0xCE
,
0x55
,
0x28
,
0xDF
,
0x8C
,
0xA1
,
0x89
,
0x0D
,
0xBF
,
0xE6
,
0x42
,
0x68
,
0x41
,
0x99
,
0x2D
,
0x0F
,
0xB0
,
0x54
,
0xBB
,
0x16
]
end
def
test_a
()
k
=
InputNode
.
new
(
name
:"K0"
,
dimensions
:[
4
,
4
])
ks
=
AESKeyScheduleNode
.
new
(
name
:"KS"
,
input
:k
.
outputs
[
0
],
subtable
:@sbox
,
rcon
:
1
)
computed_outputs
=
compute_set_of_operators
(
[
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
],
[
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
],
],
[
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
.
operators
)
assert_equal
(
computed_outputs
,
[
0x62
,
0x63
,
0x63
,
0x63
,
0x62
,
0x63
,
0x63
,
0x63
,
0x62
,
0x63
,
0x63
,
0x63
,
0x62
,
0x63
,
0x63
,
0x63
])
end
def
test_b
()
k
=
InputNode
.
new
(
name
:"K0"
,
dimensions
:[
4
,
4
])
ks
=
AESKeyScheduleNode
.
new
(
name
:"KS"
,
input
:k
.
outputs
[
0
],
subtable
:@sbox
,
rcon
:
2
)
computed_outputs
=
compute_set_of_operators
(
[
0x62
,
0x63
,
0x63
,
0x63
,
0x62
,
0x63
,
0x63
,
0x63
,
0x62
,
0x63
,
0x63
,
0x63
,
0x62
,
0x63
,
0x63
,
0x63
],
[
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
],
],
[
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
.
operators
)
assert_equal
(
computed_outputs
,
[
0x9b
,
0x98
,
0x98
,
0xc9
,
0xf9
,
0xfb
,
0xfb
,
0xaa
,
0x9b
,
0x98
,
0x98
,
0xc9
,
0xf9
,
0xfb
,
0xfb
,
0xaa
])
end
end
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment