DES

The Data Encryption Standard.

This file implements the Data Encryption Standard and the corresponding key schedule as described in [U.S1999].

This implementation is meant for experimental and educational usage only, do not use it in production code!

EXAMPLES:

Encrypt a message:

sage: from sage.crypto.block_cipher.des import DES
sage: des = DES()
sage: P = 0x01A1D6D039776742
sage: K = 0x7CA110454A1A6E57
sage: C = des.encrypt(plaintext=P, key=K); C.hex()
'690f5b0d9a26939b'
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES
>>> des = DES()
>>> P = Integer(0x01A1D6D039776742)
>>> K = Integer(0x7CA110454A1A6E57)
>>> C = des.encrypt(plaintext=P, key=K); C.hex()
'690f5b0d9a26939b'
from sage.crypto.block_cipher.des import DES
des = DES()
P = 0x01A1D6D039776742
K = 0x7CA110454A1A6E57
C = des.encrypt(plaintext=P, key=K); C.hex()

And decrypt it again:

sage: des.decrypt(ciphertext=C, key=K).hex()
'1a1d6d039776742'
>>> from sage.all import *
>>> des.decrypt(ciphertext=C, key=K).hex()
'1a1d6d039776742'
des.decrypt(ciphertext=C, key=K).hex()

Have a look at the used round keys:

sage: from sage.crypto.block_cipher.des import DES_KS
sage: ks = DES_KS()
sage: [k.hex() for k in ks(0x1F08260D1AC2465E)]
['103049bfb90e',
 '808d40f07bf',
  ...
 '231000f2dd97']
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES_KS
>>> ks = DES_KS()
>>> [k.hex() for k in ks(Integer(0x1F08260D1AC2465E))]
['103049bfb90e',
 '808d40f07bf',
  ...
 '231000f2dd97']
from sage.crypto.block_cipher.des import DES_KS
ks = DES_KS()
[k.hex() for k in ks(0x1F08260D1AC2465E)]

Validate the Sample Round Outputs for DES (cf. [KeSm1998] p. 124):

sage: from sage.crypto.block_cipher.des import DES
sage: P = 0
sage: K = 0x10316E028C8F3B4A
sage: for r in range(1, 17):
....:     DES(rounds=r, doFinalRound=False).encrypt(P, K).hex()
'47092b5b'
'47092b5b53f372af'
'53f372af9f1d158b'
...
'3f6c3efd5a1e5228'
sage: DES().encrypt(P, K).hex()
'82dcbafbdeab6602'
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES
>>> P = Integer(0)
>>> K = Integer(0x10316E028C8F3B4A)
>>> for r in range(Integer(1), Integer(17)):
...     DES(rounds=r, doFinalRound=False).encrypt(P, K).hex()
'47092b5b'
'47092b5b53f372af'
'53f372af9f1d158b'
...
'3f6c3efd5a1e5228'
>>> DES().encrypt(P, K).hex()
'82dcbafbdeab6602'
from sage.crypto.block_cipher.des import DES
P = 0
K = 0x10316E028C8F3B4A
for r in range(1, 17):
    DES(rounds=r, doFinalRound=False).encrypt(P, K).hex()
DES().encrypt(P, K).hex()

Change cipher internals:

sage: from sage.crypto.sbox import SBox
sage: cipher = DES(rounds=1, doFinalRound=False)
sage: cipher.sboxes = [[SBox(range(16))]*4]*8
sage: cipher.keySchedule = lambda x: [0]  # return the 0 key as round key
sage: cipher.encrypt(plaintext=0x1234, key=0x0).hex()
'80004000d08100'
>>> from sage.all import *
>>> from sage.crypto.sbox import SBox
>>> cipher = DES(rounds=Integer(1), doFinalRound=False)
>>> cipher.sboxes = [[SBox(range(Integer(16)))]*Integer(4)]*Integer(8)
>>> cipher.keySchedule = lambda x: [Integer(0)]  # return the 0 key as round key
>>> cipher.encrypt(plaintext=Integer(0x1234), key=Integer(0x0)).hex()
'80004000d08100'
from sage.crypto.sbox import SBox
cipher = DES(rounds=1, doFinalRound=False)
cipher.sboxes = [[SBox(range(16))]*4]*8
cipher.keySchedule = lambda x: [0]  # return the 0 key as round key
cipher.encrypt(plaintext=0x1234, key=0x0).hex()

