Simplified DES

A simplified variant of the Data Encryption Standard (DES). Note that Simplified DES or S-DES is for educational purposes only. It is a small-scale version of the DES designed to help beginners understand the basic structure of DES.

AUTHORS:

  • Minh Van Nguyen (2009-06): initial version

class sage.crypto.block_cipher.sdes.SimplifiedDES[source]

Bases: SageObject

This class implements the Simplified Data Encryption Standard (S-DES) described in [Sch1996]. Schaefer’s S-DES is for educational purposes only and is not secure for practical purposes. S-DES is a version of the DES with all parameters significantly reduced, but at the same time preserving the structure of DES. The goal of S-DES is to allow a beginner to understand the structure of DES, thus laying a foundation for a thorough study of DES. Its goal is as a teaching tool in the same spirit as Phan’s Mini-AES [Pha2002].

EXAMPLES:

Encrypt a random block of 8-bit plaintext using a random key, decrypt the ciphertext, and compare the result with the original plaintext:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES(); sdes
Simplified DES block cipher with 10-bit keys
sage: bin = BinaryStrings()
sage: P = [bin(str(randint(0, 1))) for i in range(8)]
sage: K = sdes.random_key()
sage: C = sdes.encrypt(P, K)
sage: plaintxt = sdes.decrypt(C, K)
sage: plaintxt == P
True
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES(); sdes
Simplified DES block cipher with 10-bit keys
>>> bin = BinaryStrings()
>>> P = [bin(str(randint(Integer(0), Integer(1)))) for i in range(Integer(8))]
>>> K = sdes.random_key()
>>> C = sdes.encrypt(P, K)
>>> plaintxt = sdes.decrypt(C, K)
>>> plaintxt == P
True

We can also encrypt binary strings that are larger than 8 bits in length. However, the number of bits in that binary string must be positive and a multiple of 8:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: bin = BinaryStrings()
sage: P = bin.encoding("Encrypt this using S-DES!")
sage: Mod(len(P), 8) == 0
True
sage: K = sdes.list_to_string(sdes.random_key())
sage: C = sdes(P, K, algorithm='encrypt')
sage: plaintxt = sdes(C, K, algorithm='decrypt')
sage: plaintxt == P
True
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> bin = BinaryStrings()
>>> P = bin.encoding("Encrypt this using S-DES!")
>>> Mod(len(P), Integer(8)) == Integer(0)
True
>>> K = sdes.list_to_string(sdes.random_key())
>>> C = sdes(P, K, algorithm='encrypt')
>>> plaintxt = sdes(C, K, algorithm='decrypt')
>>> plaintxt == P
True
block_length()[source]

Return the block length of Schaefer’s S-DES block cipher. A key in Schaefer’s S-DES is a block of 10 bits.

OUTPUT:

  • The block (or key) length in number of bits.

EXAMPLES:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: sdes.block_length()
10
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> sdes.block_length()
10
decrypt(C, K)[source]

Return an 8-bit plaintext corresponding to the ciphertext C, using S-DES decryption with key K. The decryption process of S-DES is as follows. Let P be the initial permutation function, P1 the corresponding inverse permutation, ΠF the permutation/substitution function, and σ the switch function. The ciphertext block C first goes through P, the output of which goes through ΠF using the second subkey. Then we apply the switch function to the output of the last function, and the result is then fed into ΠF using the first subkey. Finally, run the output through P1 to get the plaintext.

INPUT:

  • C – an 8-bit ciphertext; a block of 8 bits

  • K – a 10-bit key; a block of 10 bits

OUTPUT:

The 8-bit plaintext corresponding to C, obtained using the key K.

EXAMPLES:

