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
ea126c55
Commit
ea126c55
authored
Dec 21, 2020
by
Luc Libralesso
Browse files
add computation operators + tests for eq, xor, S, mixcolumns
parent
0cd65368
Changes
9
Hide whitespace changes
Inline
Side-by-side
cryptodag.rb
View file @
ea126c55
...
...
@@ -14,19 +14,6 @@ require_relative "constraints/constraints"
require_relative
"constraints/variables"
require_relative
"constraints/model"
# ## encodes an atomic part of the memory in a cryptosystem
# class CryptoAtom
# attr_accessor :variable
# def initialize(variable)
# raise "CryptoAtom: variable should be of type Variable" unless variable.class == Variable
# @variable = variable
# end
# def register_to_model(model)
# raise "CryptoAtom: model should be of class Model" unless model.kind_of?(Model)
# model.add_variables(@variable)
# end
# end
## represents an elementary operator (Equality, S-box, )
# # examples
...
...
@@ -38,12 +25,14 @@ class CryptoOperator
attr_accessor
:inputs
# vector of input variables
attr_accessor
:outputs
# vector of output variables
attr_accessor
:constraints
# constraints implementing the operator
attr_accessor
:global_constraints
# global constraints that should be registered while creating the CP model
##
# @param inputs [Vec<Variable>]
# @param outputs [Vec<Variable>]
# @param constraints [Vec<Constraint>]
protected
def
initialize
(
inputs
:,
outputs
:,
constraints
:)
# @param global_constraints [Vec<String>]
protected
def
initialize
(
inputs
:,
outputs
:,
constraints
:,
global_constraints
:)
inputs
.
each
do
|
e
|
raise
"CryptoOperator: inputs should be of type <= Variable (current class:
#{
e
.
class
}
)"
unless
e
.
class
<=
Variable
end
...
...
@@ -53,16 +42,39 @@ class CryptoOperator
constraints
.
each
do
|
e
|
raise
"CryptoOperator: constraint should be of type Constraint"
unless
e
.
class
<
Constraint
end
global_constraints
.
each
do
|
e
|
raise
"CryptoOperator: global_constraints should be of type String"
unless
e
.
class
==
String
end
@inputs
=
inputs
@outputs
=
outputs
@constraints
=
constraints
@global_constraints
=
global_constraints
end
def
register_to_model
(
model
)
raise
"CryptoOperator: model should be of class Model"
unless
model
.
kind_of?
(
Model
)
model
.
add_constraints
(
*
@constraints
)
end
def
check_inputs
(
values
)
raise
"CryptoOperator.check_inputs: values do not match (
#{
@values
.
length
}
should be
#{
@inputs
.
length
}
)"
unless
values
.
length
==
@inputs
.
length
# TODO(all) check domains
end
def
check_outputs
(
values
)
raise
"CryptoOperator.check_outputs: values do not match (
#{
@values
.
length
}
should be
#{
@outputs
.
length
}
)"
unless
values
.
length
==
@outputs
.
length
# TODO(all) check domains
end
##
# @param values that should be the same size of the inputs (and same domains)
# @return output values
#
def
compute
(
values
)
raise
"CryptoOperator: compute not implemented in child class"
end
end
## represents a DAG
...
...
nodes/constant.rb
deleted
100644 → 0
View file @
0cd65368
require_relative
'../cryptodag.rb'
## defines an constant node (it differs from the InputNode because the attacker cannot use it as an input)
# simply returns the value it inputs
class
ConstantNode
<
CryptoDagNode
def
initialize
(
x
,
y
,
name
)
super
(
x
:x
,
y
:y
,
inputs
:[]
,
name
:name
)
end
end
\ No newline at end of file
nodes/mixcolumn.rb
View file @
ea126c55
# MixColumn operator.
require_relative
'
../cryptodag.rb
'
require_relative
"
../cryptodag.rb
"
require_relative
"../operators/elementary.rb"
class
MixColumnNode
<
CryptoDagNode
def
initialize
(
input
,
matrix
,
name
)
super
(
x
:input
.
x
,
y
:input
.
y
,
inputs
:[
input
],
name
:name
)
@matrix
=
matrix
@is_computed
=
false
end
def
compute_call
()
input
=
@inputs
[
0
].
compute
()
res
=
Array
.
new
(
input
.
length
())
{
|
i
|
Array
.
new
(
input
[
0
].
length
())
{
|
j
|
0
}
}
@x
.
times
do
|
i
|
@y
.
times
do
|
j
|
m0
=
@matrix
[
i
][
0
]
m1
=
@matrix
[
i
][
1
]
m2
=
@matrix
[
i
][
2
]
m3
=
@matrix
[
i
][
3
]
s0
=
input
[
0
][
j
]
s1
=
input
[
1
][
j
]
s2
=
input
[
2
][
j
]
s3
=
input
[
3
][
j
]
res
[
i
][
j
]
=
(
m0
*
s0
)
^
(
m1
*
s1
)
^
(
m2
*
s2
)
^
(
m3
*
s3
)
end
end
return
res
end
def
initialize
(
name
:,
input
:,
m
:)
output
=
DTable
.
new
(
"
#{
name
}
"
,
input
.
type
,
input
.
dimensions
)
@m
=
m
operators
=
[
MixColumnsOperator
.
new
(
input
,
output
,
m
),
]
super
(
inputs:
[
input
],
outputs:
[
output
],
operators:
operators
,
name:
name
)
end
end
nodes/shiftrows.rb
View file @
ea126c55
...
...
@@ -17,15 +17,4 @@ class ShiftRowsNode < CryptoDagNode
end
super
(
inputs:
[
input
],
outputs:
[
output
],
operators:
operators
,
name:
name
)
end
# def compute_call()
# input = @inputs[0].compute()
# res = Array.new(input.length()) { |i| Array.new(input[0].length()) { |j| 0 } }
# @x.times() do |i| # shift row i by i positions
# @y.times() do |j|
# res[i][j] = input[i][(i + j) % 4]
# end
# end
# return res
# end
end
operators/elementary.rb
View file @
ea126c55
...
...
@@ -6,7 +6,7 @@ require_relative "../constraints/expression"
## equality operator
class
EqualityOperator
<
CryptoOperator
## Build an Equality ( "a
+ b
= b" )
## Build an Equality ( "a = b" )
# @param input [ Expression ]
# @param output [ Variable ]
def
initialize
(
input
,
output
)
...
...
@@ -14,8 +14,16 @@ class EqualityOperator < CryptoOperator
inputs:
[
input
],
outputs:
[
output
],
constraints:
[
Equality
.
new
(
input
,
output
)],
global_constraints:
[],
)
end
def
compute
(
values
)
check_inputs
(
values
)
outputs
=
[
values
[
0
]]
check_outputs
(
values
)
return
outputs
end
end
## xor operator
...
...
@@ -31,8 +39,16 @@ class XorOperator < CryptoOperator
Xor
.
new
(
*
inputs
),
output
)],
global_constraints:
[],
)
end
def
compute
(
values
)
check_inputs
(
values
)
outputs
=
[
values
.
reduce
(
0
,
:^
)]
check_outputs
(
outputs
)
return
outputs
end
end
## S operator
...
...
@@ -49,8 +65,16 @@ class SOperator < CryptoOperator
[
input
,
output
],
s_array
.
length
.
times
.
map
{
|
i
|
[
i
,
s_array
[
i
]]
}
)],
global_constraints:
[
"table"
],
)
end
def
compute
(
values
)
check_inputs
(
values
)
outputs
=
[
@s_array
[
values
[
0
]]]
check_outputs
(
outputs
)
return
outputs
end
end
## MixColumns operator
...
...
@@ -77,6 +101,7 @@ class MixColumnsOperator < CryptoOperator
inputs:
inputs
,
outputs:
outputs
,
constraints:
constraints
,
global_constraints:
[],
)
end
...
...
@@ -100,4 +125,49 @@ class MixColumnsOperator < CryptoOperator
raise
"galois_field_multiply: m=
#{
m
}
not supported yet (for now, it should be <= 3)"
end
end
def
compute
(
values
)
check_inputs
(
values
)
outputs
=
[]
@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
)
end
check_outputs
(
outputs
)
return
outputs
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
end
return
p
%
256
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
tests/operators/exec_op_eq.rb
0 → 100755
View file @
ea126c55
#!/usr/bin/ruby
## test equality operator
require_relative
"../../operators/elementary.rb"
require
"minitest/autorun"
require
"pry"
class
TestExecEq
<
Minitest
::
Unit
::
TestCase
def
test_a
()
a
=
Variable
.
new
(
"a"
,
0
..
255
)
b
=
Variable
.
new
(
"b"
,
0
..
255
)
op
=
EqualityOperator
.
new
(
a
,
b
)
assert_equal
(
op
.
compute
([
0
]),
[
0
])
assert_equal
(
op
.
compute
([
1
]),
[
1
])
assert_equal
(
op
.
compute
([
2
]),
[
2
])
end
end
\ No newline at end of file
tests/operators/exec_op_mc.rb
0 → 100755
View file @
ea126c55
#!/usr/bin/ruby
## test MixColumns operator
require_relative
"../../operators/elementary.rb"
require
"minitest/autorun"
require
"pry"
class
TestExecS
<
Minitest
::
Unit
::
TestCase
def
test_aes
()
inputs
=
[
Variable
.
new
(
"a"
,
0.255
),
Variable
.
new
(
"b"
,
0.255
),
Variable
.
new
(
"c"
,
0.255
),
Variable
.
new
(
"d"
,
0.255
),
]
outputs
=
[
Variable
.
new
(
"e"
,
0.255
),
Variable
.
new
(
"f"
,
0.255
),
Variable
.
new
(
"g"
,
0.255
),
Variable
.
new
(
"h"
,
0.255
),
]
m
=
[
[
2
,
3
,
1
,
1
],
[
1
,
2
,
3
,
1
],
[
1
,
1
,
2
,
3
],
[
3
,
1
,
1
,
2
],
]
op
=
MixColumnsOperator
.
new
(
inputs
,
outputs
,
m
)
assert_equal
(
op
.
compute
([
0
,
0
,
0
,
0
]),
[
0
,
0
,
0
,
0
])
assert_equal
(
op
.
compute
([
1
,
1
,
1
,
1
]),
[
1
,
1
,
1
,
1
])
assert_equal
(
op
.
compute
([
219
,
19
,
83
,
69
]),
[
142
,
77
,
161
,
188
])
assert_equal
(
op
.
compute
([
242
,
10
,
34
,
92
]),
[
159
,
220
,
88
,
157
])
assert_equal
(
op
.
compute
([
198
,
198
,
198
,
198
]),
[
198
,
198
,
198
,
198
])
assert_equal
(
op
.
compute
([
212
,
212
,
212
,
213
]),
[
213
,
213
,
215
,
214
])
assert_equal
(
op
.
compute
([
45
,
38
,
49
,
76
]),
[
77
,
126
,
189
,
248
])
end
def
test_midori
()
inputs
=
[
Variable
.
new
(
"a"
,
0.255
),
Variable
.
new
(
"b"
,
0.255
),
Variable
.
new
(
"c"
,
0.255
),
Variable
.
new
(
"d"
,
0.255
),
]
outputs
=
[
Variable
.
new
(
"e"
,
0.255
),
Variable
.
new
(
"f"
,
0.255
),
Variable
.
new
(
"g"
,
0.255
),
Variable
.
new
(
"h"
,
0.255
),
]
m
=
[
[
0
,
1
,
1
,
1
],
[
1
,
0
,
1
,
1
],
[
1
,
1
,
0
,
1
],
[
1
,
1
,
1
,
0
],
]
op
=
MixColumnsOperator
.
new
(
inputs
,
outputs
,
m
)
assert_equal
(
op
.
compute
([
0
,
0
,
0
,
0
]),
[
0
,
0
,
0
,
0
])
assert_equal
(
op
.
compute
([
1
,
1
,
1
,
1
]),
[
1
,
1
,
1
,
1
])
assert_equal
(
op
.
compute
([
0xa5
,
0x08
,
0x10
,
0x88
,
]),[
0x90
,
0x3d
,
0x25
,
0xbd
,
])
assert_equal
(
op
.
compute
([
0x56
,
0x2c
,
0x77
,
0xa3
,
]),[
0xf8
,
0x82
,
0xd9
,
0x0d
,
])
assert_equal
(
op
.
compute
([
0xb8
,
0xb7
,
0xac
,
0x84
,
]),[
0x9f
,
0x90
,
0x8b
,
0xa3
,
])
assert_equal
(
op
.
compute
([
0x3f
,
0x9f
,
0xc2
,
0x2b
,
]),[
0x76
,
0xd6
,
0x8b
,
0x62
,
])
end
end
\ No newline at end of file
tests/operators/exec_op_s.rb
0 → 100755
View file @
ea126c55
#!/usr/bin/ruby
## test S operator
require_relative
"../../operators/elementary.rb"
require
"minitest/autorun"
require
"pry"
class
TestExecS
<
Minitest
::
Unit
::
TestCase
def
test_a
()
a
=
Variable
.
new
(
"a"
,
0
..
255
)
b
=
Variable
.
new
(
"b"
,
0
..
255
)
op
=
SOperator
.
new
(
a
,
b
,
(
0
..
255
).
map
{
|
i
|
i
*
2
%
256
}.
to_a
)
assert_equal
(
op
.
compute
([
0
]),
[
0
])
assert_equal
(
op
.
compute
([
1
]),
[
2
])
assert_equal
(
op
.
compute
([
2
]),
[
4
])
assert_equal
(
op
.
compute
([
128
]),
[
0
])
end
end
\ No newline at end of file
tests/operators/exec_op_xor.rb
0 → 100755
View file @
ea126c55
#!/usr/bin/ruby
## test Xor operator
require_relative
"../../operators/elementary.rb"
require
"minitest/autorun"
require
"pry"
class
TestExecXor
<
Minitest
::
Unit
::
TestCase
def
test_2input
()
a
=
Variable
.
new
(
"a"
,
0
..
255
)
b
=
Variable
.
new
(
"b"
,
0
..
255
)
c
=
Variable
.
new
(
"c"
,
0
..
255
)
op
=
XorOperator
.
new
(
a
,
b
,
c
)
assert_equal
(
op
.
compute
([
0
,
0
]),
[
0
])
assert_equal
(
op
.
compute
([
0
,
1
]),
[
1
])
assert_equal
(
op
.
compute
([
1
,
1
]),
[
0
])
assert_equal
(
op
.
compute
([
3
,
2
]),
[
1
])
end
def
test_3input
()
a
=
Variable
.
new
(
"a"
,
0
..
255
)
b
=
Variable
.
new
(
"b"
,
0
..
255
)
c
=
Variable
.
new
(
"c"
,
0
..
255
)
d
=
Variable
.
new
(
"d"
,
0
..
255
)
op
=
XorOperator
.
new
(
a
,
b
,
c
,
d
)
assert_equal
(
op
.
compute
([
0
,
0
,
0
]),
[
0
])
assert_equal
(
op
.
compute
([
0
,
0
,
1
]),
[
1
])
assert_equal
(
op
.
compute
([
0
,
1
,
1
]),
[
0
])
assert_equal
(
op
.
compute
([
1
,
1
,
1
]),
[
1
])
assert_equal
(
op
.
compute
([
1
,
2
,
3
]),
[
0
])
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