🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: sci.crypt
Article #2696

otp.c - one-time pad program

#2696
From: Bill Stewart 908-949-0705 erebus...
Date: Sat, 08 May 1993 05:28
124 lines
5214 bytes
There's been some discussion about one-time pads, so I've written a simple
program that XORs two files together, and does simple management functions
like writing the unused bits of the pad into a new file, and
either failing or reusing the pad multiple times if the pad runs out early.

It's not usable for encryption outside the US, because that would require two
different people to securely exchange an identical set of random numbers,
which the U.S. Government would disapprove of :-)
But it's a simple demonstration of how two files can be XORed together,
using obvious techniques available in the public domain, and
furthermore includes correct use of the underutilized getopt() routine.

Disclaimer: It's Public Domain, Free, Not Copyrighted, Not Copylefted,
you may use it for anything you like, commercial or otherwise,
except in support of initiation of force against other people*,
I expressly make no guarantees about its usefulness for anything,
my employer had nothing to do with it, and the user bears all
responsibility for any consequences of using it.
In particular, please don't use otp to xor files into themselves;
they tend to be truncated, which will not be what you intended :-)

*Political Diatribe:  This program is not copyrighted,
so I can't enforce restrictions on its use, but you don't have my
permission to use it to support initiating force against anybody,
and if you work for a government, that's probably your job.
I guess that's a copyanarchist or something.....


----- cut here ------ otp.shar ------ cut here ----
#if you're not on UNIX, you can unpack this by
# removing the initial X's with your favorite text editor.
echo "x - otp.c"
sed 's/^X//' > otp.c <<!
X/* Basic Public-Domain Non-Copyrighted One Time Pad Program */
Xchar *Usage="otp [-r] [-n newpad] [-c] [-s skipbytes] padfile [file]\nxor padfile with file or stdin\n-r - reuse padfile as many times as needed [disparaged]\n-p newpad - write unused portion of padfile to newpad\n";
Xchar *Usage2="-c - output count of bytes read or skipped to stderr on completion\n-s skipbytes - skip that many bytes of pad file\nShortcomings: doesn't portably rewrite new pad onto old or overwrite file,\nand can't detect reuse of the pad\n";
Xchar *permissions="While this is not a copyrighted program, you do not have my permission to use this program for initiation of force against other people\n";
X
X#include <stdio.h>
X
Xmain(argc, argv)
Xint argc; 
Xchar **argv;
X{
X	register int c, p, n=0;
X	extern char *optarg;
X	extern int optind;
X	FILE *pad, *newpad, *in;
X	char *newpadname = 0;
X	int reuseflag = 0;
X	int skipbytes = 0;
X	int outputcount = 0;
X
X	/* getopt() is available public domain if your system doesn't have it.*/
X	while ( (c=getopt(argc, argv, "crn:s:")) != -1) switch(c) {
X	case 'c': outputcount++; break;
X	case 'r': reuseflag++; break;
X	case 'n': newpadname = optarg; 
X		if ((newpad=fopen(optarg,"w"))==NULL) {
X			fprintf(stderr,"OTP: Can't Open newpad %s\n", optarg);
X			exit(98);
X		}
X		break;
X	case 's': skipbytes = atoi(optarg); break;
X	default:  fprintf(stderr, "%s%s", Usage, Usage2); exit(99);
X	}
X
X	if (optind==argc) {fprintf(stderr, "%s%s", Usage, Usage2); exit(99);}
X	if (argv[optind][0]=='-' && argv[optind][1]=='\0') pad=stdin;
X	else if ((pad=fopen(argv[optind],"r"))==NULL) {
X		fprintf(stderr,"OTP: Can't Open %s\n", argv[optind]);
X		exit(97);
X	}
X	if (skipbytes>0) {
X		n = skipbytes;
X		/* if can't fseek, have to do it the old-fashioned way */
X		if (fseek(pad, (long) skipbytes, 0))
X			while(skipbytes-->0) (void) getc(pad);
X	}
X
X	if ((++optind)==argc) in=stdin;
X	else if ((in=fopen(argv[optind],"r"))==NULL) {
X		fprintf(stderr,"OTP: Can't Open File %s\n", argv[optind]);
X		exit(96);
X	}
X
X	/* read in the file, xor bytes with pad, output */
X	/* this could perfectly well be a subroutine,
X		but it's not obvious what is the correct use of 
X		multiple files - so do them one at a time or use cat. */
X	while ( (c=getc(in))!=EOF ) {
X		n++;
X		if ((p=getc(pad))==EOF ) {
X			if (reuseflag) {
X				if (fseek(pad, 0L,0)) {
X					fprintf(stderr, "OTP: fseek(pad) failed!\n");
X					exit(95);
X				} else if ((p=getc(pad))==EOF) {
X					fprintf(stderr, "OTP: rereading pad failed\n");
X					exit(94);
X				}
X			} else {
X				fprintf(stderr, "OTP: ran out of pad\n");
X				exit(93);
X			}
X		}
X		if (putchar(c^p)==EOF && ferror(stdout)) {
X			fprintf(stderr, "OTP: stdout failed\n");
X			exit(92);
X		}
X	}
X	fclose(in);
X
X	if (outputcount) fprintf(stderr,"%d\n",n);
X
X	/* write remaining pad to newpad if desired */
X	if (newpadname) {
X		while ( (c=getc(pad))!=EOF ) putc(c,newpad);
X		fclose(newpad);
X	}
X	fclose(pad);
X	return 0;
X}
!
Technical Details
Message-ID: <C6p0Jn.8C9@cbnewsh.cb.att.com>
Path: arc1-ca.pugleaf.net!wupost!uhog.mit.edu!xn.ll.mit.edu!ames!pacbell.com!att-out!cbnewsh!wcs

Show Full Headers
Complete Article Headers
Newsgroups: sci.crypt,alt.sources
Path: arc1-ca.pugleaf.net!wupost!uhog.mit.edu!xn.ll.mit.edu!ames!pacbell.com!att-out!cbnewsh!wcs
From: wcs@cbnewsh.cb.att.com (Bill Stewart 908-949-0705 erebus.att.com!wcs)
Subject: otp.c - one-time pad program
Organization: personal research and education
Date: Sat, 8 May 1993 05:28:32 GMT
Message-ID: <C6p0Jn.8C9@cbnewsh.cb.att.com>
Followup-To: sci.crypt
Lines: 124