AUTHORS:

  • Lukas Stennes (2019-03-29): initial version

class sage.crypto.block_cipher.des.DES(rounds=None, keySchedule='DES_KS', keySize=64, doFinalRound=True)[source]

Bases: SageObject

This class implements DES described in [U.S1999].

EXAMPLES:

You can invoke DES encryption/decryption either by calling DES with an appropriate flag:

sage: from sage.crypto.block_cipher.des import DES
sage: des = DES()
sage: P = 0x8000000000000000
sage: K = 0x0
sage: C = des(P, K, 'encrypt'); C.hex()
'95f8a5e5dd31d900'
sage: des(C, K, 'decrypt').hex()
'8000000000000000'
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES
>>> des = DES()
>>> P = Integer(0x8000000000000000)
>>> K = Integer(0x0)
>>> C = des(P, K, 'encrypt'); C.hex()
'95f8a5e5dd31d900'
>>> des(C, K, 'decrypt').hex()
'8000000000000000'
from sage.crypto.block_cipher.des import DES
des = DES()
P = 0x8000000000000000
K = 0x0
C = des(P, K, 'encrypt'); C.hex()
des(C, K, 'decrypt').hex()

Or by calling encryption/decryption methods directly:

sage: C = des.encrypt(P, K)
sage: P == des.decrypt(C, K)
True
>>> from sage.all import *
>>> C = des.encrypt(P, K)
>>> P == des.decrypt(C, K)
True
C = des.encrypt(P, K)
P == des.decrypt(C, K)

The number of rounds can be reduced easily:

sage: des = DES(rounds=15)
sage: des(des(P, K, 'encrypt'), K, 'decrypt') == P
True
>>> from sage.all import *
>>> des = DES(rounds=Integer(15))
>>> des(des(P, K, 'encrypt'), K, 'decrypt') == P
True
des = DES(rounds=15)
des(des(P, K, 'encrypt'), K, 'decrypt') == P

You can use hex (i.e. integers) or a list-like bit representation for the inputs. If the input is an integer the output will be too. If it is list-like the output will be a bit vector:

sage: des = DES()
sage: P = vector(GF(2), 64, [1] + [0]*63)
sage: K = vector(GF(2), 64, [0,0,0,0,0,0,0,1]*8)
sage: des.encrypt(P, K)
(1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0,
 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0,
 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
sage: P = 0x8000000000000000
sage: K = 0x0101010101010101
sage: C = des.encrypt(P, K); C; C.hex()
10806569712552630528
'95f8a5e5dd31d900'
>>> from sage.all import *
>>> des = DES()
>>> P = vector(GF(Integer(2)), Integer(64), [Integer(1)] + [Integer(0)]*Integer(63))
>>> K = vector(GF(Integer(2)), Integer(64), [Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),Integer(0),Integer(1)]*Integer(8))
>>> des.encrypt(P, K)
(1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0,
 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0,
 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
>>> P = Integer(0x8000000000000000)
>>> K = Integer(0x0101010101010101)
>>> C = des.encrypt(P, K); C; C.hex()
10806569712552630528
'95f8a5e5dd31d900'
des = DES()
P = vector(GF(2), 64, [1] + [0]*63)
K = vector(GF(2), 64, [0,0,0,0,0,0,0,1]*8)
des.encrypt(P, K)
P = 0x8000000000000000
K = 0x0101010101010101
C = des.encrypt(P, K); C; C.hex()
__init__(rounds=None, keySchedule='DES_KS', keySize=64, doFinalRound=True)[source]

Construct an instance of DES.

INPUT:

  • rounds – integer (default: None); the number of rounds. If None the number of rounds of the key schedule is used.

  • keySchedule – (default: 'DES_KS') the key schedule that will be used for encryption and decryption. If 'DES_KS' the default DES key schedule is used.

  • keySize – (default: 64) the key length in bits. Must be 56 of 64. In the latter case the key contains 8 parity bits.

  • doFinalRound – boolean (default: True); if False a swap takes places but the inverse initial permutation is omitted (i.e. you can get the state after rounds). This only effects encryption.

EXAMPLES:

sage: from sage.crypto.block_cipher.des import DES
sage: DES() # indirect doctest
DES block cipher with 16 rounds and the following key schedule:
Original DES key schedule with 16 rounds
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES
>>> DES() # indirect doctest
DES block cipher with 16 rounds and the following key schedule:
Original DES key schedule with 16 rounds
from sage.crypto.block_cipher.des import DES
DES() # indirect doctest

Reducing the number of rounds is simple. But increasing it is only possible if the key schedule can produce enough round keys:

sage: DES(rounds=11) # indirect doctest
DES block cipher with 11 rounds and the following key schedule:
Original DES key schedule with 16 rounds
sage: DES(rounds=42) # indirect doctest
Traceback (most recent call last):
...
ValueError: number of rounds must be less or equal to the number
of rounds of the key schedule
>>> from sage.all import *
>>> DES(rounds=Integer(11)) # indirect doctest
DES block cipher with 11 rounds and the following key schedule:
Original DES key schedule with 16 rounds
>>> DES(rounds=Integer(42)) # indirect doctest
Traceback (most recent call last):
...
ValueError: number of rounds must be less or equal to the number
of rounds of the key schedule
DES(rounds=11) # indirect doctest
DES(rounds=42) # indirect doctest

You can use arbitrary key schedules. Since it is the only one implemented here the original key schedule is used for demonstration:

sage: from sage.crypto.block_cipher.des import DES_KS
sage: DES(keySchedule=DES_KS(11)) # indirect doctest
DES block cipher with 11 rounds and the following key schedule:
Original DES key schedule with 11 rounds
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES_KS
>>> DES(keySchedule=DES_KS(Integer(11))) # indirect doctest
DES block cipher with 11 rounds and the following key schedule:
Original DES key schedule with 11 rounds
from sage.crypto.block_cipher.des import DES_KS
DES(keySchedule=DES_KS(11)) # indirect doctest
__call__(block, key, algorithm='encrypt')[source]

Apply DES encryption or decryption on block using key. The flag algorithm controls what action is to be performed on block.

INPUT:

  • block – integer or bit list-like; the plaintext or ciphertext

  • key – integer or bit list-like; the key

  • algorithm – string (default: 'encrypt'); a flag to signify whether encryption or decryption is to be applied to block. The encryption flag is 'encrypt' and the decryption flag is 'decrypt'

OUTPUT:

  • The plaintext or ciphertext corresponding to block, obtained using key. If block is an integer the output will be too. If block is list-like the output will be a bit vector.

EXAMPLES:

sage: from sage.crypto.block_cipher.des import DES
sage: des = DES()
sage: P = 0x480D39006EE762F2
sage: K = 0x025816164629B007
sage: des(P, K, 'encrypt').hex()
'a1f9915541020b56'
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES
>>> des = DES()
>>> P = Integer(0x480D39006EE762F2)
>>> K = Integer(0x025816164629B007)
>>> des(P, K, 'encrypt').hex()
'a1f9915541020b56'
from sage.crypto.block_cipher.des import DES
des = DES()
P = 0x480D39006EE762F2
K = 0x025816164629B007
des(P, K, 'encrypt').hex()
decrypt(ciphertext, key)[source]

Return the plaintext corresponding to ciphertext, using DES decryption with key.

INPUT:

  • ciphertext – integer or bit list-like; the ciphertext that will be decrypted

  • key – integer or bit list-like; the key

OUTPUT:

  • The plaintext corresponding to ciphertext, obtained using key. If ciphertext is an integer the output will be too. If ciphertext is list-like the output will be a bit vector.

EXAMPLES:

Decrypt a message:

sage: from sage.crypto.block_cipher.des import DES
sage: des = DES()
sage: K64 = 0x7CA110454A1A6E57
sage: C = 0x690F5B0D9A26939B
sage: P = des.decrypt(C, K64).hex(); P
'1a1d6d039776742'
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES
>>> des = DES()
>>> K64 = Integer(0x7CA110454A1A6E57)
>>> C = Integer(0x690F5B0D9A26939B)
>>> P = des.decrypt(C, K64).hex(); P
'1a1d6d039776742'
from sage.crypto.block_cipher.des import DES
des = DES()
K64 = 0x7CA110454A1A6E57
C = 0x690F5B0D9A26939B
P = des.decrypt(C, K64).hex(); P

You can also use 56 bit keys i.e. you can leave out the parity bits:

sage: K56 = 0x7D404224A35BAB
sage: des = DES(keySize=56)
sage: des.decrypt(C, K56).hex() == P
True
>>> from sage.all import *
>>> K56 = Integer(0x7D404224A35BAB)
>>> des = DES(keySize=Integer(56))
>>> des.decrypt(C, K56).hex() == P
True
K56 = 0x7D404224A35BAB
des = DES(keySize=56)
des.decrypt(C, K56).hex() == P
encrypt(plaintext, key)[source]

Return the ciphertext corresponding to plaintext, using DES encryption with key.

INPUT:

  • plaintext – integer or bit list-like; the plaintext that will be encrypted

  • key – integer or bit list-like; the key

OUTPUT:

  • The ciphertext corresponding to plaintext, obtained using key. If plaintext is an integer the output will be too. If plaintext is list-like the output will be a bit vector.

EXAMPLES:

Encrypt a message:

sage: from sage.crypto.block_cipher.des import DES
sage: des = DES()
sage: K64 = 0x133457799BBCDFF1
sage: P = 0x0123456789ABCDEF
sage: C = des.encrypt(P, K64); C.hex()
'85e813540f0ab405'
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES
>>> des = DES()
>>> K64 = Integer(0x133457799BBCDFF1)
>>> P = Integer(0x0123456789ABCDEF)
>>> C = des.encrypt(P, K64); C.hex()
'85e813540f0ab405'
from sage.crypto.block_cipher.des import DES
des = DES()
K64 = 0x133457799BBCDFF1
P = 0x0123456789ABCDEF
C = des.encrypt(P, K64); C.hex()

You can also use 56 bit keys i.e. you can leave out the parity bits:

sage: K56 = 0x12695BC9B7B7F8
sage: des = DES(keySize=56)
sage: des.encrypt(P, K56) == C
True
>>> from sage.all import *
>>> K56 = Integer(0x12695BC9B7B7F8)
>>> des = DES(keySize=Integer(56))
>>> des.encrypt(P, K56) == C
True
K56 = 0x12695BC9B7B7F8
des = DES(keySize=56)
des.encrypt(P, K56) == C
round(state, round_key)[source]

Apply one round of DES to state and return the result.

EXAMPLES:

sage: from sage.crypto.block_cipher.des import DES
sage: from sage.crypto.block_cipher.des import convert_to_vector
sage: des = DES()
sage: k1 = convert_to_vector(0xFFFFFFFFFFFF, 48)
sage: state = convert_to_vector(0xFFFFFFFF11111111, 64)
sage: ZZ(list(des.round(state, k1))[::-1], 2).hex()
'11111111b29684b8'
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES
>>> from sage.crypto.block_cipher.des import convert_to_vector
>>> des = DES()
>>> k1 = convert_to_vector(Integer(0xFFFFFFFFFFFF), Integer(48))
>>> state = convert_to_vector(Integer(0xFFFFFFFF11111111), Integer(64))
>>> ZZ(list(des.round(state, k1))[::-Integer(1)], Integer(2)).hex()
'11111111b29684b8'
from sage.crypto.block_cipher.des import DES
from sage.crypto.block_cipher.des import convert_to_vector
des = DES()
k1 = convert_to_vector(0xFFFFFFFFFFFF, 48)
state = convert_to_vector(0xFFFFFFFF11111111, 64)
ZZ(list(des.round(state, k1))[::-1], 2).hex()
sbox_layer(block)[source]

Apply the Sboxes to block.

EXAMPLES:

sage: from sage.crypto.block_cipher.des import DES
sage: des = DES()
sage: B = vector(GF(2), 48, [0,1,1,0,0,0,0,1,0,0,0,1,0,1,1,1,1,0,1,
....:                        1,1,0,1,0,1,0,0,0,0,1,1,0,0,1,1,0,0,1,
....:                        0,1,0,0,1,0,0,1,1,1])
sage: des.sbox_layer(B)
(0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1,
 0, 1, 1, 0, 0, 1, 0, 1, 1, 1)
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES
>>> des = DES()
>>> B = vector(GF(Integer(2)), Integer(48), [Integer(0),Integer(1),Integer(1),Integer(0),Integer(0),Integer(0),Integer(0),Integer(1),Integer(0),Integer(0),Integer(0),Integer(1),Integer(0),Integer(1),Integer(1),Integer(1),Integer(1),Integer(0),Integer(1),
...                        Integer(1),Integer(1),Integer(0),Integer(1),Integer(0),Integer(1),Integer(0),Integer(0),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),Integer(0),Integer(1),
...                        Integer(0),Integer(1),Integer(0),Integer(0),Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(1)])
>>> des.sbox_layer(B)
(0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1,
 0, 1, 1, 0, 0, 1, 0, 1, 1, 1)
