DES-Modes.mws

Exploring DES, Modes of encryption

© Mike May, S. J., 2002, maymk@slu.edu

>    restart:

This worksheet does some exploration of DES.  It focuses on the 4 standard modes of using DES to encrypt and decrypt longer message .

Before you start this worksheet, you need to establish the file DES.m with a collection of constants and functions used by this worksheet.  This can be done by opening the worksheets entitled DES constants and DES functions and executing everything on those worksheets to define all the constants and functions we need.

This worksheet assumes that you have worked through the worksheet DES Example which looks at the mechanics of DES encryption on a single block of data.  (You don't require to have done that in this session.  We don't need results defined on that worksheet to make this one run.)

>    read `DES.m`:

We want to start with a standard key and a standard message for this worksheet.

>    plaintext := "Good morning Mr. Phelps.  Your mission,
should you choose to accept it, is to learn to use DES.";
DESkeyASCII := "Be-Happy";

plaintext :=
plaintext :=

DESkeyASCII :=

We want to convert our key to a hex string.  Then we want to expand the key out to the 16 subkeys.

>    hexkey := ASCII2hex16(DESkeyASCII);
keytable := keyexpander(hexkey):

hexkey := `42652D4861707079`

We also want to break our message into a list of hexwords.

>    plainhex := asciistrtohexword(plaintext);
plainlength := linalg[vectdim](plainhex);