Decrypt an 8-bit ciphertext block:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: C = [0, 1, 0, 1, 0, 1, 0, 1]
sage: K = [1, 0, 1, 0, 0, 0, 0, 0, 1, 0]
sage: sdes.decrypt(C, K)
[0, 0, 0, 1, 0, 1, 0, 1]
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> C = [Integer(0), Integer(1), Integer(0), Integer(1), Integer(0), Integer(1), Integer(0), Integer(1)]
>>> K = [Integer(1), Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(0)]
>>> sdes.decrypt(C, K)
[0, 0, 0, 1, 0, 1, 0, 1]

We can also work with strings of bits:

sage: C = "01010101"
sage: K = "1010000010"
sage: sdes.decrypt(sdes.string_to_list(C), sdes.string_to_list(K))
[0, 0, 0, 1, 0, 1, 0, 1]
>>> from sage.all import *
>>> C = "01010101"
>>> K = "1010000010"
>>> sdes.decrypt(sdes.string_to_list(C), sdes.string_to_list(K))
[0, 0, 0, 1, 0, 1, 0, 1]
encrypt(P, K)[source]

Return an 8-bit ciphertext corresponding to the plaintext P, using S-DES encryption with key K. The encryption process of S-DES is as follows. Let P be the initial permutation function, P1 the corresponding inverse permutation, ΠF the permutation/substitution function, and σ the switch function. The plaintext block P first goes through P, the output of which goes through ΠF using the first subkey. Then we apply the switch function to the output of the last function, and the result is then fed into ΠF using the second subkey. Finally, run the output through P1 to get the ciphertext.

INPUT:

  • P – an 8-bit plaintext; a block of 8 bits

  • K – a 10-bit key; a block of 10 bits

OUTPUT:

The 8-bit ciphertext corresponding to P, obtained using the key K.

EXAMPLES:

Encrypt an 8-bit plaintext block:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: P = [0, 1, 0, 1, 0, 1, 0, 1]
sage: K = [1, 0, 1, 0, 0, 0, 0, 0, 1, 0]
sage: sdes.encrypt(P, K)
[1, 1, 0, 0, 0, 0, 0, 1]
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> P = [Integer(0), Integer(1), Integer(0), Integer(1), Integer(0), Integer(1), Integer(0), Integer(1)]
>>> K = [Integer(1), Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(0)]
>>> sdes.encrypt(P, K)
[1, 1, 0, 0, 0, 0, 0, 1]

We can also work with strings of bits:

sage: P = "01010101"
sage: K = "1010000010"
sage: sdes.encrypt(sdes.string_to_list(P), sdes.string_to_list(K))
[1, 1, 0, 0, 0, 0, 0, 1]
>>> from sage.all import *
>>> P = "01010101"
>>> K = "1010000010"
>>> sdes.encrypt(sdes.string_to_list(P), sdes.string_to_list(K))
[1, 1, 0, 0, 0, 0, 0, 1]
initial_permutation(B, inverse=False)[source]

Return the initial permutation of B. Denote the initial permutation function by P and let (b0,b1,b2,,b7) be a vector of 8 bits, where each bi{0,1}. Then

P(b0,b1,b2,b3,b4,b5,b6,b7)=(b1,b5,b2,b0,b3,b7,b4,b6)

The inverse permutation is P1:

P1(b0,b1,b2,b3,b4,b5,b6,b7)=(b3,b0,b2,b4,b6,b1,b7,b5)

INPUT:

  • B – list; a block of 8 bits

  • inverse – boolean (default: False); if True then use the inverse permutation P1. If False then use the initial permutation P.

OUTPUT:

The initial permutation of B if inverse=False, or the inverse permutation of B if inverse=True.

EXAMPLES:

The initial permutation of a list of 8 bits:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: B = [1, 0, 1, 1, 0, 1, 0, 0]
sage: P = sdes.initial_permutation(B); P
[0, 1, 1, 1, 1, 0, 0, 0]
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> B = [Integer(1), Integer(0), Integer(1), Integer(1), Integer(0), Integer(1), Integer(0), Integer(0)]
>>> P = sdes.initial_permutation(B); P
[0, 1, 1, 1, 1, 0, 0, 0]

