.title DESALT Macro-11 version of an encryption algorithm .ident /1.0.00/ .psect descod ,ro,d,lcl,rel,con .psect desdat ,ro,d,lcl,rel,con ; 02-AUG-1986 06:00 Brian Nelson (brian@uoft02.bitnet) ; ;/* NEWDES: An algorithm presented in CRYPTOLOGIA, Volume 9, Number 1, ; * January, 1985 in the article "Wide-Open Encryption Design ; * Offers Flexible Implementation" by Robert Scott, pp75-91. ; * This is a Feistel cipher which because of its simplicity ; * and "open" design, is touted by the author as an easily ; * programmed alternative to the Data Encryption Standard. ; * ; * This implementation by Richard Outerbridge, 8503.14. ; */ ; ; ; Macro-11 version notes: ; ; Macro-11 Translation by Brian Nelson 1-AUG-1986 15:32 ; ; Differences: I changed the data type for the key and data ; to CHAR (8 bit) ; ; Why?: I needed a good encryption routine for encoding data ; in the dynamic region I use for a command line editor on ; RSTS/E 9.3. Otherwise I would be quite content to leave it ; in C. ; ; ; Sample driver (DECUS C) ; ; ;#define EN 0 ;#define DE 1 ; ; ;char enks[60], deks[60]; ;char kraw[15] = { ; 31, 41, 59, 26, 53, 58, 97, 93, 238, 46, 26, 43, 38, 32, 79 }; ; ;char block[8] = { 65,66,67,68,69,70,71,72 }; ; ;main() { ; int i; ; ; kinit(kraw, EN, enks); ; kinit(kraw, DE, deks); ; ; putout(block); ; desalt(block, enks); ; putout(block); ; desalt(block, deks); ; putout(block); ; ; for(i=0; i<29; i++) desalt(block, enks); ; putout(block); ; ; for(i=0; i<29; i++) desalt(block, deks); ; putout(block); ; ; } ; ;putout(oblock) ;char *oblock; ; { ; int i ; ; int j ; ; for(i=0; i<8; i++) { j=oblock[i]; printf(" %d", j); } ; ; printf("\n"); ; return; ; } ; ; ; ; Debuging .enabl gbl .save .psect desdat ,d fmt$: .asciz /%d/<12> .restore .macro DECOUT v mov r0 ,-(sp) mov r1 ,-(sp) mov v ,-(sp) mov #fmt$ ,-(sp) call PRINTF cmp (sp)+ ,(sp)+ mov (sp)+ ,r1 mov (sp)+ ,r0 .endm DECOUT .sbttl Initialize the key string .psect descod ,i ; KINIT ; ; Passed: ; 2(sp) Ascii key address, 8 characters ; 4(sp) MODE, eq 1 for DECRYPT, 0 for ENCRYPT ; 6(sp) Where to write new KEY, 60 characters long K.IN = 2 + <4*2> MODE = 4 + <4*2> KSCHED = 6 + <4*2> DE = 1 Kinit:: mov r2 ,-(sp) ; Save mov r3 ,-(sp) ; ..Save mov r4 ,-(sp) ; ....Save mov r5 ,-(sp) ; ......Save mov KSCHED(sp),r5 ; Destination (byte) cmp MODE(sp),#DE ; Which way (Decode or Encode)? bne 10$ ; Not decode mov #11. ,r0 ; I = 11 mov #9. ,r1 ; Delta = 9 mov #12. ,r2 ; Finis = 12 br 20$ ; 10$: clr r0 ; else I = 0 mov #1 ,r1 ; Delta = 1 clr r2 ; Finis = 0 20$: call 200$ ; First inc r0 ; Move offset up cmp r0 ,#15. ; Reset offset yet? bne 30$ ; No clr r0 ; Yes 30$: call 200$ ; ..Next inc r0 ; Move offset up cmp r0 ,#15. ; Reset offset yet? bne 40$ ; No clr r0 ; Yes 40$: call 200$ ; ....Next inc r0 ; Move offset up cmp r0 ,#15. ; Reset offset yet? bne 50$ ; No clr r0 ; Yes 50$: call 200$ ; ......Next add r1 ,r0 ; i += delta cmp r0 ,#14. ; If (i > 14 ) i -= 15 ble 60$ ; Ok sub #15. ,r0 ; Done 60$: cmp r0 ,r2 ; Are we all done with key gen? beq 100$ ; Yes, exit call 200$ ; No, Do the next three inc r0 ; i++ call 200$ ; .. inc r0 ; i++ call 200$ ; .... add r1 ,r0 ; i += delta cmp r0 ,#14. ; Reset? ble 70$ ; No sub #15. ,r0 ; Yes 70$: br 20$ ; Next please 100$: mov (sp)+ ,r5 ; ......Restore mov (sp)+ ,r4 ; ....Restore mov (sp)+ ,r3 ; ..Restore mov (sp)+ ,r2 ; Restore return ; Exit 200$: mov r0 ,r3 ; *ksched++ = k_in[i++] add K.IN+2(sp),r3 ; .. movb (r3) ,(r5)+ ; .. return .sbttl The actual encryption code and data .psect desdat ,d .radix 10 f$tab: .byte 32,137,239,188,102,125,221, 72,212, 68, 81, 37, 86,237,147,149, .byte 70,229, 17,124,115,207, 33, 20,122,143, 25,215, 51,183,138,142, .byte 146,211,110,173, 1,228,189, 14,103, 78,162, 36,253,167,116,255, .byte 158, 45,185, 50, 98,168,250,235, 54,141,195,247,240, 63,148, 2, .byte 224,169,214,180, 62, 22,117,108, 19,172,161,159,160, 47, 43,171, .byte 194,175,178, 56,196,112, 23,220, 89, 21,164,130,157, 8, 85,251, .byte 216, 44, 94,179,226, 38, 90,119, 40,202, 34,206, 35, 69,231,246, .byte 29,109, 74, 71,176, 6, 60,145, 65, 13, 77,151, 12,127, 95,199, .byte 57,101, 5,232,150,210,129, 24,181, 10,121,187, 48,193,139,252, .byte 219, 64, 88,233, 96,128, 80, 53,191,144,218, 11,106,132,155,104, .byte 91,136, 31, 42,243, 66,126,135, 30, 26, 87,186,182,154,242,123, .byte 82,166,208, 39,152,190,113,205,114,105,225, 84, 73,163, 99,111, .byte 204, 61,200,217,170, 15,198, 28,192,254,134,234,222, 7,236,248, .byte 201, 41,177,156, 92,131, 67,249,245,184,203, 9,241, 0, 27, 46, .byte 133,174, 75, 18, 93,209,100,120, 76,213, 16, 83, 4,107,140, 52, .byte 58, 55, 3,244, 97,197,238,227,118, 49, 79,230,223,165,153, 59 .radix 8 .psect descod ,i ; DESALT ; ; Passed: 2(sp) Address of data to be acted on, 8 bytes ; 4(sp) Address of key string from KINIT TBLOCK = 2 + <6*2> ; Offset for data + registers saved KS = 4 + <6*2> ; Offset for key + registers saved ; Register usage: ; ; R5 key string, after call to KINIT, 60 bytes ; R4 DOEE ; R3 DOER Desalt::mov r0 ,-(sp) ; Save mov r1 ,-(sp) ; ..Save mov r2 ,-(sp) ; ....Save mov r3 ,-(sp) ; ......Save mov r4 ,-(sp) ; ........Save mov r5 ,-(sp) ; ..........Save clr r2 ; Loop counter mov KS(sp) ,r5 ; Get a pointer to key (byte) 10$: mov TBLOCK(sp),r3 ; Get a pointer to text (byte) mov r3 ,r4 ; Get a pointer to 5th byte add #4 ,r4 ; Set it up and move over call 200$ ; Convert a byte call 200$ ; ..Convert a byte call 200$ ; ....Convert a byte call 200$ ; ......Convert a byte cmp r2 ,#10 ; Time to leave? beq 100$ ; Yes, exit mov TBLOCK(sp),r4 ; Pointer to text[1] inc r4 ; ... clr r1 ; Get a copy of the 5th character bisb @r3 ,r1 ; Without sign extension call 200$ ; Same thing again clr r0 ; Next character is special case bisb (r3)+ ,r0 ; Copy without sign extension xor r1 ,r0 ; Do the XOR clr r1 ; Now get set to xor the table bisb (r4) ,r1 ; entry with the destination mov r2 ,-(sp) ; Save it clr r2 ; Avoid SXT bisb f$tab(r0),r2 ; XOR is restrictive in address modes. xor r2 ,r1 ; Do it movb r1 ,(r4)+ ; Copy mov (sp)+ ,r2 ; Restore r2 call 200$ ; Do the next one mov TBLOCK(sp),r4 ; Do the last one call 200$ ; Do it inc r2 ; Loop back now br 10$ ; Next please 100$: mov (sp)+ ,r5 ; ..........Restore mov (sp)+ ,r4 ; ........Restore mov (sp)+ ,r3 ; ......Restore mov (sp)+ ,r2 ; ....Restore mov (sp)+ ,r1 ; ..Restore mov (sp)+ ,r0 ; Restore return ; Exit 200$: mov r1 ,-(sp) ; Save it mov r2 ,-(sp) ; ..Save it clr r0 ; Compute now bisb (r3)+ ,r0 ; ... clr r1 ; Second part bisb (r5)+ ,r1 ; Get the key data xor r1 ,r0 ; Compute XOR clr r1 ; Now get set to xor with the bisb (r4) ,r1 ; destination. Avoid sign extension clr r2 ; Avoid SXT bisb f$tab(r0),r2 ; Get the table entry xor r1 ,r2 ; Do it movb r2 ,(r4)+ ; Copy mov (sp)+ ,r2 ; ..Pop it mov (sp)+ ,r1 ; Pop it return ; Exit .end