cascada.primitives.blockcipher module
Represent encryption functions and block ciphers.
Represent encryption functions of block ciphers. |
|
Represent block ciphers. |
|
Return a random |
- class cascada.primitives.blockcipher.Encryption(*args, **options)[source]
Bases:
object
Represent encryption functions of block ciphers.
An encryption function is a bit-vector function (see
BvFunction
) that takes the plaintext as input and returns the ciphertext for some fixed master key.An encryption function together with a key-schedule function forms a
Cipher
.The tuple of round keys (the outputs of the associated key-schedule function) are accessible through the class attribute
round_keys
.The encryption function is not responsible for the creation of the round keys, and the
eval
method ofEncryption
can assume thatround_keys
is a tuple of bit-vectors with the bit-sizes given byCipher.key_schedule.output_widths
.Note
The
eval
method ofEncryption
is meant to be called from theeval
method ofCipher
, and in the lattereval
the round keys for the given master key are automatically created and temporarily stored inround_keys
(until the end ofeval
).To use the encryption function as a regular
BvFunction
,round_keys
must be filled with a tuple ofConstant
orVariable
objects. This can be easily done byCipher.set_round_keys
Ifround_keys
containsVariable
objects, the round keys are represented in theSSA
of the encryption function as external variables.To define an encryption function for a new
Cipher
, you must create a new class with two parent/base classes:Encryption
and eitherBvFunction
orRoundBasedFunction
.Note
Encryption
must always be the first parent/base class so that theEncryption
methods can override theBvFunction
orRoundBasedFunction
methods.
- class cascada.primitives.blockcipher.Cipher(plaintext, masterkey, **options)[source]
Bases:
object
Represent block ciphers.
A block cipher is a pair of bit-vector functions (see
BvFunction
): the key schedule that computes the round keys from a master key, and theEncryption
function.Similar to
BvFunction
,Cipher
is evaluated with the operator()
that is,Cipher(plaintext, masterkey)
returns the ciphertext. The argumentsplaintext
andmasterkey
are both lists ofConstant
objects or integers (integers are automatically converted toConstant
objects using the bit-sizes given byCipher.key_schedule.input_widths
andCipher.encryption.input_widths
.An iterated block cipher is a
Cipher
where both the key-schedule and the encryption functions areRoundBasedFunction
objects.This class is not meant to be instantiated but to provide a base class for block ciphers. To define a block cipher, subclass
Cipher
and set the class attributeskey_schedule
andencryption
. For an iterated block cipher, the methodset_num_rounds
must be implemented.Note
The method
set_num_rounds
must set the number of rounds ofencryption
to the given number of rounds, but the number of rounds ofkey_schedule
might differ.For an iterated block cipher
C
where thekey_schedule
and theencryption
share the number of rounds (i.e.,C.key_schedule.num_rounds == C.encryption.num_rounds
), the usual implement ofset_num_rounds
is@classmethod def set_num_rounds(cls, encryption_new_num_rounds): cls.key_schedule.set_num_rounds(encryption_new_num_rounds) cls.encryption.set_num_rounds(encryption_new_num_rounds)
However, an iterated block cipher can also contain a
key_schedule
with a different number of rounds than theencryption
. An example ofset_num_rounds
for an iterated cipher where thekey_schedule
has one less round that theencryption
is@classmethod def set_num_rounds(cls, encryption_new_num_rounds): cls.key_schedule.set_num_rounds(encryption_new_num_rounds - 1) cls.encryption.set_num_rounds(encryption_new_num_rounds)
>>> from cascada.primitives.blockcipher import Cipher >>> from cascada.primitives import speck >>> Speck32 = speck.get_Speck_instance(speck.SpeckInstance.speck_32_64) >>> issubclass(Speck32, Cipher) True >>> Speck32(plaintext=[0, 0], masterkey=[0, 0, 0, 0]) # Automatic Constant Conversion (0x2bb9, 0xc642) >>> Speck32.get_name() 'SpeckCipher_22R' >>> Speck32.vrepr() 'SpeckCipher.set_num_rounds_and_return(22)' >>> Speck32.set_round_keys(masterkey=[0, 0, 0, 0]) >>> Speck32.encryption.round_keys (0x0000, 0x0000, 0x0001, 0x0007, 0x0018, 0x027c, 0x0189, 0x0fab, 0x7904, 0x8f0d, 0x911f, 0xa5da, 0x49d1, 0xba62, 0xeda2, 0xd3da, 0x6c70, 0x0da9, 0x86c6, 0xa604, 0xef7d, 0x093e) >>> Speck32.set_num_rounds(2) >>> Speck32(plaintext=[0, 0], masterkey=[0, 0]) # masterkey is now a 2-word list (0x0000, 0x0000) >>> Speck32.get_name() 'SpeckCipher_2R' >>> Speck32.vrepr() 'SpeckCipher.set_num_rounds_and_return(2)' >>> Speck32.set_round_keys(symbolic_prefix="k") >>> for v in Speck32.encryption.round_keys: print(v.vrepr()) Variable('k0', width=16) Variable('k1', width=16)
- key_schedule
the key-schedule function (a subclass of
BvFunction
)
- encryption
the encryption function (a subclass of
Encryption
andBvFunction
)
- class property num_rounds
The number of rounds of
encryption
if iterated, otherwiseNone
- classmethod get_name()[source]
Return the class name and the current number of rounds (if iterated).
- classmethod vrepr()[source]
Return an executable string representation.
This method returns a string so that
eval(cls.vrepr())
returns a newCipher
object with the same content.
- classmethod set_num_rounds(encryption_new_num_rounds)[source]
Call
RoundBasedFunction.set_num_rounds
ofkey_schedule
andencryption
(if iterated).
- classmethod set_num_rounds_and_return(new_num_rounds)[source]
Call
set_num_rounds
and returncls
(if iterated).
- classmethod set_round_keys(masterkey=None, symbolic_prefix=None)[source]
Set
cls.encryption.round_keys
.If
masterkey
is given, set the round keys as the output ofcls.key_schedule(*masterkey)
.If
symbolic_prefix
is given, set the round keys as a tuple ofVariable
objects with prefix namesymbolic_prefix
and with bit-sizes given bycls.key_schedule.output_widths
.- Parameters
masterkey – (optional) a list of
Constant
objects or integerssymbolic_prefix – (optional) a string
- cascada.primitives.blockcipher.get_random_cipher(width, key_num_inputs, key_num_assignments, enc_num_inputs, enc_num_outputs, enc_num_assignments, seed, external_variable_prefix, operation_set_index=0, num_rounds=None, extra_operations=None)[source]
Return a random
Cipher
with given shape.- Parameters
width – the common bitsize of the input and output variables of the function
key_num_inputs – the number of inputs of the key schedule
key_num_assignments – an estimation of the number of operations within the key schedule
enc_num_inputs – the number of inputs of the encryption
enc_num_assignments – an estimation of the number of operations within the encryption
enc_num_outputs – the number of outputs of the encryption
seed – the seed used when sampling
operation_set_index – four set of operations to choose indexed by 0, 1, 2 and 3
num_rounds – if not
None
, sample the key-schedule and the encryption functions as randomRoundBasedFunction
objects with the given number of roundsextra_operations – an optional
tuple
containingOperation
subclasses to add to the list of operations to choose
>>> from cascada.bitvector.core import Variable >>> from cascada.primitives.blockcipher import get_random_cipher >>> my_cipher = get_random_cipher(4, 1, 1, 2, 2, 4, seed=1, external_variable_prefix="rk") >>> my_cipher.key_schedule.to_ssa(["mk0"], "k") SSA(input_vars=[mk0], output_vars=[k0_out], assignments=[(k0, mk0 & 0x5), (k0_out, Id(k0))]) >>> my_cipher.encryption.round_keys = [Variable(f"rk{i}", 4) for i in range(1)] >>> my_cipher.encryption.to_ssa(["p0", "p1"], "x") SSA(input_vars=[p0, p1], output_vars=[x2_out, x3_out], external_vars=[rk0], assignments=[(x0, p0 ^ rk0), (x1, x0 - p1), (x2, p0 + p1), (x3, -x1), (x2_out, Id(x2)), (x3_out, Id(x3))])
See also
get_random_bvfunction
.