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:
objectRepresent 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
evalmethod ofEncryptioncan assume thatround_keysis a tuple of bit-vectors with the bit-sizes given byCipher.key_schedule.output_widths.Note
The
evalmethod ofEncryptionis meant to be called from theevalmethod ofCipher, and in the latterevalthe 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_keysmust be filled with a tuple ofConstantorVariableobjects. This can be easily done byCipher.set_round_keysIfround_keyscontainsVariableobjects, the round keys are represented in theSSAof 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:Encryptionand eitherBvFunctionorRoundBasedFunction.Note
Encryptionmust always be the first parent/base class so that theEncryptionmethods can override theBvFunctionorRoundBasedFunctionmethods.
- class cascada.primitives.blockcipher.Cipher(plaintext, masterkey, **options)[source]
Bases:
objectRepresent 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 theEncryptionfunction.Similar to
BvFunction,Cipheris evaluated with the operator()that is,Cipher(plaintext, masterkey)returns the ciphertext. The argumentsplaintextandmasterkeyare both lists ofConstantobjects or integers (integers are automatically converted toConstantobjects using the bit-sizes given byCipher.key_schedule.input_widthsandCipher.encryption.input_widths.An iterated block cipher is a
Cipherwhere both the key-schedule and the encryption functions areRoundBasedFunctionobjects.This class is not meant to be instantiated but to provide a base class for block ciphers. To define a block cipher, subclass
Cipherand set the class attributeskey_scheduleandencryption. For an iterated block cipher, the methodset_num_roundsmust be implemented.Note
The method
set_num_roundsmust set the number of rounds ofencryptionto the given number of rounds, but the number of rounds ofkey_schedulemight differ.For an iterated block cipher
Cwhere thekey_scheduleand theencryptionshare the number of rounds (i.e.,C.key_schedule.num_rounds == C.encryption.num_rounds), the usual implement ofset_num_roundsis@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_schedulewith a different number of rounds than theencryption. An example ofset_num_roundsfor an iterated cipher where thekey_schedulehas one less round that theencryptionis@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
EncryptionandBvFunction)
- class property num_rounds
The number of rounds of
encryptionif 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 newCipherobject with the same content.
- classmethod set_num_rounds(encryption_new_num_rounds)[source]
Call
RoundBasedFunction.set_num_roundsofkey_scheduleandencryption(if iterated).
- classmethod set_num_rounds_and_return(new_num_rounds)[source]
Call
set_num_roundsand returncls(if iterated).
- classmethod set_round_keys(masterkey=None, symbolic_prefix=None)[source]
Set
cls.encryption.round_keys.If
masterkeyis given, set the round keys as the output ofcls.key_schedule(*masterkey).If
symbolic_prefixis given, set the round keys as a tuple ofVariableobjects with prefix namesymbolic_prefixand with bit-sizes given bycls.key_schedule.output_widths.- Parameters
masterkey – (optional) a list of
Constantobjects 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
Cipherwith 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 randomRoundBasedFunctionobjects with the given number of roundsextra_operations – an optional
tuplecontainingOperationsubclasses 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.