.title DES - Software DES functions ; ; Program: DES.MAR V4.1 ; ; Author: David G. North, CCP ; 1333 Maywood Ct ; Plano, Texas 75023-1914 ; (214) 902-3957 ; Co-authorship credits: ; Jim Gillogly, 1977 initial release of a PD DES program ; Phil Karn, 1986 conversion/insertion to DECUS Crypt ; ; Date: 90.11.16 ; ; Revisions: ; Who Date Description ; D.North 901116 DECUS release (V4.0) ; D.North 911113 DECUS release (V4.1) ; ; License: ; Ownership of and rights to these programs is retained by the author(s). ; Limited license to use and distribute the software in this library is ; hereby granted under the following conditions: ; 1. Any and all authorship, ownership, copyright or licensing ; information is preserved within any source copies at all times. ; 2. Under absolutely *NO* circumstances may any of this code be used ; in any form for commercial profit without a written licensing ; agreement from the author(s). This does not imply that such ; a written agreement could not be obtained. ; 3. Except by written agreement under condition 2, source shall ; be freely provided with all binaries. ; 4. Library contents may be transferred or copied in any form so ; long as conditions 1, 2, and 3 are met. Nominal charges may ; be assessed for media and transferral labor without such charges ; being considered 'commercial profit' thereby violating condition 2. ; ; Warranty: ; These programs are distributed in the hopes that they will be useful, but ; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ; or FITNESS FOR A PARTICULAR PURPOSE. ; ;/* Sofware DES functions ; * written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from ; * the 1977 public-domain program by Jim Gillogly ; */ ; Converted from C to MACRO-32 90.09.11 DGN .psect DES$RO$TABLES,noexe,rd,nowrt,shr,pic ;/* Tables defined in the Data Encryption Standard documents */ ; ;/* initial permutation IP */ ;char iprm[] = { iprm: .byte - 58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7 ;}; ; ;/* final permutation IP^-1 */ ;char fprm[] = { fprm: .byte - 40, 8, 48, 16, 56, 24, 64, 32, - 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25 ;}; ; ;/* expansion operation matrix ; * This is for reference only; it is unused in the code ; * as the f() function performs it implicitly for speed ; */ ;#if 0 ;char ei[] = { ; 32, 1, 2, 3, 4, 5, ; 4, 5, 6, 7, 8, 9, ; 8, 9, 10, 11, 12, 13, ; 12, 13, 14, 15, 16, 17, ; 16, 17, 18, 19, 20, 21, ; 20, 21, 22, 23, 24, 25, ; 24, 25, 26, 27, 28, 29, ; 28, 29, 30, 31, 32, 1 ;}; ;#endif ; ;/* permuted choice table (key) */ ;char pc1[] = { pc1: .byte - 57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - ; 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4 ;}; ; ;/* number left rotations of pc1 */ ;char totrot[] = { totrot: .byte - 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 ;}; ; ;/* permuted choice key (table) */ ;char pc2[] = { pc2: .byte - 14, 17, 11, 24, 1, 5, - 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, - 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, - 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, - 46, 42, 50, 36, 29, 32 ;}; ; ;/* The (in)famous S-boxes */ ;char si[8][64] = { si: .byte - ; /* S1 */ 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, - 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, - 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, - 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, - ; ; /* S2 */ 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, - 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, - 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, - 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, - ; ; /* S3 */ 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, - 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, - 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, - 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, - ; ; /* S4 */ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, - 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, - 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, - 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, - ; ; /* S5 */ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, - 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, - 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, - 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, - ; ; /* S6 */ 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, - 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, - 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, - 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, - ; ; /* S7 */ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, - 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, - 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, - 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, - ; ; /* S8 */ 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, - 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, - 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, - 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 ;}; ; ;/* 32-bit permutation function P used on the output of the S-boxes */ ;char p32i[] = { p32i: .byte - 16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25 ;}; ;/* End of DES-defined tables */ .psect DES$RW$DATA,noexe,rd,wrt,noshr,pic ; ;/* Lookup tables initialized once only at startup by desinit() */ ;long spc[8][64]; /* Combined S and P boxes */ spc: .blkl 8*64 ; ;char iperm[8*16][16][8]; /* Initial and final permutations */ iperm: .blkb 8*16*8*16 ;16Kb ;char fperm[8*16][16][8]; fperm: .blkb 8*16*8*16 ;16Kb ; ;/* 8 6-bit subkeys for each of 16 rounds, initialized by setkey() */ ;unsigned char kn[16*8][8]; kn: .blkb 16*8*8 ; ;/* bit 0 is left-most in byte */ ;int bytebit[] = { ; 0200,0100,040,020,010,04,02,01 bytebit: .long 128,64,32,16,8,4,2,1 ;}; ; ;int nibblebit[] = { ; 010,04,02,01 nibblebit: .long 8,4,2,1 ;}; ; .psect DES$RO$CODE,exe,rd,nowrt,shr,pic ;/* Allocate space and initialize DES lookup arrays ; * mode == 0: standard DES ; */ ;int ;desinit(){ .entry desinit,^m<> subl2 #16,sp ; spcinit(); calls #0,spcinit ; perminit(iperm,iprm); pushal IPRM pushal IPERM calls #2,perminit ; perminit(fperm,fprm); pushal FPRM pushal FPERM calls #2,perminit ; return(0); clrl r0 ret ;} nop ; ;/* Free up storage used by DES */ ;int ;desdone(){ .entry desdone,^m<> subl2 #4,sp ; /* Stubbed... data now statically allocated */ ;} ret tstl r0 ; ;/* Set key (initialize key schedule array) */ ;setkey(key) ;char *key; /* 64 bits (will use only 56) */ .entry setkey,^m movab -128(sp),sp movab BYTEBIT,r11 movab KN,r8 movab PC2,r9 movab PC1,r10 ;{ ; char pc1m[56]; /* place to modify pc1 into */ ; char pcr[56]; /* place to rotate pc1 into */ ; register int i,j,l; ; int m; ; ; for (j=0; j<56; j++) { /* convert pc1 to bits of key */ clrl r2 movl 4(ap),r7 movab -60(fp),r6 movab (r10),r5 sym.1: ; l=pc1[j]-1; /* integer bit location */ cvtbl (r5),r3 decl r3 ; m = l & 07; /* find bit */ bicl3 #-8,r3,r4 ; pc1m[j]=(key[l>>3] & /* find which key byte l is in */ ; bytebit[m]) /* and which bit of that byte */ ; ? 1 : 0; /* and store 1-bit result */ ashl #-3,r3,r3 cvtbl (r7)[r3],r3 mcoml r3,r3 bicl3 r3,(r11)[r4],r3 beql sym.2 movb #1,r3 brb sym.3 tstl r0 nop sym.2: clrb r3 sym.3: movb r3,(r6) ; } incl r6 incl r5 aobleq #55,r2,sym.1 ; /* Clear key schedule */ ; for (i=0; i<16; i++) clrl r1 nop sym.4: ; for (j=0; j<8; j++) clrl r0 ashl #3,r1,r3 movab 0(r8)[r3],r2 sym.5: ; kn[i][j]=0; clrb (r2) incl r2 aobleq #7,r0,sym.5 aobleq #15,r1,sym.4 ; ; for (i=0; i<16; i++) { /* key chunk for each iteration */ clrl r3 movab TOTROT,8(sp) nop sym.6: ; for (j=0; j<56; j++) /* rotate pc1 the right amount */ clrl r0 cvtbl @8(sp),r7 movab -116(fp),r6 sym.7: ; pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28]; addl3 r0,r7,r5 cmpl r0,#28 bgeq sym.8 movb #28,r1 brb sym.9 tstl r0 sym.8: movb #56,r1 sym.9: cvtbl r1,r2 cmpl r5,r2 bgeq sym.10 movl r5,r4 brb sym.11 sym.10: subl3 #28,r5,r4 sym.11: movb -60(fp)[r4],(r6) incl r6 aobleq #55,r0,sym.7 ; /* rotate left and right halves independently */ ; for (j=0; j<48; j++){ /* select bits individually */ clrl r2 movab (r9),r6 sym.12: ; /* check bit that goes to kn[j] */ ; if (pcr[pc2[j]-1]){ cvtbl (r6),r0 decl r0 tstb -116(fp)[r0] beql sym.13 ; /* mask it in if it's there */ ; l= j % 6; emul #0,#0,r2,r0 ediv #6,r0,r1,r0 movl r0,r5 ; kn[i][j/6] |= bytebit[l] >> 2; ashl #3,r3,r1 divl3 #6,r2,r0 addl2 r1,r0 movab (r8)[r0],r1 movzbl (r1),r4 ashl #-2,(r11)[r5],r0 bisb3 r0,r4,(r1) ; } ; } sym.13: incl r6 aobleq #47,r2,sym.12 ; } incl 8(sp) acbl #15,#1,r3,sym.6 ;} ret ;/* In-place encryption of 64-bit block */ ;endes(block) ;char *block; .entry endes,^m subl2 #24,sp ;{ ; register int i; ; long work[2]; /* Working data storage */ ; long tmp; ; ; permute(block,iperm,(char *)work); /* Initial Permutation */ pushal -12(fp) pushal IPERM pushl 4(ap) calls #3,permute ; ; /* Do the 16 rounds */ ; for (i=0; i<16; i++) clrl r2 nop sym.14: ; round(i,work); pushal -12(fp) pushl r2 calls #2,round aobleq #15,r2,sym.14 ; ; /* Left/right half swap */ ; tmp = work[0]; movl -12(fp),r2 ; work[0] = work[1]; movl -8(fp),-12(fp) ; work[1] = tmp; movl r2,-8(fp) ; ; permute((char *)work,fperm,block); /* Inverse initial permutation */ pushl 4(ap) pushal FPERM pushal -12(fp) calls #3,permute ;} ret ;/* In-place decryption of 64-bit block */ ;dedes(block) ;char *block; .entry dedes,^m subl2 #24,sp ;{ ; register int i; ; unsigned long work[2]; /* Working data storage */ ; long tmp; ; ; permute(block,iperm,(char *)work); /* Initial permutation */ pushal -12(fp) pushal IPERM pushl 4(ap) calls #3,permute ; ; /* Left/right half swap */ ; tmp = work[0]; movl -12(fp),r3 ; work[0] = work[1]; movl -8(fp),-12(fp) ; work[1] = tmp; movl r3,-8(fp) ; ; /* Do the 16 rounds in reverse order */ ; for (i=15; i >= 0; i--) cvtwl #15,r2 sym.15: ; round(i,work); pushal -12(fp) pushl r2 calls #2,round sobgeq r2,sym.15 ; ; permute((char *)work,fperm,block); /* Inverse initial permutation */ pushl 4(ap) pushal FPERM pushal -12(fp) calls #3,permute ;} ret tstl r0 ; ;/* Permute inblock with perm */ ;static ;permute(inblock,perm,outblock) ;char *inblock, *outblock; /* result into outblock,64 bits */ .entry permute,^m subl2 #4,sp ;char perm[16][16][8]; /* 2K bytes defining perm. */ ;{ ; register int i,j; ; register char *ib, *ob; /* ptr to input or output block */ ; register char *p, *q; ; ; /* Clear output block */ ; for (i=8, ob = outblock; i != 0; i--) movl #8,r0 movl 12(ap),r1 tstl r0 beql sym.17 sym.16: ; *ob++ = 0; clrb (r1)+ decl r0 bneq sym.16 sym.17: ; ; ib = inblock; movl 4(ap),r5 ; for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */ clrl r4 movl 8(ap),r9 sym.18: ; ob = outblock; movl 12(ap),r3 ; p = perm[j][(*ib >> 4) & 017]; ashl #7,r4,r7 movb (r5),r8 cvtbl r8,r6 ashl #-4,r6,r6 bicl2 #-16,r6 ashl #3,r6,r6 addl2 r7,r6 movab (r9)[r6],r2 ; q = perm[j + 1][*ib & 017]; addl3 #1,r4,r7 ashl #7,r7,r7 bicb3 #-16,r8,r6 cvtbl r6,r6 ashl #3,r6,r6 addl2 r7,r6 movab (r9)[r6],r1 ; for (i = 8; i != 0; i--){ /* and each output byte */ movl #8,r0 beql sym.20 tstl r0 nop sym.19: ; *ob++ |= *p++ | *q++; /* OR the masks together*/ bisb3 (r2)+,(r1)+,r6 bisb2 r6,(r3)+ ; } decl r0 bneq sym.19 sym.20: ; } addl2 #2,r4 incl r5 cmpl r4,#16 blss sym.18 ;} ret tstl r0 ; ;/* Do one DES cipher round */ ;static ;round(num,block) ;int num; /* i.e. the num-th one */ .entry round,^m subl2 #4,sp ;unsigned long *block; ;{ ; long f(); ; ; /* The rounds are numbered from 0 to 15. On even rounds ; * the right half is fed to f() and the result exclusive-ORs ; * the left half; on odd rounds the reverse is done. ; */ ; if(num & 1){ moval 4(ap),r3 bbc #0,(r3),sym.21 ; block[1] ^= f(block[0],kn[num]); movl 8(ap),r2 ashl #3,(r3),r0 pushab KN[r0] pushl (r2) calls #2,f xorl2 r0,4(r2) ; } else { ret nop sym.21: ; block[0] ^= f(block[1],kn[num]); movl 8(ap),r2 ashl #3,(r3),r0 pushab KN[r0] pushl 4(r2) calls #2,f xorl2 r0,0(r2) ; } ;} ret ;/* The nonlinear function f(r,k), the heart of DES */ ;static ;long ;f(r,subkey) ;unsigned long r; /* 32 bits */ .entry f,^m subl2 #4,sp movab SPC,r4 ;unsigned char subkey[8]; /* 48-bit key for this round */ ;{ ; register unsigned long rval,rt; ; /* Run E(R) ^ K through the combined S & P boxes ; * This code takes advantage of a convenient regularity in ; * E, namely that each group of 6 bits in E(R) feeding ; * a single S-box is a contiguous segment of R. ; */ ; rt = (r >> 1) | ((r & 1) ? 0x80000000 : 0); extzv #1,#31,4(ap),r3 movl 4(ap),r5 blbc r5,sym.22 movl #-2147483648,r6 brb sym.23 tstl r0 sym.22: clrl r6 sym.23: bisl3 r6,r3,r1 ; rval = 0; clrl r0 ; rval |= spc[0][((rt >> 26) ^ *subkey++) & 0x3f]; extzv #26,#6,r1,r3 movl 8(ap),r2 incl 8(ap) movzbl (r2),r2 xorl2 r2,r3 bicl2 #-64,r3 bisl2 (r4)[r3],r0 ; rval |= spc[1][((rt >> 22) ^ *subkey++) & 0x3f]; extzv #22,#10,r1,r3 movl 8(ap),r2 incl 8(ap) movzbl (r2),r2 xorl2 r2,r3 bicl2 #-64,r3 bisl2 256(r4)[r3],r0 ; rval |= spc[2][((rt >> 18) ^ *subkey++) & 0x3f]; extzv #18,#14,r1,r3 movl 8(ap),r2 incl 8(ap) movzbl (r2),r2 xorl2 r2,r3 bicl2 #-64,r3 bisl2 512(r4)[r3],r0 ; rval |= spc[3][((rt >> 14) ^ *subkey++) & 0x3f]; extzv #14,#18,r1,r3 movl 8(ap),r2 incl 8(ap) movzbl (r2),r2 xorl2 r2,r3 bicl2 #-64,r3 bisl2 768(r4)[r3],r0 ; rval |= spc[4][((rt >> 10) ^ *subkey++) & 0x3f]; extzv #10,#22,r1,r3 movl 8(ap),r2 incl 8(ap) movzbl (r2),r2 xorl2 r2,r3 bicl2 #-64,r3 bisl2 1024(r4)[r3],r0 ; rval |= spc[5][((rt >> 6) ^ *subkey++) & 0x3f]; extzv #6,#26,r1,r3 movl 8(ap),r2 incl 8(ap) movzbl (r2),r2 xorl2 r2,r3 bicl2 #-64,r3 bisl2 1280(r4)[r3],r0 ; rval |= spc[6][((rt >> 2) ^ *subkey++) & 0x3f]; extzv #2,#30,r1,r3 movl 8(ap),r2 incl 8(ap) movzbl (r2),r2 xorl2 r2,r3 bicl2 #-64,r3 bisl2 1536(r4)[r3],r0 ; rt = (r << 1) | ((r & 0x80000000) ? 1 : 0); ashl #1,r5,r3 bbc #31,r5,sym.24 movb #1,r5 brb sym.25 sym.24: clrb r5 sym.25: cvtbl r5,r2 bisl3 r2,r3,r1 ; rval |= spc[7][(rt ^ *subkey) & 0x3f]; movzbl @8(ap),r2 xorl2 r1,r2 bicl2 #-64,r2 bisl2 1792(r4)[r2],r0 ; ; return(rval); ret ;} ;/* initialize a perm array */ ;static ;perminit(perm,p) ;char perm[16][16][8]; /* 64-bit, either init or final */ .entry perminit,^m subl2 #8,sp movab NIBBLEBIT,r9 movab BYTEBIT,r10 ;char p[64]; ;{ ; register int l, j, k; ; int i,m; ; ; /* Clear the permutation array */ ; for (i=0; i<16; i++) clrl r6 movl 4(ap),r4 sym.26: ; for (j=0; j<16; j++) clrl r1 ashl #7,r6,r5 tstl r0 sym.27: ; for (k=0; k<8; k++) clrl r0 ashl #3,r1,r3 addl2 r5,r3 movab 0(r4)[r3],r2 nop sym.28: ; perm[i][j][k]=0; clrb (r2) incl r2 aobleq #7,r0,sym.28 aobleq #15,r1,sym.27 aobleq #15,r6,sym.26 ; ; for (i=0; i<16; i++) /* each input nibble position */ clrl r7 movl 8(ap),r8 nop sym.29: ; for (j = 0; j < 16; j++)/* each possible input nibble */ clrl r1 tstl r0 sym.30: ; for (k = 0; k < 64; k++)/* each output bit position */ clrl r0 movab 0(r8),r6 nop sym.31: ; { l = p[k] - 1; /* where does this bit come from*/ cvtbl (r6),r3 decl r3 ; if ((l >> 2) != i) /* does it come from input posn?*/ ashl #-2,r3,r2 cmpl r2,r7 bneq sym.32 ; continue; /* if not, bit k is 0 */ ; if (!(j & nibblebit[l & 3])) bicl2 #-4,r3 mcoml r1,r2 bicl3 r2,(r9)[r3],r2 beql sym.32 ; continue; /* any such bit in input? */ ; m = k & 07; /* which bit is this in the byte*/ bicl3 #-8,r0,r5 ; perm[i][j][k>>3] |= bytebit[m]; ashl #7,r7,r2 ashl #3,r1,r3 addl2 r2,r3 ashl #-3,r0,r4 addl2 r3,r4 movl 4(ap),r3 cvtbl (r3)[r4],r2 bisl2 (r10)[r5],r2 cvtlb r2,(r3)[r4] ; } sym.32: incl r6 aobleq #63,r0,sym.31 aobleq #15,r1,sym.30 aobleq #15,r7,sym.29 ;} ret tstl r0 ; ;/* Initialize the lookup table for the combined S and P boxes */ ;static int ;spcinit() ;{ .entry spcinit,^m subl2 #40,sp movab P32I,r8 ; char pbox[32]; ; int p,i,s,j,rowcol; ; long val; ; ; /* Compute pbox, the inverse of p32i. ; * This is easier to work with ; */ ; for(p=0;p<32;p++){ clrl r6 movab -36(fp),r5 nop sym.33: ; for(i=0;i<32;i++){ clrl r3 movab 0(r8),r2 nop sym.34: ; if(p32i[i]-1 == p){ cvtbl (r2),ap decl ap cmpl ap,r6 bneq sym.35 ; pbox[p] = i; cvtlb r3,(r5) ; break; brb sym.36 ; } nop ; } sym.35: incl r2 aobleq #31,r3,sym.34 sym.36: ; } incl r5 aobleq #31,r6,sym.33 ; for(s = 0; s < 8; s++){ /* For each S-box */ clrl r4 tstl r0 sym.37: ; for(i=0; i<64; i++){ /* For each possible input */ clrl r9 ashl #6,r4,r6 moval SPC[r6],r10 tstl r0 sym.38: ; val = 0; clrl r2 ; /* The row number is formed from the first and last ; * bits; the column number is from the middle 4 ; */ ; rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf); bicl3 #-33,r9,r1 blbc r9,sym.39 movb #16,r5 brb sym.40 tstl r0 sym.39: clrb r5 sym.40: cvtbl r5,ap bisl2 ap,r1 ashl #-1,r9,ap bicl2 #-16,ap bisl3 ap,r1,r11 ; for(j=0;j<4;j++){ /* For each output bit */ clrl r0 addl3 r11,r6,r3 movb SI[r3],r7 cvtbl r7,r1 tstl r0 nop sym.41: ; if(si[s][rowcol] & (8 >> j)){ mnegl r0,ap ashl ap,#8,ap mcoml ap,ap bicl3 ap,r1,ap beql sym.42 ; val |= 1L << (31 - pbox[4*s + j]); ashl #2,r4,ap addl2 r0,ap cvtbl -36(fp)[ap],ap subl3 ap,#31,ap ashl ap,#1,ap bisl2 ap,r2 ; } ; } sym.42: aobleq #3,r0,sym.41 ; spc[s][i] = val; movl r2,(r10) ; ; } addl2 #4,r10 aobleq #63,r9,sym.38 ; } acbl #7,#1,r4,sym.37 ;} ret .end