Recovering the original list of 8 bits from the permutation:

sage: Pinv = sdes.initial_permutation(P, inverse=True)
sage: Pinv; B
[1, 0, 1, 1, 0, 1, 0, 0]
[1, 0, 1, 1, 0, 1, 0, 0]
>>> from sage.all import *
>>> Pinv = sdes.initial_permutation(P, inverse=True)
>>> Pinv; B
[1, 0, 1, 1, 0, 1, 0, 0]
[1, 0, 1, 1, 0, 1, 0, 0]

We can also work with a string of bits:

sage: S = "10110100"
sage: L = sdes.string_to_list(S)
sage: P = sdes.initial_permutation(L); P
[0, 1, 1, 1, 1, 0, 0, 0]
sage: sdes.initial_permutation(sdes.string_to_list("01111000"), inverse=True)
[1, 0, 1, 1, 0, 1, 0, 0]
>>> from sage.all import *
>>> S = "10110100"
>>> L = sdes.string_to_list(S)
>>> P = sdes.initial_permutation(L); P
[0, 1, 1, 1, 1, 0, 0, 0]
>>> sdes.initial_permutation(sdes.string_to_list("01111000"), inverse=True)
[1, 0, 1, 1, 0, 1, 0, 0]
left_shift(B, n=1)[source]

Return a circular left shift of B by n positions. Let B=(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) be a vector of 10 bits. Then the left shift operation Ln is performed on the first 5 bits and the last 5 bits of B separately. That is, if the number of shift positions is n=1, then L1 is defined as

L1(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9)=(b1,b2,b3,b4,b0,b6,b7,b8,b9,b5)

If the number of shift positions is n=2, then L2 is given by

L2(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9)=(b2,b3,b4,b0,b1,b7,b8,b9,b5,b6)

INPUT:

  • B – list of 10 bits

  • n – (default: 1) if n=1 then perform left shift by 1 position; if n=2 then perform left shift by 2 positions. The valid values for n are 1 and 2, since only up to 2 positions are defined for this circular left shift operation.

OUTPUT: the circular left shift of each half of B

EXAMPLES:

Circular left shift by 1 position of a 10-bit string:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: B = [1, 0, 0, 0, 0, 0, 1, 1, 0, 0]
sage: sdes.left_shift(B)
[0, 0, 0, 0, 1, 1, 1, 0, 0, 0]
sage: sdes.left_shift([1, 0, 1, 0, 0, 0, 0, 0, 1, 0])
[0, 1, 0, 0, 1, 0, 0, 1, 0, 0]
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> B = [Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(1), Integer(0), Integer(0)]
>>> sdes.left_shift(B)
[0, 0, 0, 0, 1, 1, 1, 0, 0, 0]
>>> sdes.left_shift([Integer(1), Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(0)])
[0, 1, 0, 0, 1, 0, 0, 1, 0, 0]

Circular left shift by 2 positions of a 10-bit string:

sage: B = [0, 0, 0, 0, 1, 1, 1, 0, 0, 0]
sage: sdes.left_shift(B, n=2)
[0, 0, 1, 0, 0, 0, 0, 0, 1, 1]
>>> from sage.all import *
>>> B = [Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0)]
>>> sdes.left_shift(B, n=Integer(2))
[0, 0, 1, 0, 0, 0, 0, 0, 1, 1]

Here we work with a string of bits:

sage: S = "1000001100"
sage: L = sdes.string_to_list(S)
sage: sdes.left_shift(L)
[0, 0, 0, 0, 1, 1, 1, 0, 0, 0]
sage: sdes.left_shift(sdes.string_to_list("1010000010"), n=2)
[1, 0, 0, 1, 0, 0, 1, 0, 0, 0]
>>> from sage.all import *
>>> S = "1000001100"
>>> L = sdes.string_to_list(S)
>>> sdes.left_shift(L)
[0, 0, 0, 0, 1, 1, 1, 0, 0, 0]
>>> sdes.left_shift(sdes.string_to_list("1010000010"), n=Integer(2))
[1, 0, 0, 1, 0, 0, 1, 0, 0, 0]
list_to_string(B)[source]

