Encryption utility
Karl Denninger
karl at ddsw1.UUCP
Mon Apr 4 14:11:21 AEST 1988
This is a 'C' rewrite of a publically-available encryption utility we've had
in the woodwork for a while. It works on a rather simple, but surprisingly
effective principle. The output while encrypted has a nearly perfect random
byte distribution from 1 -- 255.
Without the password, which can be up to 80 characters in length (ie: a
sentence; in fact this is recommended) you're in a for a *long* search.
I'm all ears on methods of attacking this, it's been through some reasonably
concerted attempts to break it and no one has yet succeeded.
Basic operation:
The cipher is a substitution cipher executed by the 'XOR'
instruction, with an interesting twist.
Picture a key and plaintext, as thus:
Key > a b c d e f g h i j
Plain> z x y c d s f g h t
The cipher proceeds down the line, from left to right, XORing the
bytes one by one. This would be trivially easy to break, except for
one feature:
A checksum is kept of the bytes processed before and after
XOR; when this checksum reaches a value the entire KEY
string is XORd with the checksum value; the checksum value
is then normalized to reflect the remainder from the
'preset' value.
This combination makes for a cipher which produces a near-random
distribution. For binary files, this is probably enough. For text, though,
there is a small window in the very front of the file in which it might be
possible to perform pattern-analysis to produce the password. To forestall
these attempts, 768 bytes of randomly-generated garbage are prepended to the
file before encryption takes place, and are removed on decryption. These
random bytes serve only to provide a 'seed' for the encryption function to
prevent pattern analysis. In addition, three "FF"s are added during
encryption at the VERY END of the file; this facilitates location of the
actual file end point if the encrypted file should be transmitted via
Xmodem or any other protocol which pads received data.
Of course, I welcome any comments on the implementation; those of you who
believe it should be trivial to break are welcome to try - a sample text
file is enclosed in the 'shar' which follows, encoded with a reasonably
simple password. The only hint I will give you is that it is prose, and
in English. The first person (and only the first one) who can send the
plaintext of this to me by email will receive $25.00 (just to make it
worth your while). The file is called 'text.uue' in the SHAR, it's a
uuencoded copy of the encrypted text file.
This code should run on any reasonable UNIX-based system.
---- Code begins below ----
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# encrypt.c
# text.uue
sed 's/^X//' << 'SHAR_EOF' > encrypt.c
X/* Encrypt: encrypt or decrypt a file. */
X/*
X This code and associated documentation is Copyright 1988 MCS, Inc.
X Non-profit distribution authorized.
X Please send modifications, etc. to ....ihnp4!ddsw1!karl.
X
X NOTE: If your system uses unsigned characters, you need to change
X the define below for MARKER to be '255' instead of '-1'.
X
X*/
X
X#include <stdio.h>
X#include <fcntl.h>
X#include <sys/types.h>
X
X#define MARKER -1 /* Marker for EOF (unsigned uses 255) */
X
Xchar key[80]; /* Keep the keyspace global */
X
Xenchar(ch) /* Process one character */
Xchar ch; /* Current character */
X
X{
X static int kptr = 0; /* Key pointer */
X static int chsum = 0; /* Key checksum */
X char outch;
X int kx;
X int xkey;
X
X chsum += ch; /* Add before encryption */
X outch = ch ^ key[kptr++]; /* Encrypt */
X chsum += outch; /* And add after */
X if (key[kptr] == 0) /* Restart if at end */
X kptr = 0;
X if (chsum >= 4096) { /* If > 2^^12 - 1 */
X chsum -= 4096; /* Roll checksum... */
X kx = 0;
X xkey = chsum && 255; /* And XOR key */
X while (key[kx] != 0) {
X key[kx] = key[kx] ^ xkey;
X if (key[kx] == 0)/* Insure we don't stop early */
X key[kx] = key[kx] ^ xkey;
X kx++;
X }
X }
X return(outch); /* Return encrypted/decrypted */
X}
X
Xmain()
X{
X
X char infile[80]; /* Path buffers */
X char outfile[80];
X char buffer[256], bufout[256]; /* Block buffers */
X char key2[80]; /* Verification space */
X int fi, fo; /* Two fd's */
X long posit, outpos, pst, oldpos; /* file offsets */
X int jcount; /* Count of skips */
X char encdec[5]; /* Operation flag */
X int ctback, blocks, remain; /* Temp storage */
X int encrypt = 0, decrypt = 0; /* Two flags */
X int outch; /* Outbound character */
X int x, y; /* Two temps */
X
X fputs("Encrypt/Decrypt : ", stdout);
X gets(encdec); /* See what the user wants */
X if ((*encdec == 'e') || (*encdec == 'E'))
X encrypt++;
X else {
X if ((*encdec == 'd') || (*encdec == 'D'))
X decrypt++;
X else {
X puts("Invalid encrypt/decrypt, exit");
X exit(1);
X }
X }
X fputs(" Input filename : ", stdout);
X gets(infile);
X fputs("Output filename : ", stdout);
X gets(outfile);
X fputs(" Enter key : ", stdout);
X gets(key);
X fputs(" Validate : ", stdout);
X gets(key2);
X if (strcmp(key, key2) != 0) {
X puts("Key validation failed.");
X exit(1);
X }
X puts("\nStand by, working...");
X if ((fi = open(infile, O_RDONLY)) == MARKER) {
X perror("Input");
X exit(1);
X }
X if ((fo = open(outfile, O_WRONLY|O_CREAT, 0660)) == MARKER) {
X perror("Output");
X exit(1);
X }
X posit = lseek(fi, 0L, 2); /* Seek EOF */
X posit--; /* Last byte is 1 less */
X if (decrypt != 0) { /* Find marker if decrypt */
X puts("Searching for marker");
X oldpos = posit;
X posit -= 2;
X while (posit >= 0) {
X lseek(fi, posit, 0);
X read(fi, buffer, 3);
X if ((buffer[0] == MARKER) && (buffer[1] == MARKER) && (buffer[2] == MARKER)) {
X oldpos = posit - 1;
X printf("Found marker at location %d\n", oldpos);
X posit = 0;
X }
X posit--;
X }
X if (posit < 0) /* Adjust file pointer */
X posit = oldpos;
X }
X if (encrypt != 0) { /* Add scrambling on encrypt */
X posit += 768; /* Do 3 256-byte records */
X srand(time(0L)); /* Seed random generator */
X puts("Adding seed data (768 bytes)");
X for (x = 0; x < 768; x++) {
X y = (char) rand();
X outch = enchar(y); /* Add 768 random bytes */
X lseek(fo, posit, 0);
X write(fo, &outch, 1);
X posit--;
X }
X }
X if (encrypt != 0)
X puts("Encrypting...");
X else
X puts("Decrypting...");
X if (decrypt != 0)
X jcount = 768; /* Strip 768 on decrypt */
X else
X jcount = 0;
X blocks = ((posit + 1) / 256); /* Number of full blocks */
X remain = ((posit + 1) - (blocks * 256)); /* Remainder */
X lseek(fi, (long) (blocks * 256), 0); /* Seek to start of remainder */
X read(fi, buffer, remain); /* Get remainder */
X remain--;
X for (x = remain; x >= 0; x--) /* Build remainder buffer */
X bufout[x] = enchar(buffer[x]);
X if (jcount == 0) {
X lseek(fo, (long) (blocks * 256), 0);
X write(fo, bufout, (remain + 1)); /* Write remainder */
X } else
X jcount -= (remain + 1); /* Ditch it */
X blocks--; /* Compute # of blocks */
X for (x = blocks; x >= 0 ; x--) {
X lseek(fi, (long) (x * 256), 0);
X read(fi, buffer, 256); /* Read block */
X for (y = 255; y >= 0; y--) /* Encrypt/decrypt block */
X bufout[y] = enchar(buffer[y]);
X lseek(fo, (long) (x * 256), 0);
X if (jcount != 0) { /* Write/count block */
X if (jcount > 256)
X jcount -= 256;
X else {
X write(fo, bufout, (256 - jcount));
X jcount = 0;
X }
X } else
X write(fo, bufout, 256);
X }
X if (encrypt != 0) {
X buffer[0] = MARKER;
X buffer[1] = MARKER; /* Make 3 255's */
X buffer[2] = MARKER;
X lseek(fo, 0L, 2); /* Seek EOF */
X write(fo, buffer, 3);
X }
X close(fo);
X close(fi);
X puts("Complete.");
X exit(0);
X}
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > text.uue
Xbegin 660 text.enc
XM9SX53U,O-UU43DL!05Q=%$`<5T)C8C8\2408%59N*C8`%T<>#155'@XR1QH!
XM"@%23S]/!@<,%#1%4P0)&D!*"P$!``%810 at .$E@#&F=;'`M84A8-%40&!@@1
XM,%(2#@U424)/$$@03PI(#1YK1!L<,EP<#0Q4&P`(#E,',A%C4Q<)!1E8#0H,
XM11I)#`$(%1!$$!IG3AH7%T\63A)/4T0+&"<`!AE(`TE8!T14'08*#$P.%%1X
XM'"]`%@I86!P;1TD34`!4)TX<#4D&3 at T7"E14!AE7"$T!`1`&)T`6"EE!!D\'
XM``!*!1DN``$,'Q522$%N*C8`%U0-#Q4`/RT4`U0G%D)=3 at 584D,(%2I-4@<;
XM55="!P9$5!X03@,)040''2]`$D\;50$&"$4`5$0=+54!&D at 55`Q'5Q%'1W(4
XM6UM-&4I?=P-4`0H!!0<&`1=+!!TO`1,<25T/`T`,21H>30$("!)70TXM3P<#
XM4`Y23R]&4UX+`&)!`0Q(`$A)3R)H)CTL*QT($E(<`&=8'`%84Q8>"%,&544`
XM+`$'&TD"25@'1$$;3QQ8#0\5`!$`-E=5`!\`!@</4U-!#1DG`%H-``%)2!Q%
XM408'%E4("4!.`60B0A4'%$073A-.4E,,$&)!$08>$0!-"P!2$!P*"4P5#E52
XM&"]"&4\+11$*#E<7!D%&=@]"6&-_:$,-"500"QP!!`-`51L'-`\2!Q1$4 at X4
XM15-4"Q at G```<!1E!7A9$4P$.#4D?&`A#`4\G31L;#`$<&Q4!`5\6`"9,4@<?
XM$%,-&@U$?@(94AE-!D4%3R)/#!Q901P+1D%32P$!-D4!21\<24\'1%<4'%A,
XM#`0,1!=.,T!4'1=,%DX.3P9#%Q$P51<,205$7@$7`!1/#D4)!VM/`$\U054-
XM&$,95$94&T(7$&)!`0U)'$]9"PM%$0I83@,!&0$'`6=-`0<415,:#T1250T/
XM)P`<#T@`2$E/`DD9"EE4`TP`*@`*)UT:`1A"'@I&31=0`!AM`5(_!@!-20!"
XM5509&4\9311.4P,F1!%.$512&PE/4T(%!CL`'`=(#4]93PM5`4\-2`D>!`QX
XM&"A:&`I85A91;2M?"TA9;@$P#0X<3PT(#$T8"PH!0$!-#%YD3!9!6TP04A\'
XM1Q8'!Q0A2!9)`!U47V5$`%5>2AA?7$%0$@DB#Q</&TD63 at I(`54`!TD!4DA)
XM50$-7D51!@$;4DT>%T`#'B)+5`<6*U-.1P%2!D5$8U$`!PH&`5X9!%$$"QP!
XM`A at 4*U)/9A]&5TH04 at D/3!94'08V11Y)&!5'24\6110+"BI,34`!4TYV'%0=
XM#T`#3 at 93%T=%!")&%T@;$$!)'6\!5$Y8`4Q?4@`!&"=>50X+11-/%D$40D0"
XM,$D'#!M^``Q/1`!"74$!'0P'1`!.-4H7`AE('@L#`114"AEC1P`-#%5-1!T1
XM*U5/2!547E$14A\G21`<65,:#A1%%P<``"<`!P9(%T]<%TA.&D,/4P09!0$5
XM`35$?DY8`5-.1P%+!A45)$0!2!H=0%X*```1&AP`&`-!0Q,,+DM5!Q!4`65&
XM`%,14T)U$%,:`!532`I%414)'5)-#@]1&@LC)51<0!-&7%804E8$$R8!%`D=
XM&%1?940`1UA,%EY504,"&F9-&@$-10H;1E,$3A`6*T0!8DE$&1U:5QA,3E!/
XM`@-`0A\!)$1=3AQ$!0<$1%)."@$G4@$<&`!3)D]$$T=62Q!:3!52$Q\U)$1>
XM215`6E$34E4<!S=$'T@*%$U!'6\K5$Y8`3 at D)`%33A=F,$Y8<2,F(@!39$15
XM8@`@/2$Y90P[,'E53RUI(2E!8STB"V\[*W,`4TX,0`!*145W&$5>2405%%U7
XM`51>6!-?5U,825Y_#U1>2@%27UP10`=+`#%27`L!&@]:!D0/!1T/#P<-$TQ=
XM02=<`08;319.;0$!7Q85)TQ22%],$A].10%46DH!351`$$M4=!I.7$H`4E]7
XM`%,>7D1Z```0&P!!6$]N`%5/$D$>`$$11E9U'%5/6`%'74<!0 at 971GD22E)<
XM10$-7E<!5%Y"$5Q-34H`!F<E5$Y82A(="@!"$E=`<@!"6E]`$0Q;70!'74,5
XM7E93$E)/=AU53TD:0EQ&5QL&$ATM3Q<:27\!#4X.0`8"6!!865,04U]R'$%>
XM6!=*3E0221)13W,34TE81P`,7UX014\)4TQ!`$043TPD-`$=`!-/%$$<0 at H9
XM8W47$!U52$,-"50'!Q=/3&=J:1I.,T<1'!P!>&4G3!\'"Q-B61P<2!Q!6 at I$
XM4A`>#$4?&`1$4 at 8I21L<%4`'!PA/4DD+5"Q4`$@(`%5"#`14$$Y?1 at D8%5E5
XM3S1+!0,80Q<"`TX'+104(4L2#@U:``PG`5(020L!&04%`1`;-5T:"PP!&@`!
XM3EX&!`=C5A=(`1172$X,5$]E<T],)14`$QHA0Q`!#5-2(@]#`4 at 4&C!45!I(
XM$T19&AP-5`\614T)#T0`3BE``$X=3P<'%40>7T4&)E`?"`L1`$4;2@!5-A95
XM9DQ!50$*9EH=!@H`'0$#`!Q)1`TL5`!(#1Q`00<+`1@'%D0>0VI.4SHO2E08
XM'5,`!PE.4V4-&2X`)0@"'P!9'`%350<84TP.!$4<3S5;!0H*4A8*`D5>!A(=
XM-TE2`00%4T(8`$5^3EA"#!T!0QH"+UH<"@H.4D]L3U-N$%4K4U,('A5)0`X&
XM3!!/&%1,`P\!$`8F71,+6$``3 at 8!`E0`&2I4'T@>'%5%3A%)$4\)51X/"4$!
XM"F9!$T\-2!=E1@`52`@9+5<:!P]44%\!`507&@L;9V0/`3(E!'Q41A=4`4X%
XM0P$&%ALE504)&Q$/808'4AH?%E(80$$3$%YI'1==6092/"5O4W\!&RM84CY`
XM?RA"3C%@,$Y0<@X"0'D6`"Y75#A83AT"'@AX+PI4`D\+2"0<0E\!%4X&&EAT
XM(R0X`1P<9WPW(5AY%@`/6%-!$1DN```0&P!%04]N*55/44D)5D%D%QEF?0P<
XM60M2/1-.!TX)$&)/`4D+&TU<`P%4$$9S*C\)$4$`#C-*&!=4`0<&`@$1218`
XM8T@!2$U`$0->50]43C%530X/3!8<9ED<&Q$`$T\52!Q5$%4F10`*&AU06`8+
XM3E4`'P!G`A!$`0\S1AL`6$`="D=('%41!C9"!@$&&U(-1A=%%`,564!,"%12
XM!BA=`0X53`%/#TY3%408*TX&'0T'`1=#3"M^)QX!&@A`0A(`9TT13A='4P8"
XM30(&`1LM!@9(`1!311L%5!!/#4],!`Y,'@HT#W]E4P!:/"5O4W\!&RM84@$:
XM54`-&A=`$`L50!\&0$X53C-'$4XK0!T:!@$Q5!$/8F\##!H55$4`"@!33S1)
XM#QX.4QT),@=_3UD(/P8%4AQ7"P<V`"8G(2P`11Q$054;"T$("0Q!``1F01-/
XM.'14.T9B%DL(52Y!$1I(4@!A!@=2&A\64AA`06D<#&@'?W3Q=*<;;L-O at M/6
XM at D)Y]MAKL)9@#"ZKWHU)GP at 9:..`>E@`M`DHQIM:8\&I_$Z3J))2 at F4(Q!-*
XM:5')CI_?NL4:TE$*PRAE'HC?/'^*,?1*1F1VD+6S@$J++V0,H%7'[!9BMM"@
XM_\N1)Y'6"0S%+<D.?4(Y+T^?QAZ\!^7.`-';"+!)XV1)QC#.>,/SDX##<4FX
XMHV#E27L!`+(L\'B9._T#^6^>#H[75IY31Y=(F3>L[IOF;J.\<4AO0,-_C:NQ
XMR\-I>[HGW-F4\L3#)KH??C86C>ZF?#<!&H!?(X,K1?X,*WT*/K/.&H3WC/T:
XMY,Z7=`+Q-%T:P(*0-,*2V68IJFVL<O(10&N;BQ9(^NZMI[O9Q-6O](<E?"$(
XMN5LI9`1QH&MG-O2JV'Q6::OW7DJ*TK,Q8FV,S,AHWR]`M;E>J&*6H1&=N,BY
XM=Y*D8,:WE:*M=I<D@#"&JY=ME,R$='U^WJGED<:<5WGE+7OL6VA7>."]<H?E
XMJLCHY)#>U447!A^8C]I-Y;&A at 05K6*8.BO";MJ_-9/]$M]2)D:8?L\$9(![&
XM at K/!7\>&XG#Y[(1*WG"+E]2C6,:KZ^F?!>X4,T4F%3V'1+CAF^ORVL[R/>"=
XMAI4UUD3=`\\V\V_$U-IHDC-7N2,4.N=ZNS?JVQ7ZL[^$2J-H277K(+?RW-&$
XMPZ23YD5IV5?#^&7_O@[+4MN=N^$:%F^;%YK@,W:&!Y/\YR(L_A at GR3TXO]/C
XMZ081L&(`L&;8]!\$&3(C)%W2,!"S'$E_H37^AL+\MMZ7"R+XQ at V5#QUAMN8#
XMY"\\Q4CX$5,8PC-PC[WNM&G,+:H7C[PPBS_$K0SAB,47C_74>33#A]0JOW21
XMU/H]HV=9<0T/$)5A- at HE?#(G6FO at R:^HR!3>^,I7<RP*JVI&BV6N\DF_FOXJ
XMI1%3>_I[2C3U'DQ$XN!)7,82N<:LB/E9UCLHZQ5\?)NK7WRFOTLQ]7G;\D"`
XH`_1.*Q')UTO%)&T-B+</<;823G?'*]]1`T?CFM*UI&DM-*TNL/___WG;
X`
Xend
SHAR_EOF
exit
More information about the Alt.sources
mailing list