from sage.crypto.block_cipher.des import DES
des = DES()
B = vector(GF(2), 48, [0,1,1,0,0,0,0,1,0,0,0,1,0,1,1,1,1,0,1,
                       1,1,0,1,0,1,0,0,0,0,1,1,0,0,1,1,0,0,1,
                       0,1,0,0,1,0,0,1,1,1])
des.sbox_layer(B)
class sage.crypto.block_cipher.des.DES_KS(rounds=16, masterKey=None)[source]

Bases: SageObject

This class implements the DES key schedules described in [U.S1999].

EXAMPLES:

Initialise the key schedule with a \(masterKey\) to use it as an iterable:

sage: from sage.crypto.block_cipher.des import DES_KS
sage: ks = DES_KS(masterKey=0)
sage: ks[0]
0
sage: ks[15]
0
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES_KS
>>> ks = DES_KS(masterKey=Integer(0))
>>> ks[Integer(0)]
0
>>> ks[Integer(15)]
0
from sage.crypto.block_cipher.des import DES_KS
ks = DES_KS(masterKey=0)
ks[0]
ks[15]

Or omit the \(masterKey\) and pass a key when calling the key schedule:

sage: ks = DES_KS()
sage: K = ks(0x584023641ABA6176)
sage: K[0].hex()
'd0a2ed2fa124'
sage: K[15].hex()
'43b42af81183'
>>> from sage.all import *
>>> ks = DES_KS()
>>> K = ks(Integer(0x584023641ABA6176))
>>> K[Integer(0)].hex()
'd0a2ed2fa124'
>>> K[Integer(15)].hex()
'43b42af81183'
ks = DES_KS()
K = ks(0x584023641ABA6176)
K[0].hex()
K[15].hex()

