Algebraic Cryptanalysis of Round Reduced Versions of CSA

Algebraic Cryptanalysis of Round
Reduced Versions of CSA and
the LED Family of Block Ciphers
Bachelor-Thesis von Julian Wälde
Januar 2013
Computer Science
CDC
Algebraic Cryptanalysis of Round Reduced Versions of CSA and
the LED Family of Block Ciphers
Vorgelegte Bachelor-Thesis von Julian Wälde
1. Gutachten: Prof. Dr. Johannes Buchmann
2. Gutachten: Dr. Stanislav Bulygin
3. Gutachten:
Tag der Einreichung:
Bitte zitieren Sie dieses Dokument als:
URN: urn:nbn:de:tuda-tuprintsURL: http://tuprints.ulb.tu-darmstadt.de/
Dieses Dokument wird bereitgestellt von tuprints,
E-Publishing-Service der TU Darmstadt
http://tuprints.ulb.tu-darmstadt.de
[email protected]
Die Veröffentlichung steht unter folgender Creative Commons Lizenz:
Namensnennung – Keine kommerzielle Nutzung – Keine Bearbeitung 2.0 Deutschland
http://creativecommons.org/licenses/by-nc-nd/2.0/de/
Erklärung zur Bachelor-Thesis
Hiermit versichere ich, die vorliegende Bachelor-Thesis ohne Hilfe Dritter nur mit den angegebenen Quellen und Hilfsmitteln angefertigt zu haben. Alle Stellen, die aus Quellen
entnommen wurden, sind als solche kenntlich gemacht. Diese Arbeit hat in gleicher oder
ähnlicher Form noch keiner Prüfungsbehörde vorgelegen.
Darmstadt, den January 28, 2013
(Julian Wälde)
1
Abstract
Lightweigt cryptograhy aims to achieve high security while at the same time reducing complexity of
computation by relying on simpler building blocks. This work analyses the security of two lightweight
block ciphers (LED and CSA) against algebraic cryptanalysis. We describe an algebraic attack on 3 round
LED64 and a simple generic attack on 8 round LED80/LED128. Using side channel information we were
able to break full round LED. In regards to CSA we found an attack on up to 15 rounds that is faster than
a corresponding generic attack as well as algebraic side channel attacks on the full round CSA.
2
Contents
1. Introduction
1.1. Definitions . . . . . . . . . . . . . . . . . . . .
1.2. Symmetric encryption . . . . . . . . . . . . .
1.2.1. Block cipher . . . . . . . . . . . . . . .
1.2.2. Iterated block ciphers . . . . . . . . .
1.2.3. Modes of operation . . . . . . . . . .
1.2.4. Cryptanalysis . . . . . . . . . . . . . .
1.2.5. The Satisfiability problem . . . . . .
1.2.6. Algebra . . . . . . . . . . . . . . . . . .
1.3. Side channel cryptanalysis . . . . . . . . . . .
1.4. Algebraic cryptanalysis . . . . . . . . . . . . .
1.4.1. Algebraic representation of a cipher
1.4.2. Solving methods . . . . . . . . . . . .
1.4.3. SAT solvers . . . . . . . . . . . . . . .
1.4.4. Measuring attack costs . . . . . . . .
1.4.5. Algebraic side channel cryptanalysis
4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2.0.6. Key schedule . . . . . . . . . . . . . . . . . . . . .
2.0.7. Round function . . . . . . . . . . . . . . . . . . . .
Previous cryptanalysis of LED . . . . . . . . . . . . . . . .
Generic attack on 8 rounds of LED80 and LED128 . . .
An algebraic attack on 3 rounds of LED64 . . . . . . . .
2.3.1. A note on reduced variants of LED . . . . . . . .
2.3.2. An algebraic model for the LED round function
2.3.3. Performance of the attack . . . . . . . . . . . . .
A side channel attack on the full round LED cipher . . .
2.4.1. Modeling side channel information . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2. The LED Family of Block Ciphers
2.1.
2.2.
2.3.
2.4.
4
4
4
4
5
5
5
6
7
7
7
7
7
8
8
9
3. The CSA block cipher
3.1. DVBCSA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2. The design of the CSA block cipher . . . . . . . . . . . . . . .
3.2.1. Key schedule . . . . . . . . . . . . . . . . . . . . . . . .
3.2.2. The round function . . . . . . . . . . . . . . . . . . . .
3.3. Previous cryptanalysis of CSA . . . . . . . . . . . . . . . . . . .
3.4. A Meet in the Middle Attack on up to 15 rounds of CSA . .
3.5. An algebraic cryptanalysis of the CSA block cipher . . . . . .
3.5.1. An algebraic description of the CSA round function .
3.6. Key bit guessing strategy . . . . . . . . . . . . . . . . . . . . . .
3.6.1. Experimental data on the speed of the attack . . . .
3.7. A algebraic side channel analysis of the CSA block cipher .
9
9
11
11
12
12
12
13
14
14
16
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
16
16
16
17
18
19
19
19
19
20
20
4. Conclusion
21
A. Appendix
24
3
1 Introduction
In many communication applications cryptography is the most resource demanding part of the communication. The up-coming of RFID and wireless sensor networks and chip cards resulted in the need for
lightweight cryptography to make secure communication in restricted environments possible. In this
work we will analyse the LED and CSA block cipher regarding their security against algebraic cryptanalysis.
1.1 Definitions
In this section we will establish various concepts that we will later call upon to explain what we’ve been
working on.
1.2 Symmetric encryption
Symmetric encryption deals with the problem of securing the confidentiality of communication. The
usual approach to this is to create an algorithm that given an arbitrary message and a secret key scrambles a message in a manner that makes knowledge of the secret key mandatory for anyone seeking
knowledge of the messages content.
1.2.1 Block cipher
A block cipher is a cipher that operates on blocks of fixed size. Formally it can be viewed as a tuple
(P, C, K, E, D). P being the set of plain texts and C being the set of cipher-texts. K is the set of keys and
E and D are functions for encryption and decryption with
Ek : P → C
Dk : C → P
Ek ◦ Dk = id for any k ∈ K . E x is supposed to be indistinguishable from a bijective random function
f r and om : P → C if x is selected at random. Usually P = C can be assumed, making E a family of so called
pseudo random permutations (PRP).
1.2.2 Iterated block ciphers
Iterated block ciphers are a concept for the construction of secure block ciphers; it follows the idea that
a simple transformation is applied to the plain-text in an iterated fashion to create a complex relation
between plain- and cipher-text and a key. This simple transformation is often referred to as a round
function; and its iterations are referred to as round. The keys that are used to obscure the intermediate
cipher-text are called round keys. The round keys are created by expanding the actual secret key using
another function referred to as the key schedule.
Confusion
Confusion is the concept of creating a very complex relationship between plain- and cipher-text. To
create a compact function for a large domain and range often a complex function is applied locally.
Often this is implemented by using a lookup table that is referred to as an S-Box; the S-Box implements a
4
very non-linear function but its lookup table requires memory that is exponential in the size of its input
domain. Due to this the S-Box usually operates on small parts of the intermediate cipher-text. Most
popular choices for the size of the S-Box are 4 and 8 bit.
Diffusion
Diffusion is the property of the cipher that every bit of its output depends on any bit of the input in a
complex way. Such that even a small change on the input results in a change in the output that appears
completely random.
1.2.3 Modes of operation
Since a block cipher encrypts “blocks” of fixed size (in many cases shorter than the message that needs
encryption) one needs to find a way to encrypt a large message using block ciphers.
CBC
CBC (Cipher Block Chaining) operates by xoring any plain-text block with the previous cipher-text block
(i.e. repeating plain-text blocks do not result in repeating cipher-text blocks). An initialization vector IV
is used to randomize the encryption of the first block; such that repeating messages result in apparent
random cipher-texts. A message m := p0 ||p1 || . . . ||pn is encrypted as E(m) := c0 ||c1 || . . . ||cn :
c0 = Ek (p0 ⊕ I V ) and 0 ≤ I V ≤ 2n
ci = Ek (pi ⊕ ci−1 )
with n being the block size in bits.
1.2.4 Cryptanalysis
In general cryptanalysis is the effort to break a crypto-system under certain assumptions faster then brute
force. There are only a few crypto-systems that are provably secure against this effort.
Exhaustive search
The most generic attack thinkable on any cipher that is not information theoretically secure would be to
try out every k ∈ K until the right key is found. This technique is known as “brute force” or “exhaustive
search”. In order for the attack to work an attack requires some way to recognize the “right” key or
likewise discard “wrong” keys. E.g. in case of a block cipher a couple of plain-text cipher-text pairs
(pi , ci ) with Ek (pi ) = ci would suffice to test any given k for being the key actually used.
1.2.5 The Satisfiability problem
The satisfiability problem (SAT) is the problem of determining whether there exists a setting for logical
variables that satisfies a given logical formula or whether there exists no such setting. We will refer to
these as SAT and UNSAT respectively. SAT is a NP-complete problem. SAT solvers are programs that are
used to solve instances of the SAT problem.
Example:
(v 1 ∨ ¬v 2 ) ∧ (v 2 ∨ v 3 ) ∧ (v 1 ∨ v 3 ∨ v 4 )
is satisfied if v 1 and v 3 are set to true. While there exists no satisfying setting for this formula:
v 1 ∧ (v 2 ∨ ¬v 1 ) ∧ ¬v 2
5
1.2.6 Algebra
In this part we will recall a few basic facts about algebra that are required to understand the rest of this
work.
Polynomial
In algebra a polynomial p in the variable X over a field F is the sum of products of coefficients ai ∈ F
and powers of X . These summands are referred to monomials. Polynomials in more than one variable
are referred to as multivariate polynomials. The degree of a monomial is the sum of exponents of the
variables that appear in it; the degree of a polynomial is the maximum degree of its monomials. The
polynomials in a given field F and n variables form the ring of polynomials (F[X 0 , . . . , X n ]).
Pn
p := i=0 ai X i .
A multivariate Polynomial with variables in X := {x 1 , x 2 , . . . , x n } has the form:
Pn
p(x 1 , x 2 , . . . , x n ) := i=0 mi
With monomials mi of degree d e g(mi ) = d being products of the form mi = ai ·
Qd
j=1
x j and x j ∈ X.
ANF
The Algebraic Normal Form of a polynomial is the sum of its monomials (that can be any product of
available variables) e.g.:
[[p(x,y,z) = xyz+xy+z ]]
CNF
In order to run a system of equations through a SAT solver one needs a description of the system that
sat solvers can work with. The Conjunctive Normal Form (CNF) is a format to write down equations in
boolean logic using only a conjunction of disjunctions (or clauses). The format is relatively simple. The
formula
(v 1 ∨ ¬v 2 ) ∧ (v 2 ∨ v 3 ) ∧ (v 1 ∨ v 3 ∨ v 4 )
would be encoded as:
c
p
1
2
1
t h i s i s a comment
cnf 4 3
−2 0
3 0
3 4 0
ANF to CNF conversion
Another problem concerning the modeling of a cipher for the purpose of applying algebraic cryptanalysis
is, that given a system of polynomials over GF(2) one must convert them into a CNF to be able to apply
a sat solvers to it. There are many different CNF that satisfy a given polynomial system; among which a
system that only consists of one clause per variable.
6
1.3 Side channel cryptanalysis
Modern ciphers are especially hardened against conventional cryptanalysis e.g. linear [17] and differential cryptanalysis [5]. While conventional cryptanalysis aims at identifying weaknesses in algorithms
side channel analysis relies on information leakage in implementations of cryptographic algorithms; i.e.
the implementation of an otherwise secure algorithm might still leak enough information to recover the
key used. This leaked information is considered to be side channel information. A variety of things like
timing behaviour [4], power consumption [6], electro magnetic radiation, and sound [2] can be used as
side channel information. Using this information alone the key in many cases can be recovered within
neglectable time. However this method imposes additional assumptions on the attacker.
1.4 Algebraic cryptanalysis
Algebraic cryptanalysis [3] aims at breaking a primitive by finding and solving a suitable algebraic description of the primitive. An algebraic description is a system of equations that models the cipher such
that the equation system describes the encryption function algebraically. Solving this system with known
variables set is now equivalent to learning the unknown variables (e.g. the key of a cipher). If solving the
system right ahead is infeasible one can guess the value of some of the variables to further simplify the
problem. Any symmetric cipher has (at least) two inputs: the key and the plain-text; and the cipher-text
output. If and attacker has a suitable algebraic description (i.e. one which allows fast determination of
its satisfiability) of the primitive of interest and enough plain-/cipher-text pairs to limit the number of
satisfying keys to a single key, that key can be recovered.
1.4.1 Algebraic representation of a cipher
When applying algebraic cryptanalysis to a cipher it is important to find a “good” algebraic description of
the cipher. Since it is hard to model the cipher directly one has to model the structure of the cipher and
create equation systems for every part of the cipher. These partial systems are chained using intermediate
variables to create a single bigger system that fully describes the cipher. The intermediate variables are
also useful when it comes to keeping the size of the actual equations small. It is very important, that the
system specifies the cipher (meaning that every solving constellation of variables would also work with
the cipher). In this work all modeling is done using polynomials in GF (2)[x 0 , x 1 , . . .] or logical equations
in CNF(Conjunktive Normal Form) created from the truth table that models the function of interest.
1.4.2 Solving methods
Given an algebraic representation (ANF or CNF) of a cipher and a sufficient number of known plain/cipher-text pairs in order to recover the secret key the known information is added to the system. Now
the secret key can be found by finding a solution to the system. If it is not possible to solve the system
right away one can guess a number of key bits to help the solving algorithms by reducing the number of
unknowns. Guessing key bits requires exponentially (in the number of guessed key bits) many runs of
the solving algorithm.
1.4.3 SAT solvers
A SAT solver is a program that gets a logical formula written as CNF as input and determines whether
the formula is satisfiable; the sat solver proves this by producing a satisfying setting for all variables in
the formula. Most SAT solvers today work with variants of the DPLL algorithm originally introduced by
7
[10]. In our experiments we used Cryptominisat[16], a sat solver that extends the DPLL algorithm to
make use of linear equations (XOR clauses) in the system.
Cryptominisat
Cryptominisat [16] is a SAT solver that uses a variant of DPLL. It extracts linear equations from the CNF
and uses Gaussian Elimination to solve them; these solutions are then used to aid the DPLL algorithm.
Also cryptominisat allows to directly write down XOR clauses (that define the xor of all their variables)
in CNF. Such XOR clauses look like this:
x 2340
is equivalent to the linear equation
x2 + x3 + x4 = 0
1.4.4 Measuring attack costs
Since in algebraic cryptanalysis there is no notion of an access to an encryption or decryption oracle,
it’s not possible to directly compare an algebraic attack to brute force. We are going to compare the
estimated run time of our attacks with the estimated time for an brute force.
If no key bits are guessed this time T is simply the average time to determine satisfiability TSAT for
the given system. If n key bits are guessed there are 2n different settings of which only one is correct;
now the average time to recover the key is Tav g = 2n−1 ∗ TU N SAT . In worst case all 2n settings have to be
processed puting the worst case time for key recovery Tworst = 2n ∗ TU N SAT . The time required to brute
force the key is estimated using the average time required to do one encryption on the same hardware
as the SAT solver is running. This time is Tbrut e f or ce = Tenc ∗ 2l−1 on average; l is the key size in bits and
Tenc is the time required to test a single key.
1.4.5 Algebraic side channel cryptanalysis
The concepts of algebraic and side channel cryptanalysis can be combined by adding side channel information to the equation system or CNF. Adding side channel information can have interesting effects on
SAT solving (e.g. UNSAT might be easier to determine than SAT due to conflicts between guessed key
bits and known Hamming weights). In this work we present an algebraic attack on a full round version
of the CSA block cipher that is using side channel information.
8
2 The LED Family of Block Ciphers
The LED family of block ciphers introduced in [13] has a design very similar to that of the Rijndael
[18] Algorithm that was choosen as the Advanced Encryption Standard (AES) in 2010. The major
differences are a smaller 4-bit S-Box (that originates from the PRESENT [8] cipher) and a very simplistic
key schedule. Every four rounds a roundkey is XORed into the state then the state is transformed using
the not keyed round function for another four rounds. After the final transformation the last roundkey
is XORed into the state.
2.0.6 Key schedule
LED [13] employs a very minimalistic key schedule. While LED64 uses the same key for every step the
other variants split a bigger key into two pieces and (if necessary) pad the smaller piece to 64 bit length
these two 64bit round keys are then being used in an alternating fashion; padding is done by appending
a prefix of the first key with suitable length. LED80 uses the first 64 bits for the first key and last 16 bits
padded with the first 48 bits for the second key. LED128 just splits the 128 bit long key into two 64 bit
keys.
Figure 2.1.: LED encryption function [13]
LED64:
LED80/96/128:
A key schedule that is this simple would directly lead to instances of slide attacks [7].However, the design of the round function (mainly the AddConstants part) turns every round into a different permutation
and thus prevents such attacks from working on LED.
2.0.7 Round function
LED operates on a state that consists of 16 4-bit cells. The 16 4-bit cells are arranged in 4 columns and 4
rows. This only matters for the description of the round function since parts of it operate on single cells,
rows, and columns of the state. A one dimensional array s would be arranged like this:
s0 s1 s2 s3
s4 s5 s6 s7
s8 s9 s10 s11
s12 s13 s14 s15
The LED round function has many similarities to that of the AES block cipher. It consists of four parts
AddConstants, SubCells, ShiftRows, and MixColumns.
9
Figure 2.2.: LED round function [13]
AddConstants
The AddConstants part of the round function serves to prevent slide attacks [7] that would threaten the
cipher due to its very simple key schedule. At the begin of every round different constants are being
XORed into the state. The constants follow this scheme:
0
1
2
3
(r c5 ||r c4 ||r c3 )
(r c2 ||r c1 ||r c0 )
(r c5 ||r c4 ||r c3 )
(r c2 ||r c1 ||r c0 )
0
0
0
0
0
0
0
0
with r c being a six bit wide linear feedback shift register with r c5 ⊕ r c4 ⊕ 1 as its feedback function.
The initial value of the r c is all six bits zero. The values of r c are:
round
rc
0
01
1
03
2
07
3
0f
4
1f
5
3e
6
3d
7
3b
8
37
9
2f
10
1e
11
3c
round
rc
12
39
13
33
14
27
15
0e
16
1d
17
3a
18
35
19
2b
20
16
21
2c
22
18
23
30
round
rc
24
21
25
02
26
05
27
0b
28
17
29
2e
30
1c
31
38
32
31
33
23
34
06
35
0d
round
rc
36
1b
37
36
38
2d
39
1a
40
34
41
29
42
12
43
24
44
08
45
11
46
22
47
04
SubCells
The SubCells step of the LED round function substitutes every nibble according to this Sbox:
0
12
1
5
2
6
3
11
4
9
5
0
6
10
7
13
8
3
9
14
10
15
11
8
12
4
13
7
14
1
15
2
The S-Box is identical to the one being used in PRESENT [8]. It also is the only source of non-linearity
in the cipher so that without it one could easily break LED using Gaussian elimination.
ShiftRows
Shift Rows operates on the rows of the state and works exactly like its counterpart in AES [18]. Every
row is rotated left by its index minus one.
s1 s2 s3 s4
s1 s2 s3 s4
s5 s6 s7 s8
s
s7 s8 s5
→ 6
s9 s10 s11 s12
s11 s12 s9 s10
s13 s14 s15 s16
s16 s13 s14 s15
10
Even though this part of the round function is very simple, it becomes a powerful diffusion layer for
the cipher in combination with MixColumns.
MixColoumns
Just like AES [18] LED uses a maximum distance separable code to transform the columns of its state.
And just as in AES [18] this step is called “MixColumns”. This step consists of multiplying every column
of the state with a fixed matrix that has the maximum distance sparse property. LED uses a matrix A over
the extension field (G F )(2)[X ]/(X 4 + X + 1):
 