Return a binary string representation of the list B.

INPUT:

  • B – a non-empty list of bits

OUTPUT: the binary string representation of B

EXAMPLES:

A binary string representation of a list of bits:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: L = [0, 0, 0, 0, 1, 1, 0, 1, 0, 0]
sage: sdes.list_to_string(L)
0000110100
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> L = [Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(1), Integer(0), Integer(1), Integer(0), Integer(0)]
>>> sdes.list_to_string(L)
0000110100
permutation10(B)[source]

Return a permutation of a 10-bit string. This permutation is called P10 and is specified as follows. Let (b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) be a vector of 10 bits where each bi{0,1}. Then P10 is given by

P10(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9)=(b2,b4,b1,b6,b3,b9,b0,b8,b7,b5)

INPUT:

  • B – a block of 10-bit string

OUTPUT: a permutation of B

EXAMPLES:

Permute a 10-bit string:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: B = [1, 1, 0, 0, 1, 0, 0, 1, 0, 1]
sage: sdes.permutation10(B)
[0, 1, 1, 0, 0, 1, 1, 0, 1, 0]
sage: sdes.permutation10([0, 1, 1, 0, 1, 0, 0, 1, 0, 1])
[1, 1, 1, 0, 0, 1, 0, 0, 1, 0]
sage: sdes.permutation10([1, 0, 1, 0, 0, 0, 0, 0, 1, 0])
[1, 0, 0, 0, 0, 0, 1, 1, 0, 0]
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> B = [Integer(1), Integer(1), Integer(0), Integer(0), Integer(1), Integer(0), Integer(0), Integer(1), Integer(0), Integer(1)]
>>> sdes.permutation10(B)
[0, 1, 1, 0, 0, 1, 1, 0, 1, 0]
>>> sdes.permutation10([Integer(0), Integer(1), Integer(1), Integer(0), Integer(1), Integer(0), Integer(0), Integer(1), Integer(0), Integer(1)])
[1, 1, 1, 0, 0, 1, 0, 0, 1, 0]
>>> sdes.permutation10([Integer(1), Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(0)])
[1, 0, 0, 0, 0, 0, 1, 1, 0, 0]

Here we work with a string of bits:

sage: S = "1100100101"
sage: L = sdes.string_to_list(S)
sage: sdes.permutation10(L)
[0, 1, 1, 0, 0, 1, 1, 0, 1, 0]
sage: sdes.permutation10(sdes.string_to_list("0110100101"))
[1, 1, 1, 0, 0, 1, 0, 0, 1, 0]
>>> from sage.all import *
>>> S = "1100100101"
>>> L = sdes.string_to_list(S)
>>> sdes.permutation10(L)
[0, 1, 1, 0, 0, 1, 1, 0, 1, 0]
>>> sdes.permutation10(sdes.string_to_list("0110100101"))
[1, 1, 1, 0, 0, 1, 0, 0, 1, 0]
permutation4(B)[source]

Return a permutation of a 4-bit string. This permutation is called P4 and is specified as follows. Let (b0,b1,b2,b3) be a vector of 4 bits where each bi{0,1}. Then P4 is defined by

P4(b0,b1,b2,b3)=(b1,b3,b2,b0)

INPUT:

  • B – a block of 4-bit string

OUTPUT: a permutation of B

EXAMPLES:

Permute a 4-bit string:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: B = [1, 1, 0, 0]
sage: sdes.permutation4(B)
[1, 0, 0, 1]
sage: sdes.permutation4([0, 1, 0, 1])
[1, 1, 0, 0]
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> B = [Integer(1), Integer(1), Integer(0), Integer(0)]
>>> sdes.permutation4(B)
[1, 0, 0, 1]
>>> sdes.permutation4([Integer(0), Integer(1), Integer(0), Integer(1)])
[1, 1, 0, 0]