See also

DES

__init__(rounds=16, masterKey=None)[source]

Construct an instance of DES_KS.

INPUT:

  • rounds – integer (default: \(16\)); the number of rounds self can create keys for

  • masterKey – integer or bit list-like (default: None); the 64-bit key that will be used

EXAMPLES:

sage: from sage.crypto.block_cipher.des import DES_KS
sage: DES_KS()
Original DES key schedule with 16 rounds
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES_KS
>>> DES_KS()
Original DES key schedule with 16 rounds
from sage.crypto.block_cipher.des import DES_KS
DES_KS()

Note

If you want to use a DES_KS object as an iterable you have to pass a masterKey value on initialisation. Otherwise you can omit masterKey and pass a key when you call the object.

__call__(key)[source]

Return all round keys in a list.

INPUT:

  • key – integer or bit list-like; the 64-bit key

OUTPUT:

  • A list containing the round keys. If key is an integer the elements of the output list will be too. If key is list-like the element of the output list will be bit vectors.

EXAMPLES:

This implementation is using bit vectors for all internal representations. So you can invoke the key schedule with a bit vector:

sage: from sage.crypto.block_cipher.des import DES_KS
sage: K = vector(GF(2),[0,0,0,1,0,0,1,1,0,0,1,1,0,1,0,0,0,1,0,1,0,
....:                   1,1,1,0,1,1,1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,
....:                   1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,0,0,0,1])
sage: ks = DES_KS(16, K)
sage: [k for k in ks]
[(0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1,
  0, 0, 1, 0),
 (0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0,
  0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0,
  0, 1, 0, 1),
 ...
 (1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0,
  1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1,
  0, 1, 0, 1)]
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import DES_KS
>>> K = vector(GF(Integer(2)),[Integer(0),Integer(0),Integer(0),Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),Integer(1),Integer(0),Integer(0),Integer(0),Integer(1),Integer(0),Integer(1),Integer(0),
...                   Integer(1),Integer(1),Integer(1),Integer(0),Integer(1),Integer(1),Integer(1),Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),Integer(1),Integer(1),Integer(1),Integer(0),
...                   Integer(1),Integer(1),Integer(1),Integer(1),Integer(0),Integer(0),Integer(1),Integer(1),Integer(0),Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),Integer(1),Integer(0),Integer(0),Integer(0),Integer(1)])
>>> ks = DES_KS(Integer(16), K)
>>> [k for k in ks]
[(0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1,
  0, 0, 1, 0),
 (0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0,
  0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0,
  0, 1, 0, 1),
 ...
 (1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0,
  1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1,
  0, 1, 0, 1)]