plainhex := [`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `6973207...
plainhex := [`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `6973207...
plainhex := [`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `6973207...

plainlength := 12

Since our message is 12 blocks long we will need to use DES 12 times to encode our standard message.

Mode 1 - ECB - Electronic Code Book mode

The easiest mode to understand is the ECB mode.  This mode simply applied DES to each message block in turn.  The mode is easy to understand, can be adapted to parallel processing, and errors in one block of message do not cause problems in later blocks.

>    ECBcipher := linalg[vector](plainlength):
for i from 1 to plainlength do
    ECBcipher[i] := qdDEShex(plainhex[i],keytable):
od;
print(ECBcipher);

ECBcipher[1] := `752220C5FD43A428`

ECBcipher[2] := BB1C43EAF39906D1

ECBcipher[3] := `7938031E97FA3AA4`

ECBcipher[4] := `7540CBA014C43E48`

ECBcipher[5] := `5AEF081B303DFDC2`

ECBcipher[6] := F278EF6F34EE1BA0

ECBcipher[7] := EC3065BC54539DF7

ECBcipher[8] := `6332B8C57B8D9522`

ECBcipher[9] := `472A75F168F49681`

ECBcipher[10] := EF91FE7336918244

ECBcipher[11] := `84B3F8C6CAF52ECB`

ECBcipher[12] := `1451581B7832EFF1`

vector([`752220C5FD43A428`, BB1C43EAF39906D1, `7938031E97FA3AA4`, `7540CBA014C43E48`, `5AEF081B303DFDC2`, F278EF6F34EE1BA0, EC3065BC54539DF7, `6332B8C57B8D9522`, `472A75F168F49681`, EF91FE7336918244, `...
vector([`752220C5FD43A428`, BB1C43EAF39906D1, `7938031E97FA3AA4`, `7540CBA014C43E48`, `5AEF081B303DFDC2`, F278EF6F34EE1BA0, EC3065BC54539DF7, `6332B8C57B8D9522`, `472A75F168F49681`, EF91FE7336918244, `...
vector([`752220C5FD43A428`, BB1C43EAF39906D1, `7938031E97FA3AA4`, `7540CBA014C43E48`, `5AEF081B303DFDC2`, F278EF6F34EE1BA0, EC3065BC54539DF7, `6332B8C57B8D9522`, `472A75F168F49681`, EF91FE7336918244, `...

For decryption in this mode we simply apply unDEShex to each cipherblock in turn.

>    outofECB := linalg[vector](plainlength):
for i from 1 to plainlength do
    outofECB[i] := unDEShex(ECBcipher[i],keytable):
od:
print(outofECB);

vector([`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `697320746F20...
vector([`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `697320746F20...
vector([`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `697320746F20...

>    hexwordtoasciistr(outofECB);


Exercises:

1)  Create a short message (50-150 characters) that you want to encrypt.  Encrypt it with DES and the standard key.  Make sure that you can decrypt the message.  Post your message to the bulletin board and decrypt someone else's message.  (You probably want to avoid the variable names plainmess, plainhex, and plainlength, since we may want to use the current values of those variables later in the worksheet.)

>   

2)  Pick a DES key.  (It can be either 8 ASCII characters or 16 hex characters.)  Expand your key into a list of 16 subkeys.  (You probably want to avoid the variable names DESkeyASCII, hexkey, and keytable).

>   

3)  Use your key to encode the the standard message.  Make sure that it decodes as well.

>   

Mode 2 - CBC - Cipher Block Chaining

The next mode is the CBC or Cipher Block Chaining mode.  In this mode each block is XORed with the previous cipherblock before encryption.  For the first block we start with an initialization vector.  For this worksheet, we will use`0123456789ABCDEF` as the initialization vector.  In real practice, it is not unusual to start with the zero vector as the initial vector.

>    IVhex := `0123456789ABCDEF`:
CBCfeedin := linalg[vector](plainlength):
CBCcipher := linalg[vector](plainlength):
CBCfeedin[1] := xor64hex(IVhex, plainhex[1]);
CBCcipher[1] := qdDEShex(CBCfeedin[1],keytable);
for i from 2 to plainlength do
    CBCfeedin[i] := xor64hex(CBCcipher[i-1], plainhex[i]);
    CBCcipher[i] := qdDEShex(CBCfeedin[i],keytable):
od;
print(CBCcipher);

CBCfeedin[1] := `464C2A03A9C6A29D`

CBCcipher[1] := AEC5FF912E54F3FB

CBCfeedin[2] := C0AC91F60E1981D5

CBCcipher[2] := `8CAA6750C9AAB14E`

CBCfeedin[3] := ACFA0F35A5DAC260

CBCcipher[3] := CA63969B458CBEE2

CBCfeedin[4] := EA43CFF430FE9E8F

CBCcipher[4] := `8C5B07206B194975`

CBCfeedin[5] := E52874490477657F

CBCcipher[5] := `4F039292B903EDA7`

CBCfeedin[6] := `3C6BFDE7D567CDDE`

CBCcipher[6] := E17C92B174D0AC6F

CBCfeedin[7] := `8E09B2D21CBFC31C`

CBCcipher[7] := CAC60CB3A5A66FDB

CBCfeedin[8] := AFE678DC85C70CB8

CBCcipher[8] := A1E58BA294435B80

CBCfeedin[9] := C495FF82FD3777A0

CBCcipher[9] := `30FD78788C6B292E`

CBCfeedin[10] := `598E580CE34B454B`

CBCcipher[10] := D9946602E9546C62

CBCfeedin[11] := B8E608229D3B4C17

CBCcipher[11] := `4F07A9BC687B9CDF`

CBCfeedin[12] := `3C6289F82D28B2DF`

CBCcipher[12] := `783137EC03B62850`

vector([AEC5FF912E54F3FB, `8CAA6750C9AAB14E`, CA63969B458CBEE2, `8C5B07206B194975`, `4F039292B903EDA7`, E17C92B174D0AC6F, CAC60CB3A5A66FDB, A1E58BA294435B80, `30FD78788C6B292E`, D9946602E9546C62, `4F07...
vector([AEC5FF912E54F3FB, `8CAA6750C9AAB14E`, CA63969B458CBEE2, `8C5B07206B194975`, `4F039292B903EDA7`, E17C92B174D0AC6F, CAC60CB3A5A66FDB, A1E58BA294435B80, `30FD78788C6B292E`, D9946602E9546C62, `4F07...
vector([AEC5FF912E54F3FB, `8CAA6750C9AAB14E`, CA63969B458CBEE2, `8C5B07206B194975`, `4F039292B903EDA7`, E17C92B174D0AC6F, CAC60CB3A5A66FDB, A1E58BA294435B80, `30FD78788C6B292E`, D9946602E9546C62, `4F07...

To  decipher in this mode we unDES each block, then XOR the result with the previous block of plaintext result.  Note that we treat the initialization vector as the zeroth block of plaintext.

>    outofCBC := linalg[vector](plainlength):
CBCbeforeXOR := linalg[vector](plainlength):
CBCbeforeXOR[1] := unDEShex(CBCcipher[1],keytable);
outofCBC[1] := xor64hex(CBCbeforeXOR[1], IVhex);
for i from 2 to plainlength do
   CBCbeforeXOR[i] := unDEShex(CBCcipher[i],keytable):
   outofCBC[i] := xor64hex(CBCbeforeXOR[i], CBCcipher[i-1]);
od;
print(CBCcipher);
print(outofECB);
hexwordtoasciistr(outofCBC);

CBCbeforeXOR[1] := `464C2A03A9C6A29D`

outofCBC[1] := `476F6F64206D6F72`

CBCbeforeXOR[2] := C0AC91F60E1981D5

outofCBC[2] := `6E696E67204D722E`

CBCbeforeXOR[3] := ACFA0F35A5DAC260

outofCBC[3] := `205068656C70732E`

CBCbeforeXOR[4] := EA43CFF430FE9E8F

outofCBC[4] := `2020596F7572206D`

CBCbeforeXOR[5] := E52874490477657F

outofCBC[5] := `697373696F6E2C0A`

CBCbeforeXOR[6] := `3C6BFDE7D567CDDE`

outofCBC[6] := `73686F756C642079`

CBCbeforeXOR[7] := `8E09B2D21CBFC31C`

outofCBC[7] := `6F752063686F6F73`

CBCbeforeXOR[8] := AFE678DC85C70CB8

outofCBC[8] := `6520746F20616363`

CBCbeforeXOR[9] := C495FF82FD3777A0

outofCBC[9] := `6570742069742C20`

CBCbeforeXOR[10] := `598E580CE34B454B`

outofCBC[10] := `697320746F206C65`

CBCbeforeXOR[11] := B8E608229D3B4C17

outofCBC[11] := `61726E20746F2075`

CBCbeforeXOR[12] := `3C6289F82D28B2DF`

outofCBC[12] := `7365204445532E00`

vector([AEC5FF912E54F3FB, `8CAA6750C9AAB14E`, CA63969B458CBEE2, `8C5B07206B194975`, `4F039292B903EDA7`, E17C92B174D0AC6F, CAC60CB3A5A66FDB, A1E58BA294435B80, `30FD78788C6B292E`, D9946602E9546C62, `4F07...
vector([AEC5FF912E54F3FB, `8CAA6750C9AAB14E`, CA63969B458CBEE2, `8C5B07206B194975`, `4F039292B903EDA7`, E17C92B174D0AC6F, CAC60CB3A5A66FDB, A1E58BA294435B80, `30FD78788C6B292E`, D9946602E9546C62, `4F07...
vector([AEC5FF912E54F3FB, `8CAA6750C9AAB14E`, CA63969B458CBEE2, `8C5B07206B194975`, `4F039292B903EDA7`, E17C92B174D0AC6F, CAC60CB3A5A66FDB, A1E58BA294435B80, `30FD78788C6B292E`, D9946602E9546C62, `4F07...

vector([`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `697320746F20...
vector([`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `697320746F20...
vector([`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `697320746F20...


Exercises:

4)  Encrypt your short message with DES and the standard key using CBC mode.  Make sure that you can decrypt the message.  Post your message to the bulletin board and decrypt someone else's message.  

>   

5) Use your key to encode the the standard message with DES in CBC mode.  Make sure that you can decrypt back to the standard message.

>   

Mode 3 - CFB - Cipher Feedback Mode

CFB looks very similar to CBC.  The difference between the two modes is that CBC does an XOR, then encrypts, while CFB encrypts then does an XOR.  The advantage of CFB is the encryption part can be done before the block of message is entered.  That makes this mode better for devices where we want to encrypt a character or bit at a time.

>    CFBoutput := linalg[vector](plainlength):
CFBcipher := linalg[vector](plainlength):
CFBcipher[1] := qdDEShex(IVhex,keytable);
CFBoutput[1] := xor64hex(CFBcipher[1], plainhex[1]);
for i from 2 to plainlength do
    CFBcipher[i] := qdDEShex(CFBoutput[i-1],keytable):
    CFBoutput[i] := xor64hex(CFBcipher[i], plainhex[i]);
od;
print(CFBoutput);

CFBcipher[1] := B4A9495FF15BFE6C

CFBoutput[1] := F3C6263BD136911E

CFBcipher[2] :=

CFBoutput[2] := `69447C8DE65C15AD`

CFBcipher[3] := EC96E0796228835C

CFBoutput[3] := CCC6881C0E58F072

CFBcipher[4] := `9543CC6BB9C0325B`

CFBoutput[4] := B5639504CCB21236

CFBcipher[5] := A622BB7B1EFEA9B4

CFBoutput[5] := CF51C812719085BE

CFBcipher[6] := DB7F0CEF8FC94A7A

CFBoutput[6] := A817639AE3AD6A03

CFBcipher[7] := `455A024403C59B33`

CFBoutput[7] := `2A2F22276BAAF440`

CFBcipher[8] := `64D5320F5C5CFE6B`

CFBoutput[8] :=

CFBcipher[9] := D9AF107A145AA82E

CFBoutput[9] := BCDF645A7D2E840E

CFBcipher[10] := `71EB7B30C8492A1B`

CFBoutput[10] := `18985B44A769467E`

CFBcipher[11] := `487839D0F729226C`

CFBoutput[11] := `290A57F083460219`

CFBcipher[12] := `506CEDA47A3A5E69`

CFBoutput[12] := `2309CDE03F697069`

vector([F3C6263BD136911E, `69447C8DE65C15AD`, CCC6881C0E58F072, B5639504CCB21236, CF51C812719085BE, A817639AE3AD6A03, `2A2F22276BAAF440`,
vector([F3C6263BD136911E, `69447C8DE65C15AD`, CCC6881C0E58F072, B5639504CCB21236, CF51C812719085BE, A817639AE3AD6A03, `2A2F22276BAAF440`,
vector([F3C6263BD136911E, `69447C8DE65C15AD`, CCC6881C0E58F072, B5639504CCB21236, CF51C812719085BE, A817639AE3AD6A03, `2A2F22276BAAF440`,

To decrypt in this mode, we want to XOR each cipher block with the result of encrypting the previous ciphertext block.  Note that the decryption algorithm uses encryption rather than decryption for DES.

>    outofCFB := linalg[vector](plainlength):
CFBunDES := linalg[vector](plainlength):
CFBunDES[1] := qdDEShex(IVhex,keytable);
outofCFB[1] := xor64hex(CFBunDES[1], CFBoutput[1]);
for i from 2 to plainlength do
   CFBunDES[i] := qdDEShex(CFBoutput[i-1],keytable):
   outofCFB[i] := xor64hex(CFBoutput[i], CFBunDES[i]);
od;
print(CFBunDES);
print(outofCFB);
hexwordtoasciistr(outofCFB);

CFBunDES[1] := B4A9495FF15BFE6C

outofCFB[1] := `476F6F64206D6F72`

CFBunDES[2] :=

outofCFB[2] := `6E696E67204D722E`

CFBunDES[3] := EC96E0796228835C

outofCFB[3] := `205068656C70732E`

CFBunDES[4] := `9543CC6BB9C0325B`

outofCFB[4] := `2020596F7572206D`

CFBunDES[5] := A622BB7B1EFEA9B4

outofCFB[5] := `697373696F6E2C0A`

CFBunDES[6] := DB7F0CEF8FC94A7A

outofCFB[6] := `73686F756C642079`

CFBunDES[7] := `455A024403C59B33`

outofCFB[7] := `6F752063686F6F73`

CFBunDES[8] := `64D5320F5C5CFE6B`

outofCFB[8] := `6520746F20616363`

CFBunDES[9] := D9AF107A145AA82E

outofCFB[9] := `6570742069742C20`

CFBunDES[10] := `71EB7B30C8492A1B`

outofCFB[10] := `697320746F206C65`

CFBunDES[11] := `487839D0F729226C`

outofCFB[11] := `61726E20746F2075`

CFBunDES[12] := `506CEDA47A3A5E69`

outofCFB[12] := `7365204445532E00`

vector([B4A9495FF15BFE6C,
vector([B4A9495FF15BFE6C,
vector([B4A9495FF15BFE6C,

vector([`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `697320746F20...
vector([`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `697320746F20...
vector([`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `697320746F20...


Exercises

6)  Encrypt your short message with DES and the standard key using CFB mode.  Make sure that you can decrypt the message.  Post your message to the bulletin board and decrypt someone else's message.  

>   

7) Use your key to encode the the standard message with DES in CFB mode.  Make sure that you can decrypt back to the standard message.

>   

Mode 4 - OFB - Output Feedback mode

In many ways this fourth mode is a return to the one time pad with DES used as a generator of a pseudo random string.  Once again we start with an initialization vector.  This time we simply chain the encryption of the initialization vector back on itself without any interaction with the message.  We then XOR the message with the bitstream we have produced.  Since this is essentially a one time pad, it is crucial that each message start with a different initialization vector.

>    OFBoutput := linalg[vector](plainlength):
OFBbinpad := qdDEShex(IVhex,keytable);
for i from 1 to plainlength do
    CFBoutput[i] := xor64hex(OFBbinpad, plainhex[i]);
    OFBbinpad := qdDEShex(OFBbinpad,keytable);
od;
print(CFBoutput);

OFBbinpad := B4A9495FF15BFE6C

CFBoutput[1] := F3C6263BD136911E

OFBbinpad := `9F7E072A4B1C9BC1`

CFBoutput[2] := F117694D6B51E9EF

OFBbinpad := `338C08E009D3B668`

CFBoutput[3] := `13DC608565A3C546`

OFBbinpad := `7A5F35BE3A4554AA`

CFBoutput[4] := `5A7F6CD14F3774C7`

OFBbinpad := `678722CD38CC057B`

CFBoutput[5] :=

OFBbinpad := `95E9CA1D5E811C64`

CFBoutput[6] := E681A56832E53C1D

OFBbinpad := `64CDBD394F9B5C27`

CFBoutput[7] :=

OFBbinpad := C60FD370BB0F3569

CFBoutput[8] := A32FA71F9B6E560A

OFBbinpad := `3B9883F5E8B0EFE1`

CFBoutput[9] := `5EE8F7D581C4C3C1`

OFBbinpad := `10E09722A7FE839A`

CFBoutput[10] := `7993B756C8DEEFFF`

OFBbinpad := `24EFD8F69611496E`

CFBoutput[11] := `459DB6D6E27E691B`

OFBbinpad := `34029E0CDF6A58C1`

CFBoutput[12] := `4767BE489A3976C1`

OFBbinpad := `439AA5EA8748C6CA`

vector([F3C6263BD136911E, F117694D6B51E9EF, `13DC608565A3C546`, `5A7F6CD14F3774C7`,
vector([F3C6263BD136911E, F117694D6B51E9EF, `13DC608565A3C546`, `5A7F6CD14F3774C7`,
vector([F3C6263BD136911E, F117694D6B51E9EF, `13DC608565A3C546`, `5A7F6CD14F3774C7`,

Note that the creation of OFBbinpad does not interact with the message.  It could be done separately.

Once again we want to decipher the message to get back to the original message.

>    outofOFB := linalg[vector](plainlength):
OFBbinpad := qdDEShex(IVhex,keytable);
for i from 1 to plainlength do
    outofOFB[i] := xor64hex(OFBbinpad, CFBoutput[i]);
    OFBbinpad := qdDEShex(OFBbinpad,keytable);
od;
print(outofOFB);
hexwordtoasciistr(outofOFB);

OFBbinpad := B4A9495FF15BFE6C

outofOFB[1] := `476F6F64206D6F72`

OFBbinpad := `9F7E072A4B1C9BC1`

outofOFB[2] := `6E696E67204D722E`

OFBbinpad := `338C08E009D3B668`

outofOFB[3] := `205068656C70732E`

OFBbinpad := `7A5F35BE3A4554AA`

outofOFB[4] := `2020596F7572206D`

OFBbinpad := `678722CD38CC057B`

outofOFB[5] := `697373696F6E2C0A`

OFBbinpad := `95E9CA1D5E811C64`

outofOFB[6] := `73686F756C642079`

OFBbinpad := `64CDBD394F9B5C27`

outofOFB[7] := `6F752063686F6F73`

OFBbinpad := C60FD370BB0F3569

outofOFB[8] := `6520746F20616363`

OFBbinpad := `3B9883F5E8B0EFE1`

outofOFB[9] := `6570742069742C20`

OFBbinpad := `10E09722A7FE839A`

outofOFB[10] := `697320746F206C65`

OFBbinpad := `24EFD8F69611496E`

outofOFB[11] := `61726E20746F2075`

OFBbinpad := `34029E0CDF6A58C1`

outofOFB[12] := `7365204445532E00`

OFBbinpad := `439AA5EA8748C6CA`

vector([`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `697320746F20...
vector([`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `697320746F20...
vector([`476F6F64206D6F72`, `6E696E67204D722E`, `205068656C70732E`, `2020596F7572206D`, `697373696F6E2C0A`, `73686F756C642079`, `6F752063686F6F73`, `6520746F20616363`, `6570742069742C20`, `697320746F20...


Exercises:

8)  Encrypt your short message with DES and the standard key using OFB mode.  Make sure that you can decrypt the message.  Post your message to the bulletin board and decrypt someone else's message.  

>   

9) Use your key to encode the the standard message with DES in OFB mode.  Make sure that you can decrypt back to the standard message.

>