We can also work with a string of bits:

sage: S = "1100"
sage: L = sdes.string_to_list(S)
sage: sdes.permutation4(L)
[1, 0, 0, 1]
sage: sdes.permutation4(sdes.string_to_list("0101"))
[1, 1, 0, 0]
>>> from sage.all import *
>>> S = "1100"
>>> L = sdes.string_to_list(S)
>>> sdes.permutation4(L)
[1, 0, 0, 1]
>>> sdes.permutation4(sdes.string_to_list("0101"))
[1, 1, 0, 0]
permutation8(B)[source]

Return a permutation of an 8-bit string. This permutation is called P8 and is specified as follows. Let (b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) be a vector of 10 bits where each bi{0,1}. Then P8 picks out 8 of those 10 bits and permutes those 8 bits:

P8(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9)=(b5,b2,b6,b3,b7,b4,b9,b8)

INPUT:

  • B – a block of 10-bit string

OUTPUT: pick out 8 of the 10 bits of B and permute those 8 bits

EXAMPLES:

Permute a 10-bit string:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: B = [1, 1, 0, 0, 1, 0, 0, 1, 0, 1]
sage: sdes.permutation8(B)
[0, 0, 0, 0, 1, 1, 1, 0]
sage: sdes.permutation8([0, 1, 1, 0, 1, 0, 0, 1, 0, 1])
[0, 1, 0, 0, 1, 1, 1, 0]
sage: sdes.permutation8([0, 0, 0, 0, 1, 1, 1, 0, 0, 0])
[1, 0, 1, 0, 0, 1, 0, 0]
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> B = [Integer(1), Integer(1), Integer(0), Integer(0), Integer(1), Integer(0), Integer(0), Integer(1), Integer(0), Integer(1)]
>>> sdes.permutation8(B)
[0, 0, 0, 0, 1, 1, 1, 0]
>>> sdes.permutation8([Integer(0), Integer(1), Integer(1), Integer(0), Integer(1), Integer(0), Integer(0), Integer(1), Integer(0), Integer(1)])
[0, 1, 0, 0, 1, 1, 1, 0]
>>> sdes.permutation8([Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0)])
[1, 0, 1, 0, 0, 1, 0, 0]

We can also work with a string of bits:

sage: S = "1100100101"
sage: L = sdes.string_to_list(S)
sage: sdes.permutation8(L)
[0, 0, 0, 0, 1, 1, 1, 0]
sage: sdes.permutation8(sdes.string_to_list("0110100101"))
[0, 1, 0, 0, 1, 1, 1, 0]
>>> from sage.all import *
>>> S = "1100100101"
>>> L = sdes.string_to_list(S)
>>> sdes.permutation8(L)
[0, 0, 0, 0, 1, 1, 1, 0]
>>> sdes.permutation8(sdes.string_to_list("0110100101"))
[0, 1, 0, 0, 1, 1, 1, 0]
permute_substitute(B, key)[source]

Apply the function ΠF on the block B using subkey key. Let (b0,b1,b2,b3,b4,b5,b6,b7) be a vector of 8 bits where each bi{0,1}, let L and R be the leftmost 4 bits and rightmost 4 bits of B respectively, and let F be a function mapping 4-bit strings to 4-bit strings. Then

ΠF(L,R)=(LF(R,S),R)

where S is a subkey and denotes the bit-wise exclusive-OR function.

The function F can be described as follows. Its 4-bit input block (n0,n1,n2,n3) is first expanded into an 8-bit block to become (n3,n0,n1,n2,n1,n2,n3,n0). This is usually represented as follows

Unknown environment 'tabular'

Let K=(k0,k1,k2,k3,k4,k5,k6,k7) be an 8-bit subkey. Then K is added to the above expanded input block using exclusive-OR to produce