from sage.crypto.block_cipher.des import DES_KS
K = vector(GF(2),[0,0,0,1,0,0,1,1,0,0,1,1,0,1,0,0,0,1,0,1,0,
                  1,1,1,0,1,1,1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,
                  1,1,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,0,0,0,1])
ks = DES_KS(16, K)
[k for k in ks]

But of course you can invoke it with hex representation as well:

sage: K = 0x133457799bbcdff1
sage: ks = DES_KS(16, K)
sage: [k.hex() for k in ks]
['1b02effc7072',
 '79aed9dbc9e5',
 ...
 'cb3d8b0e17f5']
>>> from sage.all import *
>>> K = Integer(0x133457799bbcdff1)
>>> ks = DES_KS(Integer(16), K)
>>> [k.hex() for k in ks]
['1b02effc7072',
 '79aed9dbc9e5',
 ...
 'cb3d8b0e17f5']
K = 0x133457799bbcdff1
ks = DES_KS(16, K)
[k.hex() for k in ks]

Note

If you want to use a DES_KS object as an iterable you have to pass a masterKey value on initialisation. Otherwise you can omit masterKey and pass a key when you call the object.

sage.crypto.block_cipher.des.convert_to_vector(I, L)[source]

Convert I to a bit vector of length L.

INPUT:

  • I – integer or bit list-like

  • L – integer; the desired bit length of the ouput

OUTPUT: the L-bit vector representation of I

EXAMPLES:

sage: from sage.crypto.block_cipher.des import convert_to_vector
sage: convert_to_vector(0x1F, 8)
(0, 0, 0, 1, 1, 1, 1, 1)
sage: v = vector(GF(2), 4, [1,0,1,0])
sage: convert_to_vector(v, 4)
(1, 0, 1, 0)
>>> from sage.all import *
>>> from sage.crypto.block_cipher.des import convert_to_vector
>>> convert_to_vector(Integer(0x1F), Integer(8))
(0, 0, 0, 1, 1, 1, 1, 1)
>>> v = vector(GF(Integer(2)), Integer(4), [Integer(1),Integer(0),Integer(1),Integer(0)])
>>> convert_to_vector(v, Integer(4))
(1, 0, 1, 0)
from sage.crypto.block_cipher.des import convert_to_vector
convert_to_vector(0x1F, 8)
v = vector(GF(2), 4, [1,0,1,0])
convert_to_vector(v, 4)