4

4 1 2 2
0 1 0 0
 


 8 6 5 6   0 0 1 0 
A=
=
 
 .
 11 14 10 9   0 0 0 1 
2 2 15 11
4 1 2 2
While the SubCells part of the round function delivers all the non-linearity (confusion) for the cipher,
diffusion is achieved by MixColumns and ShiftRows; every cell in the output column depends on every
cell in the input column.
2.1 Previous cryptanalysis of LED
In 2012 Abed, Forler, List, Lucks, and Wenzel published the first attack on full round LED64 and LED128
[1] using independent bitcliques and requiring 263.34 and 2127.23 encryptions respectively. A similar attack
[14] was proposed by Jeong, Kang, Lee, Sung, and Hong int the same year.
Also in 2012 Jovanovic, Kreuzer, and Polian published a fault attack on LED64 [15] requiring only a
single fault injection.
In his Bachelor Thesis [12] Michael Dollichon attempted to break LED using Gröbner bases.
2.2 Generic attack on 8 rounds of LED80 and LED128
All variants of the LED block cipher that use more then 64 bits of key are susceptible to an generic attack
on up to 8 rounds. These reduced variants can be written as:
LE Dk1 ,k2 (x) := g( f (x ⊕ k1 ) ⊕ k2 ) ⊕ k1
where f and g are four rounds of the cipher that are not keyed. And k1 and k2 are the corresponding
64bit keys. The key recovery attack on these reduced versions of LED need 2 pairs of known plain/cipher-text namely (p0 , c0 ) and (p1 , c1 ). Given the knowledge of k1 one can easily compute k2 as follows:
k2 = g −1 (c0 ⊕ k1 ) ⊕ f (p0 ⊕ k1 )
An attacker now simply searches for the correct value of k1 , computes a candidate for k2 , and tests this
candidate against the second plain-/cipher-text pair.
Attacks as suggested above are commonly known as “Meet in the Middle Attack” originally introduced
by [11]. The complexity for this attack is in average equivalent 264 8 round LED encryptions and needs
a neglectable amount of memory. As for comparison a brute force attack needs in average 2127 and 279
trial decryptions respectively; and 2 pairs of plain-/cipher-text as well.
11
2.3 An algebraic attack on 3 rounds of LED64
2.3.1 A note on reduced variants of LED
The 3 round variant of LED we are looking at is one key injection followed by three unkeyed transformations of the state and one more key injection. Seeing that LED has 32 or 48 rounds; breaking only 3
rounds suggests that LED is rather resistant against this type of attack.
2.3.2 An algebraic model for the LED round function
AddConstants
AddConstants only inverts certain bits in the state. That is modeled by inverting the variables that
correspond to these bits of the state.
SubCells
For the PRESENT [8] Sbox there exists a quadratic system of 4 equations describing the SBox:
x 1 · x 2 + x 0 + x 1 + x 3 + y3 = 0
x 0 · x 2 + x 3 · y0 + x 0 + x 1 + y1 + 1 = 0
x 0 · x 1 + x 3 · y2 + x 1 + x 2 + y1 + y2 + 1 = 0
x 0 · x 1 + x 0 · x 2 + x 0 + x 1 + y0 + y2 + y3 + 1 = 0
It turned out however, that the interpolation polynomials yield a CNF more suited for cryptominisat
[16] to solve:
y3 = x 1 · x 2 + x 0 + x 1 + x 3
y2 = x 0 · x 1 · x 3 + x 0 · x 2 · x 3 + x 1 · x 2 · x 3 + x 0 · x 1 + x 0 · x 2 + x 0 + x 2
y1 = x 0 · x 1 · x 3 + x 0 · x 2 · x 3 + x 0 · x 2 + x 0 · x 3 + x 2 · x 3 + x 0 + x 1 + 1
y0 = x 0 · x 1 · x 3 + x 0 · x 2 · x 3 + x 1 · x 2 · x 3 + x 1 · x 2 + x 0 + x 2 + x 3 + 1
ShiftRows
Shift Rows can be viewed as an operation that only swaps cells in the state. One can simply apply
ShiftRows to an array of variables prior to the MixColumns step to achieve the desired permutation of
the inputs for the MixColumns part.
MixColumns
Since we are trying to construct a system of polynomials in GF (2)[X 1 , X 2 , . . . , X n ] that specifies LED one
has to model multiplication in the extension field that is used by LED for GF (2)[X ]. That can easily be
done by modeling a multiplication with X as a matrix-vector multiplication with:


0 0 1 1


 1 0 0 0 


 0 1 0 0 
0 0 1 0
With this technique and ⊕ as addition one can adapt a “square and multiply” alike algorithm for
arbitary multiplications in LEDs extension field. The simplest way to model the complete MixColumns
12
step now would be to simply use the linear polynomials that will be created by multiplying A with a
vector of state variables resulting in these polynomials for every column:
y0 = x 2 + x 4 + x 9 + x 13
y1 = x 0 + x 3 + x 5 + x 10 + x 14
y2 = x 0 + x 1 + x 6 + x 8 + x 11 + x 12 + x 15
y3 = x 1 + x 7 + x 8 + x 12
y4 = x 0 + x 3 + x 5 + x 6 + x 8 + x 10 + x 13 + x 14
y5 = x 0 + x 1 + x 4 + x 6 + x 7 + x 8 + x 9 + x 11 + x 12 + x 14 + x 15
y6 = x 1 + x 2 + x 5 + x 7 + x 8 + x 9 + x 10 + x 13 + x 15
y7 = x 2 + x 4 + x 5 + x 9 + x 11 + x 12 + x 13
y8 = x 1 + x 3 + x 4 + x 5 + x 6 + x 7 + x 8 + x 9 + x 11 + x 15
y9 = x 0 + x 2 + x 5 + x 6 + x 7 + x 8 + x 9 + x 10 + x 12
y10 = x 0 + x 1 + x 3 + x 6 + x 7 + x 8 + x 9 + x 10 + x 11 + x 13
y11 = x 0 + x 2 + x 3 + x 4 + x 5 + x 6 + x 8 + x 10 + x 14 + x 15
y12 = x 1 + x 5 + x 9 + x 10 + x 11 + x 13 + x 15
y13 = x 2 + x 6 + x 10 + x 11 + x 12 + x 14
y14 = x 0 + x 3 + x 4 + x 7 + x 11 + x 12 + x 13 + x 15
y15 = x 0 + x 4 + x 8 + x 9 + x 10 + x 11 + x 12 + x 14 + x 15
Experiments with cryptominisat [16] however, have shown on average four times shorter time to
decide the satisfiability of the system with a MixColumn layer being modeled as for four matrix multiplications with intermediate state variables giving us four times four systems every round of this form:
y0 = x 4
y1 = x 5
y2 = x 6
y3 = x 7
y4 = x 8
y5 = x 9
y6 = x 10
y7 = x 11
y8 = x 12
y9 = x 13
y10 = x 14
y11 = x 15
y12 = x 2 + x 4 + x 9 + x 13
y13 = x 0 + x 3 + x 5 + x 10 + x 14
y14 = x 0 + x 1 + x 6 + x 8 + x 11 + x 12 + x 15
y15 = x 1 + x 7 + x 8 + x 12
2.3.3 Performance of the attack
To conduct the attack one has to test 231 guesses for the key bits on average. The effort to test a
guess is the time needed to determine the satisfiability of the one CNF. In our experiments we used
cryptominisat[16]. We measured the time needed to determine unsatisfiability of 1000 systems with
random settings for plain-text/cipher-text and guessed keybits. In the following table we summerize the
results of the conducted experiments as the number of rounds, number of guessed key bits, the empirical
average of our measurements, their maximum and minimum, the empiric stdandard deviation and the
upper bound of the 99% confidence interval of the average for this unknown distribution.
13
# rounds # bits
avg.
max.
min.
std. deviation upper bound
2
16
19
37.7
13.19
4.13
21.11
3
32
20.30
35.78
10.86
3.75
22.82
4
48
20.11
85.5
11.34
4.49
23.39
32
48
445.14 604.51 289.67
34.90
944.99
Using an optimized implementation we measured the average time for 232 encryptions. Based on
these experiments we estimate the time required to conduct the attacks described above using brute
force instead of a SAT solver.
# rounds guessed key bits estimated average
2
16
2516582.40
3
32
57.79
4
32
78.52
32
48
18.98
Starting with four rounds brute force is faster then our attack.
2.4 A side channel attack on the full round LED cipher
If the Hamming weight of the state (per cell) can be accessed as side channel information, it is possible
to stage a key recovery attack against full round versions. It was possible to recover the used key
within seconds if either 2 consecutive rounds of the first/last step are available or 7 consecutive rounds
anywhere in the cipher.
The Hamming weights are extracted after the SubCells part of their round. The side channel information is then integrated into the encoder described above. In the following we describe two algorithms
that can be used to encode Hamming weights.
2.4.1 Modeling side channel information
Extracted side channel information is the Hamming weight of every single cell of the state right after a
SubCells step. Since every cell has 4-bit the Hamming weight of a cell can be any number from 0 to 4.
in ANF
For the task of encoding Hamming weights in ANF we used an algorithm that uses two simple observations. If x out of n variables are set to 1 there exists only one monomial m with deg(m) = x that
evaluates to 1 in any such setting (i.e. the sum of all monomial with degree x is 1). If less then x variables are set to 1 all these monomial evaluate to 0. Also at least one monomial m with deg(m) = x + 1
will evaluate to 1 if more then x variables are set to 1.
A Hamming weight w of the four variables x 0,1,2,3 would be encoded as:
w = 0 → x 0 = 0, x 1 = 0, x 2 = 0, x 3 = 0
w = 1 → x 0 + x 1 + x 2 + x 3 = 1, x 0 x 1 = 0, x 0 x 2 = 0, x 0 x 3 = 0x 1 x 2 = 0, x 1 x 3 = 0
w = 2 → x 0 x 1 + x 0 x 2 + x 0 x 3 + x 1 x 2 + x 1 x 3 = 1, x 0 x 1 x 2 = 0, x 1 x 2 x 3 = 0, x 0 x 2 x 3 = 0, x 0 x 1 x 3 = 0
w = 3 → x 0 x 1 x 2 + x 1 x 2 x 3 + x 0 x 2 x 3 + x 0 x 1 x 3 = 1, x 0 x 1 x 2 x 3 = 0
w = 4 → x0 x1 x2 x3 = 1
14
in CNF
Simpler (and thus easier to solve) equations can be generated by directly encoding the Hamming weight
in CNF. The idea behind this algorithm is that if out of k bits exactly n < k are zero any disjunction of
n + 1 bits will be true. Also any conjunction of ((k − n) + 1) will be zero (a fact that can be rewritten
as an disjunction of inverted bits). This concept yields a CNF without having to encode the information
as polynomials beforehand. Also the CNF produced has good properties as it yields only a few relatively
short clauses.
The Hamming weight w of (x 0 , x 1 , x 2 , x 3 ) would be encoded like this:
w = 0 → ¬x 0 ∧ ¬x 1 ∧ ¬x 2 ∧ ¬x 3
w = 1 → (¬x 0 ∨ ¬x 1 )∧ (¬x 0 ∨ ¬x 2 )∧ (¬x 0 ∨ ¬x 3 )∧
(¬x 1 ∨ ¬x 2 )∧ (¬x 1 ∨ ¬x 3 )∧ (¬x 2 ∨ ¬x 3 )∧
x0 ∨ x1 ∨ x2 ∨ x3
w = 2 → (¬x 0 ∨ ¬x 1 ∨ ¬x 2 )∧ (¬x 0 ∨ ¬x 1 ∨ ¬x 3 )∧ (¬x 0 ∨ ¬x 2 ∨ ¬x 3 )∧
(¬x 1 ∨ ¬x 2 ∨ ¬x 3 )∧ (x 0 ∨ x 1 ∨ x 2 )∧ (x 0 ∨ x 1 ∨ x 3 )∧
(x 0 ∨ x 2 ∨ x 3 )∧ (x 1 ∨ x 2 ∨ x 3 )
w = 3 → (¬x 0 ∨ ¬x 1 ∨ ¬x 2 ∨ ¬x 3 )∧ (x 0 ∨ x 1 )∧ (x 0 ∨ x 2 )∧ (x 0 ∨ x 3 )∧ (x 1 ∨ x 2 )∧ (x 1 ∨ x 3 )∧ (x 2 ∨ x 3 )
w = 4 → x0 ∧ x1 ∧ x2 ∧ x3
We conducted 1000 experiments to determine the average time to recover the key with side channel
information in form of the Hamming weights of 7 consecutive rounds. On average it took 14.68 seconds
to recover the key; with a minimum of 1.38 seconds and a maximum of 129.38 seconds.
15
3 The CSA block cipher
In this chapter we will explain our attacks on the DVBCSA block cipher. First we will give a description
of the encryption process. Then we will describe our algebraic description of the cipher. After that we
will describe our attacks on the cipher. As in the previous chapter we will first consider a pure algebraic
attack on a reduced round version and then add side channel information to the equation system.
3.1 DVBCSA
The DVBCSA (Digital Video Broadcasting Common Scrambling Algorithm) encryption standard was standardized by the ETSI in 1994 but most details about the standard remained secret. In 2002 a software
implementation of DVB-CSA appeared on the internet and was reverse engeneered giving a complete
description of the cipher. The block cipher used in DVBCSA operates with 64-bit keys on 64-bit blocks.
It consists of 56 identical rounds that use eight bit round keys. In DVBCSA the block cipher is used to
encrypt up to 23 64-bit blocks using the CBC mode in reverse block order (starting with the last block).
The first block then is used as IV for the CSA stream cipher to all but the first block of the intermediate
ciphertext. This scheme is completely deterministic and does not expand (padding IV) the message when
encrypted. However in many cases it was observed that DVBCSA is used with 48-bit keys with 2 bytes of
checksum padding the key to 64-bit.
Figure 3.1.: DVB-CSA encryption process [19]
Block 1
Block 2
Block 3
Block...
⊕
⊕
⊕
⊕
E
E
E
E
E
Block 1
Block 2
Block 3
Block...
Block 23
K
Block 1
⊕
Stream
cipher
Block 2
⊕
Block 3
⊕
Block 23
Block...
⊕
Block 23
Keystream
3.2 The design of the CSA block cipher
3.2.1 Key schedule
The Key schedule of the CSA block cipher makes use of a fixed bit index permutation (permute_block())
that operates on 64-bit words. The key schedule expands a 64 bit key into 56 8bit round keys. Since
16
permute_block() like all bit permutations is completely linear the key schedule is linear; i.e. every bit of
every round key depends on exactly one bit of the original key.
w i = per mut e_ bl ock(w i+1 ⊕ 0x0101010101010101 ∗ (i + 1)) ⊕ (0x0101010101010101 ∗ i)
w6 = K ⊕ 0x0606060606060606
The 56 eight bit round keys are w0 ||w1 ||w2 ||w3 ||w4 ||w5 ||w6 (starting with the first roundkey).
Table 3.1.: per mut e_ block(X )
permutes the bits in X as in this table (octal notation):
0
1
2
3
4
5
6
7
00 19 27 55 46 1 15 36 22
10 56 61 39 21 54 58 50 28
20 7 29 51 6 33 35 20 16
30 47 30 32 63 10 11 4 38
40 62 26 40 18 12 52 37 53
50 23 59 41 17 31 0 25 43
60 44 14 2 13 45 48 3 60
70 49 8 34 5
9 42 57 24
3.2.2 The round function
The CSA block cipher is made up of 56 identical rounds of which each uses a 8-bit round key. The round
function consists of six XOR operations on application of a fixed S-Box and fixed bit permutation.
Figure 3.2.: DVB-CSA block cipher round function [19]
b0,i-1 b1,i-1 b2,i-1 b3,i-1 b4,i-1 b5,i-1 b6,i-1 b7,i-1
KS[i]
S-Box
P
b0,i
b1,i
b2,i
b3,i
b4,i
b5,i
b6,i
b7,i
17
S-Box
00
10
20
30
40
50
60
70
80
90
a0
b0
c0
d0
e0
f0
Table 3.2.: (the lower nibble indexes the columns, hexadecimal notation)
0
1
2
3
4
5
6
7
8
9
a
b
c
d
e
3a ea 68 fe 33 e9 88 1a 83 cf e1 7f ba e2 38
e8 27 61 95 0c 36 e5 70 a2 06 82 7c 17 a3 26
be 7a 6d 47 c1 51 8f f3 cc 5b 67 bd cd 18 08
ff 69 ef 03 4e 48 4a 84 3f b4 10 04 dc f5 5c
16 ab ac 4c f1 6a 2f 3c 3b d4 d5 94 d0 c4 63
71 a1 f9 4f 2e aa c5 56 e3 39 93 ce 65 64 e4
6c 19 42 79 dd ee 96 f6 8a ec 1e 85 53 45 de
7e 0a 9a 13 2a 9d c2 5e 5a 1f 32 35 9c a8 73
29 3d e7 92 87 1b 2b 4b a5 57 97 40 15 e6 bc
eb c3 34 2d b8 44 25 a4 1c c7 23 ed 90 6e 50
99 9e 4d d9 da 8d 6f 5f 3e d7 21 74 86 df 6b
8e 5d 37 11 d2 28 75 d6 a7 77 24 bf f0 b0 02
f8 fc 81 09 b1 01 76 91 7d 0f c8 a0 f2 cb 78
d1 f7 e0 b5 98 22 b3 20 1d a6 db 7b 59 9f ae
fb d3 b6 ca 43 72 07 f4 d8 41 14 55 0d 54 8b
ad 46 0b af 80 52 2c fa 8c 89 66 fd b2 a9 9b
f
12
49
c9
c6
62
58
bb
30
0e
00
05
b7
60
31
b9
c0
PBox
The P function is a bit index permutation.
0 1 2 3 4 5 6 7
P=
.
1 7 5 4 2 6 0 3
Like all other steps of the CSA round function except the S-Box it is linear.
3.3 Previous cryptanalysis of CSA
In 2011 Tews, Weiner, and Wälde presented a time memory trade-off [19] to break DVBCSA within the
average lifetime of a key (7 seconds). However this attack uses some assumptions about how DVBCSA
is used. Most importantly the attack exploits the fact that in almost all its applications DVBCSA is used
with a 48 bit key space (checksums within the key) and that repeating all zero messages in plain text of
tv stations can be observed; as well as the fact that DVBCSA is completely deterministic meaning that
the same key and message will always result in the same cipher-text.
In 2004 Weinmann and Wirt found a practical attack [20] on the DVB stream cipher that exploits very
short cycle length in the stream ciphers output.
A first analysis of the block cipher was done by Weinmann and Wirt in 2004 in which they ruled out
straight forward linear and differential cryptanalysis. They also ruled out algebraic cryptanalysis based
on the high degree and density of all possible interpolations of the S-Box. In 2005 Wirt published a fault
attack [21] on the block cipher.
18
3.4 A Meet in the Middle Attack on up to 15 rounds of CSA
The key schedule of the CSA block cipher produces 57 8-bit round keys r0..56 . Also every bit of a round
key depends on only one bit of the actual key. Another Observation is that ri∗8..(i+1)∗8 is a bit permutation
of the 64-bit key XOR the constant 0x iiiiiiii . Therefore it is very easy to stage a Meet in the Middle attack
on the first eight rounds using only 232 trial encryptions to recover the key. One decrypts four rounds of
the cipher-text with all possible round keys for these four rounds and stores these intermediate values
and their corresponding round keys in a sorted table or other data structure that allows efficient lookups.
The memory consumption of this table is about 12 ∗ 232 byte (i.e. 48 GB) and can be precomputed. To
recover the key one now encrypts the plain-text with all possible round keys for the first four rounds.
Once an intermediate cipher-text is produced that is also in the table a key is found that will encrypt the
plain-text to the cipher-text. The same attack can be applied to 15 rounds of the cipher by guessing the
last seven round keys leaving only eight unknown bits for the first eight rounds. These bits are:
5
9
26
32
44
54
55
60
The cost of this attack are worth approximately 260 trial encryptions. We are going to compare any
attacks against CSA for less then 15 rounds against this generic attack since it is faster than brute force.
The memory consumption in this case is only a few bytes since the memory trade-off is used only to
recover the 8 remaining unknown bits of the key.
3.5 An algebraic cryptanalysis of the CSA block cipher
In this section we are going to present an algebraic attack on up to 15 rounds of the block cipher.
The attack does not exploit potentially present checksums within the key and recovers the 64-bit key
faster then brute force or the previously presented algebraic attack. The attack guesses the first 4 round
keys (and therewith 32 bit of the original key). After that the remaining 32 bits of the key are being
determined (if possible) by applying cryptominisat [16].
3.5.1 An algebraic description of the CSA round function
In order to apply algebraic cryptanalysis to this cipher one must find a suitable algebraic description of
it. Most parts of the round function are purely linear and will result in linear combinations of the input
variables. The only nonlinear part is the S-Box. Modeling the S-Box algebraically is done by reading a
CNF from its truth table. An unoptimized truth table CNF for an 8 bit S-Box has exactly 2048 clauses
each having a length of 9. Using the PoLyBoRi [9] encoder we used the interpolation polynomials from
the S-Box and obtained a system of 916 clauses that gives a slight speedup compared to the trivial system
of clauses. The equation generator that is used can be found in the appendix.
3.6 Key bit guessing strategy
To aid cryptominisat by providing material that is easily propagated throughout the equation system we
choose to guess the key bits corresponding to the first 4 round keys. These key bits (starting at index 0)
have the indices:
17 56 49 7
8 52 41 30 55 18 4 10 46 1 37 58
33 44 15 48 59 13 61 28 22 53 24 26 16 42 23 47
Having guessed these four round keys one can encrypt the plain-text to an intermediate cipher text
after the 4th round. Thus reducing the attack to one that attacks 4 rounds less.
19
3.6.1 Experimental data on the speed of the attack
In order to compare the attack to brute force we created and solved 1000 random systems for 15 and
16 rounds of the cipher. Since the attack guesses 32-bits of the key all but one system will be in NSAT.
We were interested in the average time cryptominisat [16] needs to determine that a system is unsolvable (UNSAT). Therefore the 1000 systems were created with random keys and plain-texts and random
guesses for the first 4 round keys. The average time to prove UNSAT for a system with the optimized
set of clauses (and having the fist 4 round keys guessed) for the S-Box is 12.31s. This puts the time for
an successful attack to 52876928281 seconds (1677 years). To run the attack in near real time would
require excessive amounts of resources and totally outweight the gain (remember CSA is mostly used
for paytv DRM in a setting that changes the key about every 7 seconds). To estimate the time required
for brute force we conducted similar experiments with optimized software implementations of the CSA
block cipher. In these experiments the average time to do a single encryption was 0.06184µs. The
estimate for a successful brute force attack is 36176 years.
3.7 A algebraic side channel analysis of the CSA block cipher
We observed that we were not able to recover the key (using SAT solvers) even if we add the Hamming
weights of every S-Box output to the equation system. However once the Hamming weights of the S-Box
input bytes were available as well cryptominisat [16] was able to solve systems for the full cipher within
a minute. This observation is interesting since the side channel information for the first 10 rounds (20
Hamming weights) seems to suffice to recover the key while when only using the Hamming weight after
the S-Box 56 Hamming weights do not suffice to recover the key in acceptable time.
If less Hamming weights are available they can be used to support an algebraic attack on full round
CSA. In our experiments adding the same side channel information as in the previous section except
only for 5 rounds (rounds 3 to 7 inclusive) enabled cryptominisat to determine UNSAT within 412ms on
average. We conducted 1000 experiments the maximum time required to determine UNSAT was 500ms
while the minimum was 300ms. On average an attacker will have to process 231 systems until a fiting
key is found. The time to do this would be 1024.03 days (2.8 years) on a single core. All experiments
were conducted on a 2.3 GHz AMD Opteron CPU.
20
4 Conclusion
In this work we attempted to break the security of the LED and CSA block ciphers. We found attacks
on both primitives; however these attacks use strong assumptions (i.e. the availability of side channel
information). When attempting to break these ciphers without the use of side channel informations
we were able to attack reduced versions of both ciphers. Even though the attacks presented in this
work do not pose a direct threat to users of these ciphers, they do discourage the use of both ciphers
in a setting in which side channel information can be obtained by an attacker. Since counter measures
against side channel attacks consume space in hardware implementations these attacks hurt the value of
both ciphers in lightweight cryptography application. Future work could focus on reducing assumptions
and increasing the performance of the attacks.
21
Bibliography
[1] F. Abed, C. Forler, E. List, S. Lucks, and J. Wenzel. Biclique Cryptanalysis of the PRESENT and LED
Lightweight Ciphers. Technical report, Cryptology ePrint Archive, Report 2012/591, 2012.
[2] D. Asonov and R. Agrawal. Keyboard acoustic emanations. In Security and Privacy, 2004. Proceedings. 2004 IEEE Symposium on, pages 3–11. IEEE, 2004.
[3] G.V. Bard. Algebraic cryptanalysis. Springer, 2009.
[4] D.J. Bernstein. Cache-timing attacks on aes.
20050414. pdf, 2005.
URL: http://cr. yp. to/antiforgery/cachetiming-
[5] E. Biham and A. Shamir. Differential cryptanalysis of DES-like cryptosystems. Journal of CRYPTOLOGY, 4(1):3–72, 1991.
[6] E. Biham and A. Shamir. Power analysis of the key scheduling of the AES candidates. In Proceedings
of the second AES Candidate Conference, pages 115–121, 1999.
[7] A. Biryukov and D. Wagner. Slide Attacks. In Fast Software Encryption, pages 245–259. Springer,
1999.
[8] A. Bogdanov, L. Knudsen, G. Leander, C. Paar, A. Poschmann, M. Robshaw, Y. Seurin, and C. Vikkelsoe. PRESENT: An ultra-lightweight block cipher. Cryptographic Hardware and Embedded SystemsCHES 2007, pages 450–466, 2007.
[9] M. Brickenstein and A. Dreyer. POLYBORI: A Gröbner basis framework for Boolean polynomials. Keywords: Gröbner basis, formal verification, Boolean polynomials, algebraic cryptoanalysis,
satisfiability, 23, 2007.
[10] M. Davis and H. Putnam. A computing procedure for quantification theory. Journal of the ACM
(JACM), 7(3):201–215, 1960.
[11] W. Diffie and M.E. Hellman. Special Feature Exhaustive Cryptanalysis of the NBS Data Encryption
Standard. Computer, 10(6):74–84, 1977.
[12] Michael Dollichon. Kryptanalyse der Blockciffre Light Encryption Device (LED), 2012.
[13] J. Guo, T. Peyrin, A. Poschmann, and M. Robshaw. The LED block cipher. Cryptographic Hardware
and Embedded Systems–CHES 2011, pages 326–341, 2011.
[14] K. Jeong, H.C. Kang, C. Lee, J. Sung, and S. Hong. Biclique Cryptanalysis of Lightweight Block
Ciphers PRESENT, Piccolo and LED.
[15] K. Jeong and C. Lee. Differential Fault Analysis on Block Cipher LED-64. Future Information
Technology, Application, and Service, pages 747–755, 2012.
[16] Karsten Nohl Mate Soos and Claude Castelluccia. Extending SAT Solvers to Cryptographic Problems. 2009.
[17] M. Matsui. Linear cryptanalysis method for DES cipher. In Advances in Cryptology—EUROCRYPT’93,
pages 386–397. Springer, 1994.
[18] F.P.U.B. NIST. 197,Advanced Encryption Standard (AES), november 2001.
22
[19] E. Tews, J. Wälde, and M. Weiner. Breaking DVB-CSA. WEWoRC West European Workshop on
Reasearch in Cryptography 2011, pages 41–45, 2011.
[20] R.P. Weinmann and K. Wirt. Analysis of the DVB (Common Scrambling Algorithm). In Communications and Multimedia Security, pages 195–207. Springer, 2005.
[21] K. Wirt. Fault attack on the DVB common scrambling algorithm. Computational Science and Its
Applications–ICCSA 2005, pages 511–577, 2005.
23
A Appendix
1
3
5
7
from sage . s a t . c o n v e r t e r s . p o l y b o r i import CNFEncoder
from sage . s a t . s o l v e r s . dimacs import DIMACS
import i t e r t o o l s
import g e t o p t
import f u n c t o o l s
import s y s
import random
9
11
R=BooleanPolynomialRing (40000 , " x " )
V=R^4 # 4 t u p l e o f p o l y n o m i a l s
13
SBOX=mq . SBox (12 , 5 , 6 , 11 , 9 , 0 , 10 , 13 , 3 , 14 , 15 , 8 , 4 , 7 , 1 , 2) # t h e p r e s e n t sbox
15
RC=(0x01 , 0x03 , 0x07 , 0x0F , 0x1F , 0x3E , 0x3D , 0x3B , 0x37 , 0x2F ,
0x1E , 0x3C , 0x39 , 0x33 , 0x27 , 0x0E , 0x1D , 0x3A , 0x35 , 0x2B ,
0x16 , 0x2C , 0x18 , 0x30 , 0x21 , 0x02 , 0x05 , 0x0B , 0x17 , 0x2E ,
0x1C , 0x38 , 0x31 , 0x23 , 0x06 , 0x0D , 0x1B , 0x36 , 0x2D , 0x1A ,
0x34 , 0x29 , 0x12 , 0x24 , 0x08 , 0x11 , 0x22 , 0x04 )
17
19
21
23
25
27
29
GF16MUL2=m a t r i x (R , 4 , 4 ) # t h i s m a t r i x m u l t i p l i e s an element i n GF( 2 ) [ x ] / x ** 4 + x + 1 with
(0 ,0 ,1 ,0)
GF16MUL2[0]=(0 ,0 ,1 ,1)
GF16MUL2[1]=(1 ,0 ,0 ,0)
GF16MUL2[2]=(0 ,1 ,0 ,0)
GF16MUL2[3]=(0 ,0 ,1 ,0)
d e f b4 ( x ) :
l = l i s t (map( lambda i : ( x>>i ) & 1 , ( 0 , 1 , 2 , 3 ) ) )
l . reverse ()
return tuple ( l )
31
33
35
37
39
41
43
45
47
49
51
53
d e f b64 ( x ) :
l = l i s t (map( lambda i : ( x>>i ) &1 , range (64) ) )
l . reverse ()
return tuple ( l )
d e f hamming ( v , n ) :
x0 , x1 , x2 , x3 = v
i f n == 0 :
r e t u r n [ x0 , x1 , x2 , x3 ]
e l i f n == 1 :
r e t u r n [ x0 + x1 + x2 + x3 + 1 ,
x0 * x1 ,
x0 * x2 ,
x0 * x3 ,
x1 * x2 ,
x1 * x3 ,
x2 * x3 ]
e l i f n == 2 :
r e t u r n [ x0 * x1+x0 * x2+x0 * x3+x1 * x2+x1 * x3+x2 * x3+ 1 ,
x0 * x1 * x2 , x1 * x2 * x3 , x0 * x2 * x3 , x0 * x1 * x3 ]
e l i f n == 3 :
r e t u r n [ x0 * x1 * x2 + x1 * x2 * x3 + x0 * x2 * x3 + x0 * x1 * x3 + 1 , x0 * x1 * x2 * x3 ]
e l i f n == 4 :
24
55
57
59
61
63
65
67
r e t u r n [ x0 * x1 * x2 * x3 + 1]
else :
return []
d e f lessthenhamming ( v ,w) :
v = l i s t (map( lambda x : i n t ( g e t i d x ( x ) ) , v ) )
r = set ([])
n = len (v)
f o r c i n i t e r t o o l s . c o m b i n a t i o n s ( v ,w+1) :
r . add ( ( " " . j o i n (map( lambda x : s t r (− x ) , c ) ) )+" 0\n " )
f o r c i n i t e r t o o l s . c o m b i n a t i o n s ( v , ( n−w)+1) :
r . add ( ( " " . j o i n (map( lambda x : s t r ( x ) , c ) ) )+" 0\n " )
return " " . join ( l i s t ( r ) )
69
71
73
75
77
79
81
83
85
87
89
91
93
95
97
99
101
103
105
107
109
111
113
d e f mul ( v , n ) :
m = GF16MUL2
b = V((0 ,0 ,0 ,0) )
while n > 0:
i f ( n%2) == 1 :
b=b+v
v = v *m
n >>= 1
return b
d e f vecprod ( u , v ) :
l = l i s t (map( lambda x , y : mul ( x , y ) , u , v ) )
r e t u r n f u n c t o o l s . reduce ( lambda x , y : x+y , l )
def addconsts ( state , r ) :
s t a t e [ 4] = s t a t e [ 4]
s t a t e [ 8] = s t a t e [ 8]
s t a t e [12] = s t a t e [12]
tmp = (RC[ r ]>>3)&7
v = V( b4 ( tmp ) )
s t a t e [ 1] = s t a t e [ 1]
s t a t e [ 9] = s t a t e [ 9]
tmp = RC[ r ]&7
v = V( b4 ( tmp ) )
s t a t e [ 5] = s t a t e [ 5]
s t a t e [13] = s t a t e [13]
return state
+ V((0 ,0 ,0 ,1) )
+ V((0 ,0 ,1 ,0) )
+ V((0 ,0 ,1 ,1) )
+ v
+ v
+ v
+ v
def s h i f t r o w s ( s t a t e ) :
def s h i f t ( x ) :
tmp = s t a t e [ x * 4 : x *4+4]
tmp = tmp [ x :4]+tmp [ 0 : x ]
f o r i i n range ( 4 ) :
s t a t e [ x*4+ i ] = tmp [ i ]
for i in (1 ,2 ,3) :
shift ( i )
return state
d e f mix ( v ) :
mcol = ( ( 4 , 1 , 2 , 2 ) , ( 8 , 6 , 5 , 6 ) , ( 0 xb , 0 xe , 0 xa , 9 ) , ( 2 , 2 , 0 xf , 0 xb ) )
r e t u r n t u p l e (map( lambda i : vecprod ( v , mcol [ i ] ) , ( 0 , 1 , 2 , 3 ) ) )
d e f mix4th ( v ) :
mcol = ( ( 0 , 1 , 0 , 0 ) , ( 0 , 0 , 1 , 0 ) , ( 0 , 0 , 0 , 1 ) , ( 4 , 1 , 2 , 2 ) )
25
115
r e t u r n t u p l e (map( lambda i : vecprod ( v , mcol [ i ] ) , ( 0 , 1 , 2 , 3 ) ) )
117
119
121
123
125
127
129
131
133
d e f m i x c o l ( s t a t e , s m a l l=F a l s e ) :
def g e t c o l ( x ) :
r e t u r n l i s t (map( lambda i : s t a t e [ x+i * 4 ] , range ( 4 ) ) )
def s e t c o l ( c , x ) :
f o r i i n range ( 4 ) :
s t a t e [ x+i * 4] = c [ i ]
f o r i i n range ( 4 ) :
i f small :
s e t c o l ( mix4th ( g e t c o l ( i ) ) , i )
else :
s e t c o l ( mix ( g e t c o l ( i ) ) , i )
return state
def l i n s t e p ( s t a t e ) :
state = shiftrows ( state )
s t a t e = mixcol ( s t a t e )
return state
135
137
d e f i n j e c t k e y ( s t a t e , key ) :
f o r i i n range (16) :
s t a t e [ i ] = s t a t e [ i ] + key [ i ]
139
141
143
def p r i n t s ( s ) :
print ( s [0:4])
print ( s [4:8])
print ( s [8:12])
p r i n t ( s [12:16])
145
147
d e f pack4 ( s ) :
r e t u r n l i s t (map( lambda i : V( t u p l e ( s [ i * 4 : i * 4+4]) ) , range (16) ) )
149
151
153
155
157
159
def getequations ( o l d s t a t e , newstate ) :
l = []
f o r i i n range (16) :
x0 , x1 , x2 , x3 = o l d s t a t e [ i ]
x4 , x5 , x6 , x7 = n e w s t a t e [ i ]
l = l + [
x1 * x2 + x0 + x1 + x3 + x7 ,
x0 * x1 * x3 + x0 * x2 * x3 + x1 * x2 * x3 + x0 * x1 + x0 * x2 + x0 + x2 + x6 ,
x0 * x1 * x3 + x0 * x2 * x3 + x0 * x2 + x0 * x3 + x2 * x3 + x0 + x1 + x5 + 1 ,
x0 * x1 * x3 + x0 * x2 * x3 + x1 * x2 * x3 + x1 * x2 + x0 + x2 + x3 + x4 + 1]
return l
161
163
165
167
169
171
173
d e f e n c r y p t ( p , k , rounds =32, s i d e c h a n n l e=None ) :
hamming = [ ]
key = pack4 ( b64 ( k ) )
p l a i n = pack4 ( b64 ( p ) )
f o r r i n range ( rounds ) :
i f ( r % 4) == 0 :
i n j e c t k e y ( p l a i n , key )
plain = addconsts ( plain , r )
p l a i n = l i s t (map( lambda x : V(SBOX( t u p l e ( x ) ) ) , p l a i n ) ) # we have t o b r i n g e v e r y t h i n g back
t o GF( 2 )^4 a f t e r t h e sbox
i f r in sidechannle :
hamming += [ [ r , l i s t (map( lambda x : t u p l e ( x ) . count ( 1 ) , p l a i n ) ) ] ]
plain = linstep ( plain )
26
175
177
i n j e c t k e y ( p l a i n , key )
c t e x t = l i s t ( reduce ( lambda x , y : l i s t ( x )+ l i s t ( y ) , p l a i n ) )
c t e x t = reduce ( lambda x , y : i n t ( x ) * 2 + i n t ( y ) , c t e x t )
r e t u r n ( c t e x t , hamming )
179
181
183
185
187
189
d e f p o l y c u t ( poly , v , n ) :
r = []
pt = l i s t ( tuple (( poly ) ) )
while len ( pt ) > n :
t v = v . pop ( 0 )
r . i n s e r t ( 0 , sum( p t [ 0 : n]+[ t v ] ) )
pt = pt [n : ]
pt . i n s e r t (0 , tv )
i f len ( pt ) > 0:
r . i n s e r t ( 0 , sum( p t ) )
return r
191
193
def getidx (p) :
v i = p . vars_as_monomial ( ) . v a r i a b l e s ( ) [ 0 ] . index ( )+1
return vi
195
197
199
201
203
205
207
209
211
213
215
217
219
221
223
225
227
229
231
233
d e f g e t c n f ( s , ns ) :
r = ""
x0 , x1 , x2 , x3 = map( lambda x : s t r ( g e t i d x ( x ) ) , s [ i ] )
y0 , y1 , y2 , y3 = map( lambda x : s t r ( g e t i d x ( x ) ) , ns [ i ] )
clausels = [
[ y0 , y1 , y2 , x0 ] ,
[ y0 , y2 , y3 , x0 ] ,
[ y0 , y2 , x0 , x1 ] ,
[ y0 , y1 , y3 , x2 ] ,
[ y0 , y2 , y3 , x2 ] ,
[ y1 , y2 , y3 , x2 ] ,
[ y0 , y2 , x0 , x2 ] ,
[ y1 , y2 , x0 , x2 ] ,
[ y1 , y3 , x0 , x2 ] ,
[ y0 , y2 , x1 , x2 ] ,
[ y1 , y2 , x1 , x2 ] ,
[ y0 , y3 , x1 , x2 ] ,
[ y1 , y3 , x0 , x3 ] ,
[ y2 , y3 , x0 , x3 ] ,
[ y3 , x0 , x1 , x3 ] ,
[ y0 , y2 , x2 , x3 ] ,
[ y1 , y2 , x2 , x3 ] ,
[ y2 , y3 , x2 , x3 ] ,
[ y2 , x0 , x2 , x3 ] ,
[ y2 , x1 , x2 , x3 ] ,
[ y1 , y2 , x2 , − y0 ] ,
[ y1 , x0 , x2 , − y0 ] ,
[ y2 , y3 , x3 , − y0 ] ,
[ y3 , x0 , x3 , − y0 ] ,
[ x0 , x2 , x3 , − y0 ] ,
[ y0 , y2 , x1 , − y1 ] ,
[ y0 , y3 , x1 , − y1 ] ,
[ y0 , x0 , x1 , − y1 ] ,
[ y0 , y2 , x2 , − y1 ] ,
[ y2 , y3 , x3 , − y1 ] ,
[ x1 , x3 , − y1 ] ,
[ y0 , x1 , x3 , − y1 ] ,
27
235
237
239
241
243
245
247
249
251
253
255
257
259
[ y2 , x1 , x3 , − y1 ] ,
[ y3 , x1 , x3 , − y1 ] ,
[ x0 , x1 , x3 , − y1 ] ,
[ x1 , x2 , x3 , − y1 ] ,
[ y3 , x3 , − y0 , − y1 ] ,
[ x0 , x3 , − y0 , − y1 ] ,
[ x1 , x3 , − y0 , − y1 ] ,
[ y1 , x0 , − y0 , − y2 ] ,
[ y3 , x0 , − y0 , − y2 ] ,
[ x0 , x1 , − y0 , − y2 ] ,
[ x0 , x3 , − y0 , − y2 ] ,
[ x0 , x1 , − y1 , − y2 ] ,
[ x1 , x3 , − y1 , − y2 ] ,
[ x3 , − y0 , − y1 , − y2 ] ,
[ y0 , y2 , x1 , − y3 ] ,
[ y2 , x0 , x2 , − y3 ] ,
[ y2 , x1 , x2 , − y3 ] ,
[ y1 , x2 , − y0 , − y3 ] ,
[ x1 , x2 , − y0 , − y3 ] ,
[ y2 , x1 , − y1 , − y3 ] ,
[ x0 , x1 , − y1 , − y3 ] ,
[ x1 , x3 , − y1 , − y3 ] ,
[ x1 , − y0 , − y1 , − y3 ] ,
[ x1 , − y0 , − y2 , − y3 ] ,
[ x3 , − y1 , − y2 , − y3 ] ]
c l a u s e l s = map( lambda x : map( s t r , x ) , c l a u s e l s )
r e t u r n " \n " . j o i n ( l i s t (map( lambda x : " " . j o i n ( x ) , l i s t ( c l a u s e l s ) ) ) )
261
263
265
267
269
271
d e f c u t a l l ( s , var , n ) :
rs = []
for p in s :
r s = r s + p o l y c u t ( p , var , n )
return rs
def p l i n ( x ) :
i f x . deg ( ) != 1 : r e t u r n F a l s e
i f l e n ( x ) < 10: r e t u r n F a l s e
r e t u r n True
273
275
277
279
def encodelinear (p) :
i f p . deg ( ) != 1 : r a i s e V a l u e E r r o r ( " p o l y n o m i a l must be o f degree 1 " )
i f l e n ( p ) == 1 :
r a i s e V a l u e E r r o r ( " p o l y n o m i a l must have l e n g t h > 1 " )
v a r = l i s t ( p . vars_as_monomial ( ) . v a r i a b l e s ( ) )
i d x = [ v . index ( )+1 f o r v i n v a r ]
i f not p . h a s _ c o n s t a n t _ p a r t ( ) : i d x [ − 1] = − i d x [ − 1]
r e t u r n " x " +( " " . j o i n (map( lambda x : s t r ( x ) , i d x ) ) )+" 0 "
281
283
285
287
289
291
293
def l i n e a r i z e ( s , v ) :
rs = []
vmap = {}
for p in s :
pt = l i s t ( tuple (p) )
f o r i i n range ( l e n ( p t ) ) :
i f p t [ i ] . deg ( ) > 1 :
i f not p t [ i ] i n vmap :
v t = v . pop ( 0 )
vmap[ p t [ i ] ] = v t
p t [ i ] = vmap[ p t [ i ] ]
r s = r s + [sum( p t ) ]
28
295
f o r i i n vmap :
r s = r s +[ i + vmap[ i ] ]
return rs , v
297
299
301
303
305
307
309
311
313
315
317
319
321
323
325
327
329
331
333
335
337
339
341
343
345
347
349
351
d e f g e t P o l y n o m i a l S y s t e m ( p , c , rounds =32,k=None , k e y i n j e c t =64, i n t e r m e d i a t e=True , c n f=True ,
p l i n e a r i z e=True , s i d e c h a n n l e = { } ) :
cnf = " "
p l a i n b i t s = pack4 ( b64 ( p ) )
c i p h e r b i t s = pack4 ( b64 ( c ) )
system = [ ]
v = R . gens ( )
key = pack4 ( v )
v = v [64:]
s = pack4 ( v )
system = system + l i s t ( reduce ( lambda x , y : l i s t ( x )+ l i s t ( y ) , map( lambda x , y : x+y , s ,
plainbits )))
v = v [64:]
ns = pack4 ( v )
v = v [64:]
i f cnf :
i n t e r m e d i a t e = True
f o r r i n range ( rounds ) :
i f ( r % 4) == 0 :
i n j e c t k e y ( s , key )
s = addconsts ( s , r )
i f intermediate :
i n j e c t k e y ( s , ns )
system = system + l i s t ( reduce ( lambda x , y : l i s t ( x )+ l i s t ( y ) , s ) )
s = ns
ns = pack4 ( v )
v = v [64:]
system = system + g e t e q u a t i o n s ( s , ns )
i f r in sidechannle :
f o r i i n range (16) :
c n f += lessthenhamming ( ns [ i ] , s i d e c h a n n l e [ r ] [ i ] )
s = ns
ns = pack4 ( v )
v = v [64:]
s = shiftrows ( s )
f o r i i n range ( 4 ) :
s = m i x c o l ( s , True )
i n j e c t k e y ( s , ns )
system = system + l i s t ( reduce ( lambda x , y : l i s t ( x )+ l i s t ( y ) , s ) )
s = ns
ns = pack4 ( v )
v = v [64:]
i n j e c t k e y ( s , key )
i n j e c t k e y ( s , ns )
i n j e c t k e y ( ns , c i p h e r b i t s )
system = system + l i s t ( reduce ( lambda x , y : l i s t ( x )+ l i s t ( y ) , s ) )
system = system + l i s t ( reduce ( lambda x , y : l i s t ( x )+ l i s t ( y ) , ns ) )
i f key!=None :
k e y b i t s = pack4 ( b64 ( k ) )
kb = l i s t ( reduce ( lambda x , y : l i s t ( x )+ l i s t ( y ) ,map( lambda x , y : x+y , key , k e y b i t s ) ) )
i f k e y i n j e c t == 28:
kb = kb [0:4]+ kb [16:24]+ kb [32:36]+ kb [40:44]+ kb [48:52]+ kb [ 6 0 : 6 4 ]
e l i f k e y i n j e c t == 16:
kb = kb [0:4]+ kb [20:24]+ kb [40:44]+ kb [ 6 0 : 6 4 ]
e l i f k e y i n j e c t == 32:
kb = kb [0:8]+ kb [20:28]+ kb [40:48]+ kb [60:64]+ kb [ 4 8 : 5 2 ]
29
353
355
357
359
361
363
365
367
system = system+kb
else :
system = system + kb [ 0 : k e y i n j e c t ]
if plinearize :
system , v = l i n e a r i z e ( system , l i s t ( v ) )
mqsystem = f i l t e r ( lambda x : not p l i n ( x ) , t u p l e ( system ) )
l i n s y s t e m = f i l t e r ( lambda x : p l i n ( x ) , t u p l e ( system ) )
f n = tmp_filename ( )
s o l v e r = DIMACS( f i l e n a m e=f n )
CE = CNFEncoder ( s o l v e r , R)
f o r p o l y i n mqsystem :
CE . c l a u s e s ( p o l y )
solver . write ()
r e s u l t = open ( f n ) . read ( )
for le in linsystem :
r e s u l t += e n c o d e l i n e a r ( l e )+" \n "
r e t u r n r e s u l t + " \n " + c n f + " \n " + " c key i s 0x "+hex ( k ) + " \n "
369
371
373
375
377
379
381
d e f usage ( ) :
print " " "
−e
e n c r y p t p l a i n t e x t with key and o u t p u t c i p h e r − t e x t
−u
g e n e r a t e system f o r random key
− r <rounds> number o f rounds ( d e f a u l t : 32)
−p <p t e x t > s e t p l a i n − t e x t ( d e f a u l t : random )
−k <key> s e t key ( d e f a u l t : random )
−c <c t e x t > s e t c i p h e r − t e x t ( d e f a u l t : random )
− i #b i t s number o f guessed k e y b i t s ( d e f a u l t : 0)
− s <s i d e >
coma s e p e r a t e d l i s t o f rounds t o e x t r a c t s i d e channel i n f o r m a t i o n from
−e
j u s t e n c r y p t p l a i n − t e x t u s i n g key
"""
sys . e x i t (1)
383
opts , a r g s = g e t o p t . g e t o p t ( s y s . argv [ 1 : ] , " huek : p : c : s : r : i : " )
385
r , u , c , p , k , i , s , e = 32 ,0 , − 1 , − 1 , − 1 ,0 ,[] ,0
387
389
391
393
395
397
399
401
403
405
f o r op i n o p t s :
i f op [ 0 ] == "−p " :
p = i n t ( op [ 1 ] , 1 6 )
e l i f op [ 0 ] == "−c " :
c = i n t ( op [ 1 ] , 1 6 )
e l i f op [ 0 ] == "−k " :
k = i n t ( op [ 1 ] , 1 6 )
e l i f op [ 0 ] == "− s " :
s = l i s t (map( lambda x : i n t ( x ) , op [ 1 ] . s p l i t ( " , " ) ) )
e l i f op [ 0 ] == "− r " :
r = i n t ( op [ 1 ] )
e l i f op [ 0 ] == "− i " :
i = i n t ( op [ 1 ] )
e l i f op [ 0 ] == "−e " :
e = 1
e l i f op [ 0 ] == "−u " :
u = 1
e l i f op [ 0 ] == "−h " :
usage ( )
407
409
i f p == −1:
p = random . r a n d i n t (0,1<<64)
411
i f k == −1:
30
413
key = random . r a n d i n t (0,1<<64)
else :
key = k
415
417
419
421
423
i f c == −1:
c , s i d e c h a n n l e = e n c r y p t ( p , key , rounds=r , s i d e c h a n n l e=s )
else :
tmp = c
c , s i d e c h a n n l e = e n c r y p t ( p , key , rounds=r , s i d e c h a n n l e=s )
c = tmp
i f u == 1 :
key = random . r a n d i n t (0,1<<64)
425
427
429
431
i f e == 0 :
system = g e t P o l y n o m i a l S y s t e m ( p , c , r , key , i , c n f=True , s i d e c h a n n l e=d i c t ( s i d e c h a n n l e ) )
p r i n t system
e l i f e == 1 :
print sidechannle
p r i n t " enc(%x,%x ) = %x " % ( p , key , c )
Listing A.1: LED equation generator
2
4
6
8
import
import
import
import
import
import
itertools
functools
sys
random
csasbox
getopt
R=BooleanPolynomialRing (40000 , " x " )
V=R^8 # 8 t u p l e o f p o l y n o m i a l s
10
12
14
16
18
20
22
24
26
28
30
32
34
36
SBOX = mq . SBox (
[0 x3a , 0xea , 0x68 , 0 xfe
0x83 , 0 x c f , 0xe1 , 0 x7f ,
0xe8 , 0x27 , 0x61 , 0x95 ,
0xa2 , 0x06 , 0x82 , 0x7c ,
0xbe , 0x7a , 0x6d , 0x47 ,
0 xcc , 0x5b , 0x67 , 0xbd ,
0 x f f , 0x69 , 0 xef , 0x03 ,
0 x3f , 0xb4 , 0x10 , 0x04 ,
0x16 , 0xab , 0xac , 0x4c ,
0x3b , 0xd4 , 0xd5 , 0x94 ,
0x71 , 0xa1 , 0 xf9 , 0 x4f ,
0xe3 , 0x39 , 0x93 , 0xce ,
0x6c , 0x19 , 0x42 , 0x79 ,
0x8a , 0xec , 0x1e , 0x85 ,
0x7e , 0x0a , 0x9a , 0x13 ,
0x5a , 0 x1f , 0x32 , 0x35 ,
0x29 , 0x3d , 0xe7 , 0x92 ,
0xa5 , 0x57 , 0x97 , 0x40 ,
0xeb , 0xc3 , 0x34 , 0x2d ,
0x1c , 0xc7 , 0x23 , 0xed ,
0x99 , 0x9e , 0x4d , 0xd9 ,
0x3e , 0xd7 , 0x21 , 0x74 ,
0x8e , 0x5d , 0x37 , 0x11 ,
0xa7 , 0x77 , 0x24 , 0 xbf ,
0 xf8 , 0 x f c , 0x81 , 0x09 ,
0x7d , 0 x0f , 0xc8 , 0xa0 ,
, 0x33 , 0xe9 , 0x88 , 0x1a ,
0xba , 0xe2 , 0x38 , 0x12 ,
0x0c , 0x36 , 0xe5 , 0x70 ,
0x17 , 0xa3 , 0x26 , 0x49 ,
0xc1 , 0x51 , 0 x8f , 0 xf3 ,
0xcd , 0x18 , 0x08 , 0xc9 ,
0x4e , 0x48 , 0x4a , 0x84 ,
0xdc , 0 xf5 , 0x5c , 0xc6 ,
0 xf1 , 0x6a , 0 x2f , 0x3c ,
0xd0 , 0xc4 , 0x63 , 0x62 ,
0x2e , 0xaa , 0xc5 , 0x56 ,
0x65 , 0x64 , 0xe4 , 0x58 ,
0xdd , 0xee , 0x96 , 0 xf6 ,
0x53 , 0x45 , 0xde , 0xbb ,
0x2a , 0x9d , 0xc2 , 0x5e ,
0x9c , 0xa8 , 0x73 , 0x30 ,
0x87 , 0x1b , 0x2b , 0x4b ,
0x15 , 0xe6 , 0xbc , 0x0e ,
0xb8 , 0x44 , 0x25 , 0xa4 ,
0x90 , 0x6e , 0x50 , 0x00 ,
0xda , 0x8d , 0 x6f , 0 x5f ,
0x86 , 0 xdf , 0x6b , 0x05 ,
0xd2 , 0x28 , 0x75 , 0xd6 ,
0 xf0 , 0xb0 , 0x02 , 0xb7 ,
0xb1 , 0x01 , 0x76 , 0x91 ,
0 xf2 , 0xcb , 0x78 , 0x60 ,
31
38
40
42
0xd1 ,
0x1d ,
0 xfb ,
0xd8 ,
0xad ,
0x8c ,
0 xf7 ,
0xa6 ,
0xd3 ,
0x41 ,
0x46 ,
0x89 ,
0xe0 ,
0xdb ,
0xb6 ,
0x14 ,
0x0b ,
0x66 ,
0xb5 ,
0x7b ,
0xca ,
0x55 ,
0 xaf ,
0 xfd ,
0x98 ,
0x59 ,
0x43 ,
0x0d ,
0x80 ,
0xb2 ,
0x22 ,
0 x9f ,
0x72 ,
0x54 ,
0x52 ,
0xa9 ,
0xb3 ,
0xae ,
0x07 ,
0x8b ,
0x2c ,
0x9b ,
0x20 ,
0x31 ,
0 xf4 ,
0xb9 ,
0 xfa ,
0xc0 ] )
44
46
48
50
52
d e f b8 ( x ) :
l = l i s t (map( lambda i : ( x>>i ) &1 , range ( 8 ) ) )
l . reverse ()
return tuple ( l )
d e f b64 ( x ) :
l = l i s t (map( lambda i : ( x>>i ) &1 , range (64) ) )
l . reverse ()
return tuple ( l )
54
56
58
def i64 ( x ) :
r e t u r n reduce ( lambda x , y : i n t ( x ) * 2 + i n t ( y ) , x )
d e f pack8 ( s ) :
r e t u r n l i s t (map( lambda i : V( t u p l e ( s [ i * 8 : i * 8+8]) ) , range ( 8 ) ) )
60
62
def getidx (p) :
v i = p . vars_as_monomial ( ) . v a r i a b l e s ( ) [ 0 ] . index ( )+1
return vi
64
66
68
def P( x ) :
p=[1 ,7 ,3 ,0 ,4 ,5 ,2 ,6]
p . reverse ()
r e t u r n V( t u p l e (map( lambda a : x [ p [ a ] ] , range ( 8 ) ) ) )
70
72
74
76
78
d e f lessthenhamming ( v ,w) :
v = l i s t (map( lambda x : i n t ( g e t i d x ( x ) ) , v ) )
r = set ([])
n = 8
f o r c i n i t e r t o o l s . c o m b i n a t i o n s ( v ,w+1) :
r . add ( ( " " . j o i n (map( lambda x : s t r (− x ) , c ) ) )+" 0\n " )
f o r c i n i t e r t o o l s . c o m b i n a t i o n s ( v , ( n−w)+1) :
r . add ( ( " " . j o i n (map( lambda x : s t r ( x ) , c ) ) )+" 0\n " )
return " " . join ( l i s t ( r ) )
80
82
84
86
88
90
92
94
96
d e f permuteblock ( x ) :
r = [ F a l s e ] * 64
x = tuple (x)
p=[36 ,31 ,54 ,8 ,22 ,50 ,1 ,55 ,61 ,51 ,24 ,26 ,45 ,49 ,7 ,10 ,39 ,60 ,11 ,15 ,
16 ,2 ,21 ,29 ,53 ,32 ,25 ,57 ,42 ,5 ,43 ,37 ,19 ,38 ,46 ,48 ,62 ,30 ,17 ,0 ,23 ,
56 ,52 ,41 ,63 ,28 ,20 ,40 ,58 ,14 ,12 ,27 ,34 ,35 ,3 ,6 ,47 ,44 ,4 ,33 ,9 ,13 ,59 ,18]
#r e t u r n t u p l e (map( lambda a : x [ p [ a ] ] , range (64) ) )
f o r i i n range (64) :
r [ i ] = x[p[ i ]]
return r
d e f k e y s c h e d u l e ( key ) :
ks = [ t u p l e ( key ) ]
f o r i i n range ( 6 ) :
ks = [ permuteblock ( ks [ 0 ] ) ] + ks
32
98
100
102
104
106
108
110
112
114
116
118
120
ks = l i s t (map( lambda x : pack8 ( x ) , ks ) )
ks = f u n c t o o l s . reduce ( lambda x , y : x+y , ks )
f o r i i n range (56) :
ks [ i ] = V( ks [ i ] )+V( b8 ( i n t ( i /8) ) )
r e t u r n ks
def getequations ( i , o) :
i i = t u p l e (map( g e t i d x , i ) )
oo = t u p l e (map( g e t i d x , o ) )
r = SBOX . c n f ( i i , oo , format=" dimacs " ) . s p l i t ( " \n " ) [ 1 : ]
r e t u r n " \n " . j o i n ( r )
def encodelinear (p) :
i f p . deg ( ) != 1 : r a i s e V a l u e E r r o r ( " p o l y n o m i a l must be o f degree 1 " )
i f l e n ( p ) == 1 : #r a i s e V a l u e E r r o r ( " p o l y n o m i a l must have l e n g t h > 1 " )
v = p . vars_as_monomial ( ) . v a r i a b l e s ( ) [ 0 ]
r = s t r ( v . index ( ) +1)+" 0 "
i f not p . h a s _ c o n s t a n t _ p a r t ( ) :
r = "− "+r
return r
v a r = l i s t ( p . vars_as_monomial ( ) . v a r i a b l e s ( ) )
i d x = [ v . index ( )+1 f o r v i n v a r ]
i f not p . h a s _ c o n s t a n t _ p a r t ( ) : i d x [ − 1] = − i d x [ − 1]
r e t u r n " x " +( " " . j o i n (map( lambda x : s t r ( x ) , i d x ) ) )+" 0 "
122
124
126
128
130
132
134
136
138
140
142
144
146
148
150
d e f e n c r y p t ( p , k , rounds =56, s i d e c h a n n l e =[]) :
r a s i d e = {}
r b s i d e = {}
ks = k e y s c h e d u l e ( b64 ( k ) )
s = pack8 ( b64 ( p ) )
f o r r i n range ( rounds ) :
t 1 = V( ks [ r ] ) + V( s [ 0 ] )
i f s i d e c h a n n l e and r i n s e t ( s i d e c h a n n l e ) :
r b s i d e [ r ] = t u p l e (map( lambda x : i n t ( x ) , t 1 ) ) . count ( 1 )
t 1 = V(SBOX( t u p l e ( t 1 ) ) )
i f s i d e c h a n n l e and r i n s e t ( s i d e c h a n n l e ) :
r a s i d e [ r ] = t u p l e (map( lambda x : i n t ( x ) , t 1 ) ) . count ( 1 )
t0 = s [6]
s [ 6 ] = s [7 ] + s [ 5 ]
s [ 5 ] = s [7 ] + s [ 4 ]
s [ 4 ] = s [7 ] + s [ 3 ]
s [ 3 ] = s [2 ]
s [ 2 ] = s [1 ] + V( P ( t 1 ) )
s [ 1 ] = s [0 ]
s [ 0 ] = s [7 ] + V( t 1 )
s [ 7 ] =V( t 0 )
s = list (s)
#s . r e v e r s e ( )
s = l i s t ( reduce ( lambda x , y : l i s t ( x )+ l i s t ( y ) , s ) )
s = reduce ( lambda x , y : i n t ( x ) * 2 + i n t ( y ) , s )
i f sidechannle :
return s , rbside , raside
return s
152
154
156
d e f g e t s y s t e m ( p t e x t , c t e x t , key , rounds =56, k e y i n j e c t =0, r b s ={} , r a s ={}) :
cnf = " "
system = [ ]
v = R . gens ( )
k , v = v [:64] , v [64:]
33
158
160
162
164
166
168
170
172
174
176
178
180
182
184
186
188
190
192
s , v = pack8 ( v [ : 6 4 ] ) , v [ 6 4 : ]
k e y b i t s = b64 ( key )
ks = k e y s c h e d u l e ( k )
p b y t e s = pack8 ( b64 ( p t e x t ) )
c b y t e s = pack8 ( b64 ( c t e x t ) )
f o r i i n range ( 8 ) :
system = system + l i s t ( ( p b y t e s [ i ] + s [ i ] ) )
f o r i i n range ( k e y i n j e c t ) :
r = [17 , 56 , 49 , 7 , 8 , 52 , 41 , 30 , 55 , 18 , 4 , 10 , 46 , 1 , 37 , 58 , 33 , 44 , 15 , 48 , 59 ,
13 , 61 , 28 , 22 , 53 , 24 , 26 , 16 , 42 , 23 , 47]
system = system + [R( k [ r [ i ]]+ k e y b i t s [ r [ i ] ] ) ]
f o r r i n range ( rounds ) :
t 1 = ks [ r ] + s [ 0 ]
ns1 , v = V( t u p l e ( v [ : 8 ] ) ) , v [ 8 : ]
ns2 , v = V( t u p l e ( v [ : 8 ] ) ) , v [ 8 : ]
system = system + l i s t ( t 1 + ns1 )
t 1 = V( ns1 )
i f r i n r b s . ke ys ( ) :
c n f += lessthenhamming ( ns1 , r b s [ r ] )
c n f = c n f + c s a s b o x . s b o x c l a u s e l s (map( g e t i d x , ns1 ) ,map( g e t i d x , ns2 ) ) + " \n "
i f r i n r a s . ke ys ( ) :
c n f += lessthenhamming ( ns2 , r a s [ r ] )
t 1 = V( ns2 )
t0 = s [6]
s [ 6 ] = s [7 ] + s [ 5 ]
s [ 5 ] = s [7 ] + s [ 4 ]
s [ 4 ] = s [7 ] + s [ 3 ]
s [ 3 ] = s [2 ]
s [ 2 ] = s [1 ] + V( P ( t 1 ) )
s [ 1 ] = s [0 ]
s [ 0 ] = s [7 ] + V( t 1 )
s [ 7 ] = V( t 0 )
f o r i i n range ( 8 ) :
system = system + l i s t ( ( c b y t e s [ i ] + s [ i ] ) )
system = l i s t (map( e n c o d e l i n e a r , system ) )
c n f = c n f + " \n " . j o i n ( system )
r e t u r n c n f + " \ nc " + hex ( key )
194
196
198
200
202
204
d e f usage ( ) :
print " " "
−e
−u
−r
−p
−k
−c
−i
−s
e n c r y p t p l a i n t e x t with key andoutput c i p h e r − t e x t
g e n e r a t e system f o r random key
<rounds> number o f rounds ( d e f a u l t : 32)
<p t e x t >
s e t p l a i n − t e x t ( d e f a u l t : random )
<key>
s e t key ( d e f a u l t : random )
<c t e x t >
s e t c i p h e r − t e x t ( d e f a u l t : random )
#b i t s
number o f guessed k e y b i t s ( d e f a u l t : 0)
<s i d e >
coma s e p e r a t e d l i s t o f rounds t o e x t r a c t s i d e channel
i n f o r m a t i o n from
−e
j u s t e n c r y p t p l a i n −t e x t u s i n g
206
key
208
"""
sys . e x i t (1)
210
opts , a r g s = g e t o p t . g e t o p t ( s y s . argv [ 1 : ] , " huek : p : c : s : r : i : " )
212
r , u , c , p , k , i , s , e = 56 ,0 , − 1 , − 1 , − 1 ,0 ,[ − 1] ,0
214
f o r op i n o p t s :
34
216
218
220
222
224
226
228
230
232
i f op [ 0 ] == "−p " :
p = i n t ( op [ 1 ] , 1 6 )
e l i f op [ 0 ] == "−c " :
c = i n t ( op [ 1 ] , 1 6 )
e l i f op [ 0 ] == "−k " :
k = i n t ( op [ 1 ] , 1 6 )
e l i f op [ 0 ] == "− s " :
s = l i s t (map( lambda x : i n t ( x ) , op [ 1 ] . s p l i t ( " , " ) ) )
e l i f op [ 0 ] == "− r " :
r = i n t ( op [ 1 ] )
e l i f op [ 0 ] == "− i " :
i = i n t ( op [ 1 ] )
e l i f op [ 0 ] == "−e " :
e = 1
e l i f op [ 0 ] == "−u " :
u = 1
e l i f op [ 0 ] == "−h " :
usage ( )
234
236
238
240
i f p == −1:
p = random . r a n d i n t (0,1<<64)
i f k == −1:
key = random . r a n d i n t (0,1<<64)
else :
key = k
242
244
246
248
250
i f c == −1:
c , rb , r a = e n c r y p t ( p , key , rounds=r , s i d e c h a n n l e=s )
else :
tmp = c
c , rb , r a = e n c r y p t ( p , key , rounds=r , s i d e c h a n n l e=s )
c = tmp
i f u == 1 :
key = random . r a n d i n t (0,1<<64)
252
254
256
i f e == 0 :
system = g e t P o l y n o m i a l S y s t e m ( p , c , r , key , i , r a s=ra , r b s=rb )
p r i n t system
e l i f e == 1 :
p r i n t " enc(%x,%x ) = %x " % ( p , key , c )
Listing A.2: CSA equation generator
35