Unknown environment 'tabular'

Now read the first row as the 4-bit string p0,0p0,3p0,1p0,2 and input this 4-bit string through S-box S0 to get a 2-bit output.

Unknown environment 'tabular'

Next read the second row as the 4-bit string p1,0p1,3p1,1p1,2 and input this 4-bit string through S-box S1 to get another 2-bit output.

Unknown environment 'tabular'

Denote the 4 bits produced by S0 and S1 as b0b1b2b3. This 4-bit string undergoes another permutation called P4 as follows:

P4(b0,b1,b2,b3)=(b1,b3,b2,b0)

The output of P4 is the output of the function F.

INPUT:

  • B – list of 8 bits

  • key – an 8-bit subkey

OUTPUT: the result of applying the function ΠF to B

EXAMPLES:

Applying the function ΠF to an 8-bit block and an 8-bit subkey:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: B = [1, 0, 1, 1, 1, 1, 0, 1]
sage: K = [1, 1, 0, 1, 0, 1, 0, 1]
sage: sdes.permute_substitute(B, K)
[1, 0, 1, 0, 1, 1, 0, 1]
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> B = [Integer(1), Integer(0), Integer(1), Integer(1), Integer(1), Integer(1), Integer(0), Integer(1)]
>>> K = [Integer(1), Integer(1), Integer(0), Integer(1), Integer(0), Integer(1), Integer(0), Integer(1)]
>>> sdes.permute_substitute(B, K)
[1, 0, 1, 0, 1, 1, 0, 1]

We can also work with strings of bits:

sage: B = "10111101"
sage: K = "11010101"
sage: B = sdes.string_to_list(B); K = sdes.string_to_list(K)
sage: sdes.permute_substitute(B, K)
[1, 0, 1, 0, 1, 1, 0, 1]
>>> from sage.all import *
>>> B = "10111101"
>>> K = "11010101"
>>> B = sdes.string_to_list(B); K = sdes.string_to_list(K)
>>> sdes.permute_substitute(B, K)
[1, 0, 1, 0, 1, 1, 0, 1]
random_key()[source]

Return a random 10-bit key.

EXAMPLES:

The size of each key is the same as the block size:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: key = sdes.random_key()
sage: len(key) == sdes.block_length()
True
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> key = sdes.random_key()
>>> len(key) == sdes.block_length()
True
sbox()[source]

Return the S-boxes of simplified DES.

EXAMPLES:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: sbox = sdes.sbox()
sage: sbox[0]; sbox[1]
(1, 0, 3, 2, 3, 2, 1, 0, 0, 2, 1, 3, 3, 1, 3, 2)
(0, 1, 2, 3, 2, 0, 1, 3, 3, 0, 1, 0, 2, 1, 0, 3)
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> sbox = sdes.sbox()
>>> sbox[Integer(0)]; sbox[Integer(1)]
(1, 0, 3, 2, 3, 2, 1, 0, 0, 2, 1, 3, 3, 1, 3, 2)
(0, 1, 2, 3, 2, 0, 1, 3, 3, 0, 1, 0, 2, 1, 0, 3)
string_to_list(S)[source]

Return a list representation of the binary string S.

INPUT:

  • S – string of bits

OUTPUT: list representation of the string S

EXAMPLES:

A list representation of a string of bits:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: S = "0101010110"
sage: sdes.string_to_list(S)
[0, 1, 0, 1, 0, 1, 0, 1, 1, 0]
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> S = "0101010110"
>>> sdes.string_to_list(S)
[0, 1, 0, 1, 0, 1, 0, 1, 1, 0]
subkey(K, n=1)[source]

Return the n-th subkey based on the key K.

INPUT:

  • K – a 10-bit secret key of this Simplified DES

  • n – (default: 1) if n=1 then return the first subkey based on K; if n=2 then return the second subkey. The valid values for n are 1 and 2, since only two subkeys are defined for each secret key in Schaefer’s S-DES.

