-- DES: test program
-- DESTest.mesa
-- Andrew Birrell 1-Mar-82 15:29:38
-- Michael D. Schroeder, November 4, 1981 10:29 AM--
DIRECTORY
Ascii USING[ CR, SP ],
DESFace,
TTY,
String;
DESTest: PROGRAM IMPORTS DESFace, TTY, String =
BEGIN
OPEN DESFace, String;
h: TTY.Handle = TTY.Create["DESTest.log$"];
modeChar: CHARACTER;
i: CARDINAL;
-- Test data that exercises every S-Box Entry
-- Source: Federal Register, XXX
-- Values in Hex
-- (Key) (Data) (Cipher)
-- 7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B
-- 0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271
-- 07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A
-- 3849674C2602319E 51454B582DDF440A 7178876E01F19B2A
-- 04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095
-- 0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B
-- 0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09
-- 43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A
-- 07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F
-- 04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088
-- 37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77
-- 1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A
-- 584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56
-- 025816164629B007 480D39006EE762F2 A1F9915541020B56
-- 49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556
-- 4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC
-- 49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A
-- 018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41
-- 1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793
-- 0101010101010101 AAAAAAAAAAAAAAAA 3AE716954DC04E25
-- 0101010101010101 0000000000000000 8CA64DE9C1B123A7
keySequence: ARRAY [0..20] OF Block ←
[Block[76241B, 10105B, 45032B, 67127B],
Block[461B, 154541B, 116701B, 33556B],
Block[3641B, 11476B, 45013B, 23206B],
Block[34111B, 63514B, 23002B, 30636B],
Block[2271B, 12672B, 41776B, 132666B],
Block[423B, 134560B, 176464B, 171316B],
Block[560B, 170565B, 43217B, 132746B],
Block[41451B, 77655B, 34343B, 71776B],
Block[3647B, 11560B, 42732B, 25026B],
Block[2150B, 110404B, 141375B, 35457B],
Block[33720B, 65665B, 13313B, 72506B],
Block[17410B, 23015B, 15302B, 43136B],
Block[54100B, 21544B, 15272B, 60566B],
Block[1130B, 13026B, 43051B, 130007B],
Block[44571B, 37274B, 74663B, 22617B],
Block[47660B, 57025B, 12653B, 71647B],
Block[44751B, 56555B, 46242B, 24677B],
Block[603B, 10334B, 40233B, 23326B],
Block[16130B, 77434B, 11622B, 47757B],
Block[401B, 401B, 401B, 401B],
Block[401B, 401B, 401B, 401B]];
dataSequence: ARRAY [0..20] OF Block ←
[Block[641B, 153320B, 34567B, 63502B],
Block[56325B, 46250B, 36757B, 53732B],
Block[1110B, 152070B, 3366B, 70562B],
Block[50505B, 45530B, 26737B, 42012B],
Block[41375B, 42060B, 54527B, 77642B],
Block[2633B, 57010B, 50717B, 12072B],
Block[3526B, 154340B, 73507B, 60722B],
Block[73045B, 12270B, 24677B, 44152B],
Block[35735B, 10620B, 44467B, 24002B],
Block[23225B, 57550B, 32657B, 60232B],
Block[13115B, 57100B, 47447B, 51062B],
Block[65405B, 67030B, 72637B, 56312B],
Block[113B, 153357B, 4427B, 60142B],
Block[44015B, 34400B, 67347B, 61362B],
Block[41565B, 40310B, 64617B, 36372B],
Block[3455B, 41640B, 73407B, 51222B],
Block[1376B, 52567B, 100427B, 170452B],
Block[16635B, 56120B, 14367B, 24302B],
Block[30125B, 31050B, 66557B, 24532B],
Block[125252B, 125252B, 125252B, 125252B],
Block[0B, 0B, 0B, 0B]];
cipherSequence: ARRAY [0..20] OF Block ←
[Block[64417B, 55415B, 115046B, 111633B],
Block[75070B, 116420B, 32513B, 151161B],
Block[103216B, 135521B, 145264B, 54632B],
Block[70570B, 103556B, 761B, 115452B],
Block[127467B, 175502B, 17614B, 40225B],
Block[103245B, 60361B, 7306B, 154133B],
Block[6323B, 155002B, 41B, 156011B],
Block[165147B, 65454B, 133733B, 25572B],
Block[157726B, 45201B, 56257B, 15017B],
Block[56121B, 36234B, 44206B, 140210B],
Block[5052B, 167256B, 37764B, 125567B],
Block[167433B, 170076B, 56772B, 53532B],
Block[104277B, 6666B, 153415B, 167126B],
Block[120771B, 110525B, 40402B, 5526B],
Block[67677B, 16257B, 147775B, 2526B],
Block[27442B, 162233B, 125574B, 120654B],
Block[55153B, 60454B, 141154B, 147112B],
Block[57514B, 1616B, 150453B, 27101B],
Block[61772B, 140320B, 32331B, 173623B],
Block[35347B, 13225B, 46700B, 47045B],
Block[106246B, 46751B, 140661B, 21647B]];
DO
ENABLE BEGIN -- catch phrases--
InvalidNumber =>
BEGIN TTY.PutChar[h,Ascii.CR]; TTY.PutLine[h,"Invalid number -- start over."];
CONTINUE;
END;
TTY.Rubout =>
BEGIN TTY.PutLine[h,"XXX"]; CONTINUE; END;
END; -- catch phrases--
TTY.PutString[h,
"(C)bc, (E)cb, (F)ixed parameters, Q(uit), or R(andom key)? "L];
DO
modeChar ← TTY.GetChar[h];
SELECT modeChar FROM
'c, 'e, 'f, 'q, 'r => {TTY.PutChar[h,modeChar]; EXIT};
ENDCASE;
TTY.PutChar[h,'?];
ENDLOOP;
TTY.PutChar[h,Ascii.CR];
SELECT modeChar FROM
'q => EXIT;
'r => BEGIN
key: Key ← GetRandomKey[];
keyWP: POINTER TO ARRAY [0 .. 3] OF UNSPECIFIED
= LOOPHOLE[@key];
TTY.PutString[h,"Octal key is: "];
FOR i IN [0 .. 3]
DO TTY.PutOctal[h,keyWP[i]]; TTY.PutChar[h,Ascii.SP]; ENDLOOP;
TTY.PutChar[h,Ascii.CR];
END;
'f => BEGIN --fixed parameters tests--
error: BOOLEAN ← FALSE;
block: Block;
FOR i IN [0 .. 20] DO
EncryptBlock[LOOPHOLE[keySequence[i], Key],
@dataSequence[i], @block];
IF block # cipherSequence[i] THEN BEGIN
TTY.PutString[h,"Encryption #"L];
TTY.PutDecimal[h,LOOPHOLE[i, INTEGER]];
TTY.PutLine[h," wrong."L];
error ← TRUE
END;
DecryptBlock[LOOPHOLE[keySequence[i], Key],
@cipherSequence[i], @block];
IF block # dataSequence[i] THEN BEGIN
TTY.PutString[h,"Decryption #"L];
TTY.PutDecimal[h,LOOPHOLE[i, INTEGER]];
TTY.PutLine[h," wrong."L];
error ← TRUE
END;
ENDLOOP;
IF NOT error THEN TTY.PutLine[h,"No errors in fixed parameters test."L];
END --fixed parameters tests--;
ENDCASE =>
BEGIN --encryption and decryption tests--
key: Key;
keyWP: POINTER TO ARRAY [0 .. 3] OF UNSPECIFIED
= LOOPHOLE[@key];
blocks: ARRAY [0 .. 7] OF UNSPECIFIED;
blocksLP: Blocks = LOOPHOLE[LONG[@blocks]];
seed: IV;
source: STRING ← [128];
IF modeChar='c THEN BEGIN
TTY.PutLine[h,"Type four octal numbers as chaining seed: "L];
FOR i IN [0..3] DO seed[i] ← TTY.GetOctal[h]; TTY.PutChar[h,Ascii.SP]; ENDLOOP;
TTY.PutChar[h,Ascii.CR];
END;
source.length ← 0;
TTY.PutString[h,"Password? "];
TTY.GetLine[h,source];
key ← MakeKey[LONG[source]];
TTY.PutString[h,"Octal key is: "];
FOR i IN [0 .. 3] DO TTY.PutOctal[h,keyWP[i]]; TTY.PutChar[h,Ascii.SP]; ENDLOOP;
TTY.PutChar[h,Ascii.CR];
IF modeChar='e
THEN BEGIN
TTY.PutLine[h,"Type four octal numbers as block to be encrypted: "];
FOR i IN [0..3] DO blocks[i] ← TTY.GetOctal[h]; TTY.PutChar[h,Ascii.SP]; ENDLOOP;
END
ELSE BEGIN
TTY.PutLine[h,"Type eight octal numbers as block to be encrypted: "];
FOR i IN [0..7] DO blocks[i] ← TTY.GetOctal[h]; TTY.PutChar[h,Ascii.SP]; ENDLOOP;
END;
TTY.PutChar[h,Ascii.CR];
IF modeChar='e
THEN ECBEncrypt[key, 1, blocksLP, blocksLP]
ELSE CBCEncrypt[key, 2, blocksLP, blocksLP, seed];
TTY.PutString[h,"Encrypted value is: "];
FOR i IN [0 .. IF modeChar='e THEN 3 ELSE 7] DO
TTY.PutOctal[h,blocks[i]]; TTY.PutChar[h,Ascii.SP];
ENDLOOP;
TTY.PutChar[h,Ascii.CR];
IF modeChar='c
THEN CBCDecrypt[key, 2, blocksLP, blocksLP, seed]
ELSE ECBDecrypt[key, 1, blocksLP, blocksLP];
TTY.PutString[h,"Decrypted value is: "];
FOR i IN [0 .. IF modeChar='e THEN 3 ELSE 7] DO
TTY.PutOctal[h,blocks[i]]; TTY.PutChar[h,Ascii.SP];
ENDLOOP;
TTY.PutChar[h,Ascii.CR];
END; --encryption and decryption tests--
ENDLOOP;
TTY.Destroy[h];
END.