OUTPUT: the n-th subkey based on the secret key K

EXAMPLES:

Obtain the first subkey from a secret key:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: key = [1, 0, 1, 0, 0, 0, 0, 0, 1, 0]
sage: sdes.subkey(key, n=1)
[1, 0, 1, 0, 0, 1, 0, 0]
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> key = [Integer(1), Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(0)]
>>> sdes.subkey(key, n=Integer(1))
[1, 0, 1, 0, 0, 1, 0, 0]

Obtain the second subkey from a secret key:

sage: key = [1, 0, 1, 0, 0, 0, 0, 0, 1, 0]
sage: sdes.subkey(key, n=2)
[0, 1, 0, 0, 0, 0, 1, 1]
>>> from sage.all import *
>>> key = [Integer(1), Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(0)]
>>> sdes.subkey(key, n=Integer(2))
[0, 1, 0, 0, 0, 0, 1, 1]

We can also work with strings of bits:

sage: K = "1010010010"
sage: L = sdes.string_to_list(K)
sage: sdes.subkey(L, n=1)
[1, 0, 1, 0, 0, 1, 0, 1]
sage: sdes.subkey(sdes.string_to_list("0010010011"), n=2)
[0, 1, 1, 0, 1, 0, 1, 0]
>>> from sage.all import *
>>> K = "1010010010"
>>> L = sdes.string_to_list(K)
>>> sdes.subkey(L, n=Integer(1))
[1, 0, 1, 0, 0, 1, 0, 1]
>>> sdes.subkey(sdes.string_to_list("0010010011"), n=Integer(2))
[0, 1, 1, 0, 1, 0, 1, 0]
switch(B)[source]

Interchange the first 4 bits with the last 4 bits in the list B of 8 bits. Let (b0,b1,b2,b3,b4,b5,b6,b7) be a vector of 8 bits, where each bi{0,1}. Then the switch function σ is given by

σ(b0,b1,b2,b3,b4,b5,b6,b7)=(b4,b5,b6,b7,b0,b1,b2,b3)

INPUT:

  • B – list; a block of 8 bits

OUTPUT:

A block of the same dimension, but in which the first 4 bits from B has been switched for the last 4 bits in B.

EXAMPLES:

Interchange the first 4 bits with the last 4 bits:

sage: from sage.crypto.block_cipher.sdes import SimplifiedDES
sage: sdes = SimplifiedDES()
sage: B = [1, 1, 1, 0, 1, 0, 0, 0]
sage: sdes.switch(B)
[1, 0, 0, 0, 1, 1, 1, 0]
sage: sdes.switch([1, 1, 1, 1, 0, 0, 0, 0])
[0, 0, 0, 0, 1, 1, 1, 1]
>>> from sage.all import *
>>> from sage.crypto.block_cipher.sdes import SimplifiedDES
>>> sdes = SimplifiedDES()
>>> B = [Integer(1), Integer(1), Integer(1), Integer(0), Integer(1), Integer(0), Integer(0), Integer(0)]
>>> sdes.switch(B)
[1, 0, 0, 0, 1, 1, 1, 0]
>>> sdes.switch([Integer(1), Integer(1), Integer(1), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0)])
[0, 0, 0, 0, 1, 1, 1, 1]

We can also work with a string of bits:

sage: S = "11101000"
sage: L = sdes.string_to_list(S)
sage: sdes.switch(L)
[1, 0, 0, 0, 1, 1, 1, 0]
sage: sdes.switch(sdes.string_to_list("11110000"))
[0, 0, 0, 0, 1, 1, 1, 1]
>>> from sage.all import *
>>> S = "11101000"
>>> L = sdes.string_to_list(S)
>>> sdes.switch(L)
[1, 0, 0, 0, 1, 1, 1, 0]
>>> sdes.switch(sdes.string_to_list("11110000"))
[0, 0, 0, 0, 1, 1, 1, 1]