Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

v38i010: circ - encrypted irc package, Part01/03

3 views
Skip to first unread message

Timothy Newsham

unread,
Jun 19, 1993, 3:30:21 AM6/19/93
to
Submitted-by: new...@wiliki.eng.hawaii.edu (Timothy Newsham)
Posting-number: Volume 38, Issue 10
Archive-name: circ/part01
Environment: C UNIX

The following (in uuencoded tar-Z format) is The first release (V1.0) of
the Circ package. It works in conjunction with the ircII client (chat
program: available at csd.bu.edu in pub/irc/clients)

The program allows for key management, key exchange and the exchange of
encrypted messages in real time over the IRC chat network.

The current version has been tested on Ultrix (decstation) and HPUX 9.0
(hp9000) machines. Previous versions have been tested on other
platforms, the code is mostly made up of STDIO routines and should
compile on most unix machines.

All code written by me is released into the public domain.

The code in the RSA and d3des directories were not authored by me but
are freely distributable.

****
Moderators note:
Circ was supplied to me as a single 127Kb shar file. Since this was too
large to post directly, I've split it into 3 separate issues. +Alec-
--
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: MANIFEST Circ Circ/README.old Circ/RSA Circ/RSA/conf.h
# Circ/d3des Circ/d3des/d3des.c Circ/pubkeys Circ/sock2.c
# Wrapped by alecm@uk-usenet on Sat Jun 19 08:26:20 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 1 (of 3)."'
if test -f 'MANIFEST' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(1445 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X File Name Archive # Description
X----------------------------------------------------------
XMANIFEST 1
XCirc 1
XCirc/LOG 3
XCirc/Makefile 3
XCirc/README 2
XCirc/README.old 1
XCirc/RSA 1
XCirc/RSA/MANIFEST 3
XCirc/RSA/Make.amiga 3
XCirc/RSA/Make.unix 3
XCirc/RSA/Makefile 3
XCirc/RSA/README 3
XCirc/RSA/README.english 3
XCirc/RSA/WARNING 3
XCirc/RSA/arith.c 2
XCirc/RSA/arith.h 3
XCirc/RSA/conf.h 1
XCirc/RSA/genprim.c 3
XCirc/RSA/genrsa.c 3
XCirc/RSA/makekey 3
XCirc/RSA/nio.c 2
XCirc/RSA/nio.h 3
XCirc/RSA/patchlevel.h 3
XCirc/RSA/prim.c 2
XCirc/RSA/prim.h 3
XCirc/RSA/rnd.c 3
XCirc/RSA/rnd.h 3
XCirc/RSA/rsa.c 2
XCirc/RSA/rsa.hdr 3
XCirc/RSA/test.c 3
XCirc/crypt.c 3
XCirc/crypt.irc 2
XCirc/crypt.irc2 3
XCirc/d3des 1
XCirc/d3des/d3des.c 1
XCirc/d3des/d3des.h 2
XCirc/d3des/main.c 3
XCirc/d3des/readme 3
XCirc/ignore.irc 3
XCirc/new.c 2
XCirc/pubkeys 1
XCirc/pubkeys/al 3
XCirc/sock.h 3
XCirc/sock2.c 1
XPOSTER 3
END_OF_FILE
if test 1445 -ne `wc -c <'MANIFEST'`; then
echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test ! -d 'Circ' ; then
echo shar: Creating directory \"'Circ'\"
mkdir 'Circ'
fi
if test -f 'Circ/README.old' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/README.old'\"
else
echo shar: Extracting \"'Circ/README.old'\" \(6652 characters\)
sed "s/^X//" >'Circ/README.old' <<'END_OF_FILE'
X
Xthis is a tinyirc client (client not written by me)
Xbut I added in encryption.. Right now encryption is
Xdone in DES for messages and RSA for key exchange.
X
XTo set it up, unarchive (you probably already did this)
Xthen type :
X (you should be in the 'irc' dir at this point)
X make sock
Xthis should make a program called 'sock'
X
Xnow you need to go into the RSA directory and make yourself
Xa keypair.
X
X cd RSA
X make genrsa
X make genprim
X genrsa
X
Xthis makes two files 'public' and 'secret'. You need to install
Xthese:
X mv secret ..
X mv public ../<yournick>
X cd ..
X
Xand give out your public key to everyone you want to talk to.
XThis lets them send their key to you.
X
XYou must send them your public key *BEFORE* you start talking
Xto them on irc. You can do this with mail or with /dcc on
Xa normal irc client, or any other way you wish.
X
XYou must also receive keys for the people you wish to talk to
X*BEFORE* running the program! These should be in the same
Xdirectory as 'sock' and have they same filename as the
Xother person's nickname. So by this point you should have:
X your friends key in a file named after their nickname
X your key in a file called 'secret'
X a binary named 'sock'
Xall in the same directory.
X
XI have supplied a number of public keys from me and my friends.
XThese are in the directory irc/pubkeys/*. If you wish to
Xuse any of them copy them into the same directory as you
Xhave 'sock' in:
X cp pubkeys/* .
X
Xrun sock:
X sock
X
Xjoin the same channel as your friend you wish to talk to:
X /join #channel
X
Xsend them your key, this lets them read any message typed by
Xyou (note you have to be in the same channel as them)
X /key <your friend>
X
Xyour friend will receive your key, and now everything you type
Xcan be read by him. In order to send your key to your friend
Xyou must have the file <your friend> in your directory that
Xis <your friend>'s public key. He must have the matching
Xsecret key in the file 'secret' in his directory. If your
Xfriend changes nick's and the filename of his key isnt the
Xsame as his nick you can specify the file:
X /key <your friend> <filename of his key>
X
X(note: this isnt working yet ^^^ will be fixed)
Xthats it! Everything you type is encrypted with the same key
Xwhich is chosen at random when you start up 'sock'. Every time
Xyou use sock a new key is used. Every time you want to talk to
Xa new person you have to send them your key. Anyone who has
Xyour key can read any of your messages, so if you dont want
Xpeople reading your messages dont give them your key. Everything
Xyou type is encrypted.
X
X
Xsome public keys are already provided in pubkeys/*
Xcopy them into current directory to use them.
X--------
XWeaknesses:
X
X (1) RSA key as created by 'genrsa' is not very long! It
X is crackable right now. This could be lengthened
X easily enough by modifying genrsa.c . The rest of
X the program doesnt care what length key is used.
X
X (2) You can send alot of garbage to someone's screen by
X sending out wrong key's and/or sending out bad
X data matching keys already aquired.
X possible solution: header inside of the encrypted
X data. 1 character would give a 1/256 chance of
X this attack working.
X
X (3) probably alot more I didnt think about.
X
X----------
XProtocol:
X
Xthere are two types of messages, one to send keys across
Xto other people, one to send across encrypted messages, all
Xmessages are sent to the current irc channel, not through messages
Xto individual people:
X
X SKPJACK:xxxx:yyyy:zzzzz
X xxxx - the nick name of the intended recipient
X yyyy - the serial number of the key being transfered
X zzzz - ascii encoded RSA data
X messages of this format are used to send private keys (DES
X keys) to the recipient, ie /key nick.
X Messages received are ignored if xxxxx isnt our current nick.
X
X CLIPPER:xxxx:yyyy
X xxxx - the serial number of the key used to encrypt
X yyyy - the ascii encoded crypted data (DES)
X messages of this format are used to send encrypted chat
X messages. Messages received are ignored if we dont have
X the key corresponding to the serial number.
X
X ascii coding: each byte is broken into 2 nybbles (4 bits)
X and sent across as two characters, the first nybble
X is sent as hi+'a' and the second is sent as lo+'A'
X so alternate characters are always upper then lower then
X upper case and so on. (byte = hi<<4 + lo)
X
X Keys are generated randomly and each key has a random
X 32 bit serial number associated with it. The program
X uses the serial number to decided which key to decrypt
X with. The program keeps all the keys it receives.
X All messages you type are sent with your key, all messages
X you receive are decoded with the key matching the serial
X number sent with it.
X
X your key and its serial number are generated as follows:
X srand(time(0)); <-- seed random with time
X pick 8 random chars into K
X L=encrypt(K,K) <-- encrypt K with key K
X serial = (int)L <-- use this as the serial number
X pick 8 random chars int M
X N=encrypt(M,K) <-- encrypt M with key K
X N is used as your private DES key
X serial is used to keep track of N
X
X this should thward attacks trying to guess N given
X serial and possibly a good guess of time(0);
X encrypt(a,b) means encrypt a with key b in DES
X-----
XCREDITS
X
XAlot of this software was not written by me, In fact my part
Xwas minimal. I stole code from the following people:
X
XThe basic IRC client (tinyIRC) by:
X Nathan Laredo - "Green"
X gt7...@prism.gatech.edu
X
X
XThe RSA package by: (email address is no longer valid)
X
X Martin Nicolay ( mar...@trillian.megalon.de )
X Fliederstr. 23
X 4100 Duisburg 1
X W-Germany
X
XI couldn't reach him via email. I got this package via
Xanon-ftp, I hope he doesnt mind use of it in this program.
X
X
XThe DES package (d3des):
X
X D3DES (V5.09) -
X
X A portable, public domain, version of the Data Encryption Standard.
X
X Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
X Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
X code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
X Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
X for humouring me on.
X
X Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
X (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
X
XHe says "public domain" and then later "Copyright". I assume
Xhe means "freely distributable, useable".
X
XIf any of you are out there thanx alot! Your code is much
Xappreciated.
X
END_OF_FILE
if test 6652 -ne `wc -c <'Circ/README.old'`; then
echo shar: \"'Circ/README.old'\" unpacked with wrong size!
fi
# end of 'Circ/README.old'
fi
if test ! -d 'Circ/RSA' ; then
echo shar: Creating directory \"'Circ/RSA'\"
mkdir 'Circ/RSA'
fi
if test -f 'Circ/RSA/conf.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/conf.h'\"
else
echo shar: Extracting \"'Circ/RSA/conf.h'\" \(2293 characters\)
sed "s/^X//" >'Circ/RSA/conf.h' <<'END_OF_FILE'
X/*******************************************************************************
X* *
X* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
X* *
X* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
X* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
X* verwendet werden. *
X* *
X* mar...@trillian.megalon.de *
X* *
X*******************************************************************************/
X
X#ifndef _conf_h_
X#define _conf_h_
X
Xtypedef unsigned short INT; /* muss MAXINT fassen */
Xtypedef unsigned long LONG; /* muss (MAXINT+1)^2 -1 fassen */
X
X#if defined( M_XENIX )
X#define P(x) x /* Funktions Prototypen an */
X#else
X#define P(x) () /* Funktions Prototypen aus */
X#endif
X
X/*
X * (MAXINT+1)-adic Zahlen
X */
X
X/*
X * MAXINT Maximale Zahl pro Elemenmt (muss int sein)
X * MAXBIT Maximales Bit von MAXINT
X * LOWBITS Anzahl der consekutiven low Bits von MAXINT
X * HIGHBIT Hoechsten Bit von MAXINT
X * TOINT muss (INT)( (x) % MAXINT) ergeben
X * MAXLEN Laenge der INT Array in jeder NUMBER
X */
X
X#define MAXINT 0xFFFF
X
X#if MAXINT == 99
X#define MAXBIT 7
X#define LOWBITS 2
X#endif
X#if MAXINT == 9
X#define MAXBIT 4
X#define LOWBITS 1
X#endif
X#if MAXINT == 1
X#define MAXBIT 1
X#endif
X#if MAXINT == 0xFF
X#define MAXBIT 8
X#define TOINT(x) ((INT)(x)) /* ACHTUNG !!!!! */
X#endif
X#if MAXINT == 0xFFFF
X#define MAXBIT 16
X#define TOINT(x) ((INT)(x)) /* ACHTUNG !!!!! */
X#endif
X
X#ifndef MAXBIT
X#include "<< ERROR: MAXBIT must be defined >>"
X#endif
X#ifndef LOWBITS
X#if MAXINT == (1 << MAXBIT) - 1
X#define LOWBITS MAXBIT
X#else
X#include "<< ERROR: LOWBITS must be defined >>"
X#endif
X#endif
X
X#define MAXLEN (300*8/(MAXBIT + 1))
X#define STRLEN (MAXLEN*MAXBIT/4)
X#define HIGHBIT (1 << (MAXBIT-1) )
X
X#if LOWBITS == MAXBIT
X#define DIVMAX1(x) ((x) >> MAXBIT)
X#define MODMAX1(x) ((x) & MAXINT)
X#define MULMAX1(x) ((x) << MAXBIT)
X#else
X#define DIVMAX1(x) ((x) / (MAXINT+1))
X#define MODMAX1(x) ((x) % (MAXINT+1))
X#define MULMAX1(x) ((x) * (unsigned)(MAXINT+1))
X#endif
X
X#ifndef TOINT
X#define TOINT(x) ((INT)MODMAX1(x))
X#endif
X
Xtypedef struct {
X int n_len; /* Hoechster benutzter Index */
X INT n_part[MAXLEN];
X} NUMBER;
X
X#define NUM0P ((NUMBER *)0) /* Abkuerzung */
X
X#endif
END_OF_FILE
if test 2293 -ne `wc -c <'Circ/RSA/conf.h'`; then
echo shar: \"'Circ/RSA/conf.h'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/conf.h'
fi
if test ! -d 'Circ/d3des' ; then
echo shar: Creating directory \"'Circ/d3des'\"
mkdir 'Circ/d3des'
fi
if test -f 'Circ/d3des/d3des.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/d3des/d3des.c'\"
else
echo shar: Extracting \"'Circ/d3des/d3des.c'\" \(20140 characters\)
sed "s/^X//" >'Circ/d3des/d3des.c' <<'END_OF_FILE'
X/* D3DES (V5.09) -
X *
X * A portable, public domain, version of the Data Encryption Standard.
X *
X * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
X * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
X * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
X * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
X * for humouring me on.
X *
X * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
X * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
X */
X
X#include "d3des.h"
X
Xstatic void scrunch(/* unsigned char *, unsigned long * */);
Xstatic void unscrun(/* unsigned long *, unsigned char * */);
Xstatic void desfunc(/* unsigned long *, unsigned long * */);
Xstatic void cookey(/* unsigned long * */);
X
Xstatic unsigned long KnL[32] = { 0L };
Xstatic unsigned long KnR[32] = { 0L };
Xstatic unsigned long Kn3[32] = { 0L };
Xstatic unsigned char Df_Key[24] = {
X 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
X 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
X 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 };
X
Xstatic unsigned short bytebit[8] = {
X 0200, 0100, 040, 020, 010, 04, 02, 01 };
X
Xstatic unsigned long bigbyte[24] = {
X 0x800000L, 0x400000L, 0x200000L, 0x100000L,
X 0x80000L, 0x40000L, 0x20000L, 0x10000L,
X 0x8000L, 0x4000L, 0x2000L, 0x1000L,
X 0x800L, 0x400L, 0x200L, 0x100L,
X 0x80L, 0x40L, 0x20L, 0x10L,
X 0x8L, 0x4L, 0x2L, 0x1L };
X
X/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
X
Xstatic unsigned char pc1[56] = {
X 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
X 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
X 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
X 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };
X
Xstatic unsigned char totrot[16] = {
X 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
X
Xstatic unsigned char pc2[48] = {
X 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
X 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
X 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
X 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
X
Xvoid deskey(key, edf) /* Thanks to James Gillogly & Phil Karn! */
Xunsigned char *key;
Xshort edf;
X{
X register int i, j, l, m, n;
X unsigned char pc1m[56], pcr[56];
X unsigned long kn[32];
X
X for ( j = 0; j < 56; j++ ) {
X l = pc1[j];
X m = l & 07;
X pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
X }
X for( i = 0; i < 16; i++ ) {
X if( edf == DE1 ) m = (15 - i) << 1;
X else m = i << 1;
X n = m + 1;
X kn[m] = kn[n] = 0L;
X for( j = 0; j < 28; j++ ) {
X l = j + totrot[i];
X if( l < 28 ) pcr[j] = pc1m[l];
X else pcr[j] = pc1m[l - 28];
X }
X for( j = 28; j < 56; j++ ) {
X l = j + totrot[i];
X if( l < 56 ) pcr[j] = pc1m[l];
X else pcr[j] = pc1m[l - 28];
X }
X for( j = 0; j < 24; j++ ) {
X if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
X if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
X }
X }
X cookey(kn);
X return;
X }
X
Xstatic void cookey(raw1)
Xregister unsigned long *raw1;
X{
X register unsigned long *cook, *raw0;
X unsigned long dough[32];
X register int i;
X
X cook = dough;
X for( i = 0; i < 16; i++, raw1++ ) {
X raw0 = raw1++;
X *cook = (*raw0 & 0x00fc0000L) << 6;
X *cook |= (*raw0 & 0x00000fc0L) << 10;
X *cook |= (*raw1 & 0x00fc0000L) >> 10;
X *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
X *cook = (*raw0 & 0x0003f000L) << 12;
X *cook |= (*raw0 & 0x0000003fL) << 16;
X *cook |= (*raw1 & 0x0003f000L) >> 4;
X *cook++ |= (*raw1 & 0x0000003fL);
X }
X usekey(dough);
X return;
X }
X
Xvoid cpkey(into)
Xregister unsigned long *into;
X{
X register unsigned long *from, *endp;
X
X from = KnL, endp = &KnL[32];
X while( from < endp ) *into++ = *from++;
X return;
X }
X
Xvoid usekey(from)
Xregister unsigned long *from;
X{
X register unsigned long *to, *endp;
X
X to = KnL, endp = &KnL[32];
X while( to < endp ) *to++ = *from++;
X return;
X }
X
Xvoid des(inblock, outblock)
Xunsigned char *inblock, *outblock;
X{
X unsigned long work[2];
X
X scrunch(inblock, work);
X desfunc(work, KnL);
X unscrun(work, outblock);
X return;
X }
X
Xstatic void scrunch(outof, into)
Xregister unsigned char *outof;
Xregister unsigned long *into;
X{
X *into = (*outof++ & 0xffL) << 24;
X *into |= (*outof++ & 0xffL) << 16;
X *into |= (*outof++ & 0xffL) << 8;
X *into++ |= (*outof++ & 0xffL);
X *into = (*outof++ & 0xffL) << 24;
X *into |= (*outof++ & 0xffL) << 16;
X *into |= (*outof++ & 0xffL) << 8;
X *into |= (*outof & 0xffL);
X return;
X }
X
Xstatic void unscrun(outof, into)
Xregister unsigned long *outof;
Xregister unsigned char *into;
X{
X *into++ = (*outof >> 24) & 0xffL;
X *into++ = (*outof >> 16) & 0xffL;
X *into++ = (*outof >> 8) & 0xffL;
X *into++ = *outof++ & 0xffL;
X *into++ = (*outof >> 24) & 0xffL;
X *into++ = (*outof >> 16) & 0xffL;
X *into++ = (*outof >> 8) & 0xffL;
X *into = *outof & 0xffL;
X return;
X }
X
Xstatic unsigned long SP1[64] = {
X 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
X 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
X 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
X 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
X 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
X 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
X 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
X 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
X 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
X 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
X 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
X 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
X 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
X 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
X 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
X 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
X
Xstatic unsigned long SP2[64] = {
X 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
X 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
X 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
X 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
X 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
X 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
X 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
X 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
X 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
X 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
X 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
X 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
X 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
X 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
X 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
X 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
X
Xstatic unsigned long SP3[64] = {
X 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
X 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
X 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
X 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
X 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
X 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
X 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
X 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
X 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
X 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
X 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
X 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
X 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
X 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
X 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
X 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
X
Xstatic unsigned long SP4[64] = {
X 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
X 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
X 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
X 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
X 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
X 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
X 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
X 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
X 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
X 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
X 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
X 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
X 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
X 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
X 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
X 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
X
Xstatic unsigned long SP5[64] = {
X 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
X 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
X 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
X 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
X 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
X 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
X 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
X 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
X 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
X 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
X 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
X 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
X 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
X 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
X 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
X 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
X
Xstatic unsigned long SP6[64] = {
X 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
X 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
X 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
X 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
X 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
X 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
X 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
X 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
X 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
X 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
X 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
X 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
X 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
X 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
X 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
X 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
X
Xstatic unsigned long SP7[64] = {
X 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
X 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
X 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
X 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
X 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
X 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
X 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
X 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
X 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
X 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
X 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
X 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
X 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
X 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
X 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
X 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
X
Xstatic unsigned long SP8[64] = {
X 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
X 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
X 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
X 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
X 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
X 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
X 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
X 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
X 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
X 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
X 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
X 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
X 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
X 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
X 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
X 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
X
Xstatic void desfunc(block, keys)
Xregister unsigned long *block, *keys;
X{
X register unsigned long fval, work, right, leftt;
X register int round;
X
X leftt = block[0];
X right = block[1];
X work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
X right ^= work;
X leftt ^= (work << 4);
X work = ((leftt >> 16) ^ right) & 0x0000ffffL;
X right ^= work;
X leftt ^= (work << 16);
X work = ((right >> 2) ^ leftt) & 0x33333333L;
X leftt ^= work;
X right ^= (work << 2);
X work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
X leftt ^= work;
X right ^= (work << 8);
X right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
X work = (leftt ^ right) & 0xaaaaaaaaL;
X leftt ^= work;
X right ^= work;
X leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
X
X for( round = 0; round < 8; round++ ) {
X work = (right << 28) | (right >> 4);
X work ^= *keys++;
X fval = SP7[ work & 0x3fL];
X fval |= SP5[(work >> 8) & 0x3fL];
X fval |= SP3[(work >> 16) & 0x3fL];
X fval |= SP1[(work >> 24) & 0x3fL];
X work = right ^ *keys++;
X fval |= SP8[ work & 0x3fL];
X fval |= SP6[(work >> 8) & 0x3fL];
X fval |= SP4[(work >> 16) & 0x3fL];
X fval |= SP2[(work >> 24) & 0x3fL];
X leftt ^= fval;
X work = (leftt << 28) | (leftt >> 4);
X work ^= *keys++;
X fval = SP7[ work & 0x3fL];
X fval |= SP5[(work >> 8) & 0x3fL];
X fval |= SP3[(work >> 16) & 0x3fL];
X fval |= SP1[(work >> 24) & 0x3fL];
X work = leftt ^ *keys++;
X fval |= SP8[ work & 0x3fL];
X fval |= SP6[(work >> 8) & 0x3fL];
X fval |= SP4[(work >> 16) & 0x3fL];
X fval |= SP2[(work >> 24) & 0x3fL];
X right ^= fval;
X }
X
X right = (right << 31) | (right >> 1);
X work = (leftt ^ right) & 0xaaaaaaaaL;
X leftt ^= work;
X right ^= work;
X leftt = (leftt << 31) | (leftt >> 1);
X work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
X right ^= work;
X leftt ^= (work << 8);
X work = ((leftt >> 2) ^ right) & 0x33333333L;
X right ^= work;
X leftt ^= (work << 2);
X work = ((right >> 16) ^ leftt) & 0x0000ffffL;
X leftt ^= work;
X right ^= (work << 16);
X work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
X leftt ^= work;
X right ^= (work << 4);
X *block++ = right;
X *block = leftt;
X return;
X }
X
X#ifdef D2_DES
X
Xvoid des2key(hexkey, mode) /* stomps on Kn3 too */
Xunsigned char *hexkey; /* unsigned char[16] */
Xshort mode;
X{
X short revmod;
X
X revmod = (mode == EN0) ? DE1 : EN0;
X deskey(&hexkey[8], revmod);
X cpkey(KnR);
X deskey(hexkey, mode);
X cpkey(Kn3); /* Kn3 = KnL */
X return;
X }
X
Xvoid Ddes(from, into)
Xunsigned char *from, *into; /* unsigned char[8] */
X{
X unsigned long work[2];
X
X scrunch(from, work);
X desfunc(work, KnL);
X desfunc(work, KnR);
X desfunc(work, Kn3);
X unscrun(work, into);
X return;
X }
X
Xvoid D2des(from, into)
Xunsigned char *from; /* unsigned char[16] */
Xunsigned char *into; /* unsigned char[16] */
X{
X unsigned long *right, *l1, swap;
X unsigned long leftt[2], bufR[2];
X
X right = bufR;
X l1 = &leftt[1];
X scrunch(from, leftt);
X scrunch(&from[8], right);
X desfunc(leftt, KnL);
X desfunc(right, KnL);
X swap = *l1;
X *l1 = *right;
X *right = swap;
X desfunc(leftt, KnR);
X desfunc(right, KnR);
X swap = *l1;
X *l1 = *right;
X *right = swap;
X desfunc(leftt, Kn3);
X desfunc(right, Kn3);
X unscrun(leftt, into);
X unscrun(right, &into[8]);
X return;
X }
X
Xvoid makekey(aptr, kptr)
Xregister char *aptr; /* NULL-terminated */
Xregister unsigned char *kptr; /* unsigned char[8] */
X{
X register unsigned char *store;
X register int first, i;
X unsigned long savek[96];
X
X cpDkey(savek);
X des2key(Df_Key, EN0);
X for( i = 0; i < 8; i++ ) kptr[i] = Df_Key[i];
X first = 1;
X while( (*aptr != '\0') || first ) {
X store = kptr;
X for( i = 0; i < 8 && (*aptr != '\0'); i++ ) {
X *store++ ^= *aptr & 0x7f;
X *aptr++ = '\0';
X }
X Ddes(kptr, kptr);
X first = 0;
X }
X useDkey(savek);
X return;
X }
X
Xvoid make2key(aptr, kptr)
Xregister char *aptr; /* NULL-terminated */
Xregister unsigned char *kptr; /* unsigned char[16] */
X{
X register unsigned char *store;
X register int first, i;
X unsigned long savek[96];
X
X cpDkey(savek);
X des2key(Df_Key, EN0);
X for( i = 0; i < 16; i++ ) kptr[i] = Df_Key[i];
X first = 1;
X while( (*aptr != '\0') || first ) {
X store = kptr;
X for( i = 0; i < 16 && (*aptr != '\0'); i++ ) {
X *store++ ^= *aptr & 0x7f;
X *aptr++ = '\0';
X }
X D2des(kptr, kptr);
X first = 0;
X }
X useDkey(savek);
X return;
X }
X
X#ifndef D3_DES /* D2_DES only */
X#ifdef D2_DES /* iff D2_DES! */
X
Xvoid cp2key(into)
Xregister unsigned long *into; /* unsigned long[64] */
X{
X register unsigned long *from, *endp;
X
X cpkey(into);
X into = &into[32];
X from = KnR, endp = &KnR[32];
X while( from < endp ) *into++ = *from++;
X return;
X }
X
Xvoid use2key(from) /* stomps on Kn3 too */
Xregister unsigned long *from; /* unsigned long[64] */
X{
X register unsigned long *to, *endp;
X
X usekey(from);
X from = &from[32];
X to = KnR, endp = &KnR[32];
X while( to < endp ) *to++ = *from++;
X cpkey(Kn3); /* Kn3 = KnL */
X return;
X }
X
X#endif /* iff D2_DES */
X#else /* D3_DES too */
X
Xstatic void D3des(/* unsigned char *, unsigned char * */);
X
Xvoid des3key(hexkey, mode)
Xunsigned char *hexkey; /* unsigned char[24] */
Xshort mode;
X{
X unsigned char *first, *third;
X short revmod;
X
X if( mode == EN0 ) {
X revmod = DE1;
X first = hexkey;
X third = &hexkey[16];
X }
X else {
X revmod = EN0;
X first = &hexkey[16];
X third = hexkey;
X }
X deskey(&hexkey[8], revmod);
X cpkey(KnR);
X deskey(third, mode);
X cpkey(Kn3);
X deskey(first, mode);
X return;
X }
X
Xvoid cp3key(into)
Xregister unsigned long *into; /* unsigned long[96] */
X{
X register unsigned long *from, *endp;
X
X cpkey(into);
X into = &into[32];
X from = KnR, endp = &KnR[32];
X while( from < endp ) *into++ = *from++;
X from = Kn3, endp = &Kn3[32];
X while( from < endp ) *into++ = *from++;
X return;
X }
X
Xvoid use3key(from)
Xregister unsigned long *from; /* unsigned long[96] */
X{
X register unsigned long *to, *endp;
X
X usekey(from);
X from = &from[32];
X to = KnR, endp = &KnR[32];
X while( to < endp ) *to++ = *from++;
X to = Kn3, endp = &Kn3[32];
X while( to < endp ) *to++ = *from++;
X return;
X }
X
Xstatic void D3des(from, into) /* amateur theatrics */
Xunsigned char *from; /* unsigned char[24] */
Xunsigned char *into; /* unsigned char[24] */
X{
X unsigned long swap, leftt[2], middl[2], right[2];
X
X scrunch(from, leftt);
X scrunch(&from[8], middl);
X scrunch(&from[16], right);
X desfunc(leftt, KnL);
X desfunc(middl, KnL);
X desfunc(right, KnL);
X swap = leftt[1];
X leftt[1] = middl[0];
X middl[0] = swap;
X swap = middl[1];
X middl[1] = right[0];
X right[0] = swap;
X desfunc(leftt, KnR);
X desfunc(middl, KnR);
X desfunc(right, KnR);
X swap = leftt[1];
X leftt[1] = middl[0];
X middl[0] = swap;
X swap = middl[1];
X middl[1] = right[0];
X right[0] = swap;
X desfunc(leftt, Kn3);
X desfunc(middl, Kn3);
X desfunc(right, Kn3);
X unscrun(leftt, into);
X unscrun(middl, &into[8]);
X unscrun(right, &into[16]);
X return;
X }
X
Xvoid make3key(aptr, kptr)
Xregister char *aptr; /* NULL-terminated */
Xregister unsigned char *kptr; /* unsigned char[24] */
X{
X register unsigned char *store;
X register int first, i;
X unsigned long savek[96];
X
X cp3key(savek);
X des3key(Df_Key, EN0);
X for( i = 0; i < 24; i++ ) kptr[i] = Df_Key[i];
X first = 1;
X while( (*aptr != '\0') || first ) {
X store = kptr;
X for( i = 0; i < 24 && (*aptr != '\0'); i++ ) {
X *store++ ^= *aptr & 0x7f;
X *aptr++ = '\0';
X }
X D3des(kptr, kptr);
X first = 0;
X }
X use3key(savek);
X return;
X }
X
X#endif /* D3_DES */
X#endif /* D2_DES */
X
X/* Validation sets:
X *
X * Single-length key, single-length plaintext -
X * Key : 0123 4567 89ab cdef
X * Plain : 0123 4567 89ab cde7
X * Cipher : c957 4425 6a5e d31d
X *
X * Double-length key, single-length plaintext -
X * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
X * Plain : 0123 4567 89ab cde7
X * Cipher : 7f1d 0a77 826b 8aff
X *
X * Double-length key, double-length plaintext -
X * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
X * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
X * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
X *
X * Triple-length key, single-length plaintext -
X * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
X * Plain : 0123 4567 89ab cde7
X * Cipher : de0b 7c06 ae5e 0ed5
X *
X * Triple-length key, double-length plaintext -
X * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
X * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
X * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5
X *
X * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
X **********************************************************************/
END_OF_FILE
if test 20140 -ne `wc -c <'Circ/d3des/d3des.c'`; then
echo shar: \"'Circ/d3des/d3des.c'\" unpacked with wrong size!
fi
# end of 'Circ/d3des/d3des.c'
fi
if test ! -d 'Circ/pubkeys' ; then
echo shar: Creating directory \"'Circ/pubkeys'\"
mkdir 'Circ/pubkeys'
fi
if test -f 'Circ/sock2.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/sock2.c'\"
else
echo shar: Extracting \"'Circ/sock2.c'\" \(17161 characters\)
sed "s/^X//" >'Circ/sock2.c' <<'END_OF_FILE'
X/* Nathan Laredo - "Green" - gt7...@prism.gatech.edu */
X/* mini-client, semi-raw input, formatted output */
X/* supports none of pre-2.7.2 protocol in formatting */
X/* the documentation takes up lots of the space here */
X
X/* modified Apr 21, 1993 "xxx". Changed to a special- */
X/* purpose encryption program */
X
X#include <stdio.h>
X#ifdef pyr
X#include <strings.h>
X#else
X#include <string.h>
X#endif
X#include <errno.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include <sys/socket.h>
X#include <netinet/in.h>
X#include <netdb.h>
X#include "sock.h"
X
Xchar *encode(),*decode();
Xchar *en_crypt(),*de_crypt(); /* external, in crypt.c */
X
X#define KEYLEN 24+1
X#define MAXKEYS 30
X#define HUGE 1024
X#define SECKEY "secret" /* secret key file, should be a variable */
X
Xchar keys[MAXKEYS][KEYLEN]; /* keys */
Xunsigned int sers[MAXKEYS]; /* serial numbers */
X
Xint s,d; /* IRC socket, DCC socket */
Xchar buf[512]; /* global text data buffer */
Xchar curchan[256]; /* current active channel */
Xchar localhost[64]; /* the local machine's name */
Xint dcchost,dccsock; /* for implementing DCC */
Xchar dccbuf[2048]; /* buffer for incomming */
Xchar dccname[512]; /* filename for dcc transfer */
Xunsigned long int dcclength; /* dcc reply/check */
Xchar inputbuf[512]; /* buffer for user input */
Xchar IRCNAME[32]; /* storage for current nick */
Xfd_set readfs, orig;
Xint sok=1; /* socket ok flag */
X
Xchar *token[1024]; /* worst case: 1 2 3 4 5 .. etc 512 chars */
X
X/* casecmp(a,b)
X a,b - null terminated strings.
X does a non-case sensitive compare
X */
X#define To_lower(a) (isupper(a)?tolower(a):(a))
X
Xcasecmp(a,b)
Xchar *a,*b;
X{
X while(*a && *b)
X if(To_lower(*a) != To_lower(*b))
X return (*b-*a); /* doesnt really matter if they are diff cases here*/
X else {
X a++,b++;
X }
X return(0);
X}
X
X/* asctobin(str,len)
X str - ascii string (null terminated)
X len - int *, RETURN length of binary block
X returns: char * to binary block data in static storage.
X coding:
X high nybble - 'a'=0 to 'p'=15
X low nybble - 'A'=0 to 'P'=15
X NULL returned for bad encoding.
X */
Xchar *asctobin(str,len)
Xchar *str;
Xint *len;
X{
X static char buf[HUGE];
X char a,b;
X int i;
X
X for(i=0;;) {
X a=*str++;
X while(a==' '||a=='\n') a=*str++;
X b=*str++;
X if(a=='\0' || b=='\0') {
X *len=i;
X return(buf);
X }
X if (a<'a'||a>'p' || b<'A'||b>'P')
X return(0);
X buf[i++] = ((a-'a')<<4)|(b-'A');
X }
X}
X
X/* bintoasc(str,len)
X str - a pointer to a binary block
X len - length of binary block in bytes
X return - char * to a string that is ascii, null-terminated
X coding -
X high nybble 'a'=0 to 'p'=15
X low nybble 'A'=0 to 'P'=15
X */
Xchar *bintoasc(str,len)
Xint len;
Xchar *str;
X{
X static char buf[HUGE];
X int i;
X
X for(i=0;len-- >0;str++) {
X buf[i++]=((*str&0xf0)>>4) + 'a';
X buf[i++]=(*str&0xf) + 'A';
X }
X buf[i]='\0';
X return(buf);
X}
X
X/* encode(str)
X str - an ascii null-terminated string
X returned - char * an encoded null terminated ascii string
X encoding:
X CLIPPER:xxxx:yyyyyyyyyyyyy
X xxxx - serial number of key used
X yyyyy- ascii coded, encrypted text message
X */
Xchar *encode(str)
Xchar *str;
X{
X int l,ser,a;
X static char buf[HUGE];
X char *p;
X
X set_key(keys[0]); /* use our key and our serial number */
X a=strlen(str)-1;
X if(str[a]=='\n') str[a]='\0';
X str[a++]='\0';
X p=en_crypt(str ,a,&l);
X sprintf(buf,"CLIPPER:%d:",sers[0]);
X strcat(buf,bintoasc(p,l));
X strcat(buf,"\n");
X return(buf);
X}
X
X/* decode(ar,len)
X ar - array of words like argv[]
X len - number of words, like argc
X return - char * to a decoded ascii null-termianted string
X coding: see encode()
X error codes are returned as human readable strings.
X
X CLIPPER:xxxx:yyyyyy
X x - ascii serial number
X y - ascii encoded binary data, crypted
X SKPJACK:xxxx:yyyy:zzzz
X x - nick name of destination
X y - serial number of key being received
X z - ascii encoded binary data, encrypted with rsa
X in 'nick's public key , contains the key
X needed to read messages from nick
X */
Xchar *decode(ar,len)
Xchar *ar[];
Xint len;
X{
X char *p; /* lots of chars */
X static char buf[HUGE];
X int i,ser,l,a,itsakey=0;
X
X buf[0]='\0';
X for(i=0;i<len;i++) { /* put it into a single string */
X strcat(buf,ar[i]);
X strcat(buf," "); /* spaces seperate tokens */
X }
X if(strncmp(buf,"SKPJACK:",8)==0)
X itsakey=1; /* someones sending a key */
X else if(strncmp(buf,"CLIPPER:",8))
X return(0); /* not encoded */
X for(i=8;buf[i]!=':'&&buf[i]!='\0';i++); /* jump past ser # */
X if(buf[i]!=':') {
X return("*Badly Formed*\n");
X }
X buf[i++]='\0';
X ser=atoi(buf+8); /* this is ser # */
X
X if(itsakey && casecmp(buf+8,IRCNAME)==0) { /* new key sent to us */
X ser=atoi(buf+i);
X for(;buf[i]!=':'&&buf[i]!='\0';i++) ;
X if(buf[i++]!=':') return("*Newkey: badly formed*");
X p=asctobin(buf+i,&len);
X if(!p)
X return("*new key: bad coding*");
X memcpy(buf,p,len); /* copy binary data */
X if(do_rsa(SECKEY,buf,len,HUGE)<0)
X return("*new key: couldnt decrypt (rsa)*");
X for(i=0;i<MAXKEYS;i++)
X if(sers[i]==0 || sers[i]==ser) break;
X if(i==MAXKEYS) return ("*new key: out of table entries*");
X /* *never* receive a key we already have */
X /* this could be a trick */
X if(sers[i]==ser) return("*new key: already have it!*");
X sers[i]= ser;
X memcpy(keys[i],buf,KEYLEN);
X return("*New Key installed*");
X }
Xif (itsakey) printf("Saw key for %s\n",buf+8);
X if (itsakey) return("*Key received, but not for us*");
X
X /* else its a message , try to decode */
X a=key(ser); /* find the key */
X if(a==-1) return("*Dont Have the Key*\n");
X set_key(keys[a]);
X p=asctobin(buf+i,&len); /* decrypt it */
X if(!p) return("*Bad Encoding*");
X sprintf(buf,"<E> %s",de_crypt(p,len,&l));
X return(buf);
X}
X
X/* key(ser)
X ser = serial number
X returned - index to the key with serial number ser, else -1
X */
Xint key(ser)
Xint ser;
X{
X int i;
X
X for(i=0;i<MAXKEYS;i++)
X if(ser == sers[i]) return(i);
X return(-1);
X}
X
X/* sendkey(line)
X line - char *, everything after /key on the command line
X parsed to 'nick' and the optional 'filename'
X filename is set to nick if it doesnt exist.
X encodes our key and serial number with nick's public
X key and sends it over the current channel for him
X to receive
X */
Xsendkey(line) /* handle /key nick [filename] */
Xchar *line;
X{
X char *file,*nick,*p;
X char buf[1024];
X int len;
X
X while(*line==' ') line++;
X nick=line;
X while(*line!=' '&&*line!='\0'&&*line!='\n') line++;
X if(*line=='\n') *line='\0';
X if(*line=='\0')
X file=nick;
X else {
X *line++='\0';
X file=line;
X while(*line!=' '&&*line!='\0'&&*line!='\n') line++;
X *line='\0';
X }
X if(*nick=='\0') {
X printf("*ERROR* nick missing, /key nick [file]");
X return;
X }
X
X memcpy(buf,keys[0],KEYLEN);
X len=do_rsa(file,buf,KEYLEN,1024);
X if(len<0) {
X printf("*ERROR* dont have public key for %s\n",file);
X return; /* couldnt send it, RSA failed */
X }
X p=bintoasc(buf,len);
X sprintf(buf,"PRIVMSG %s SKPJACK:%s:%d:%s\n",
X curchan,nick,sers[0],p);
X writeln(buf); /* send it to irc */
X}
X
X
Xint call_socket(hostname)
X char *hostname;
X{
X struct sockaddr_in sa;
X struct hostent *hp;
X int a, s;
X
X bzero(&sa, sizeof(sa));
X sa.sin_family = AF_INET;
X sa.sin_addr.s_addr = inet_addr(hostname);
X if (sa.sin_addr.s_addr ==-1) {
X if ((hp=gethostbyname(hostname))==NULL) {
X errno=ECONNREFUSED;
X return(-1);
X }
X sa.sin_family = hp->h_addrtype;
X bcopy(hp->h_addr, (char *)&sa.sin_addr, hp->h_length);
X }
X sa.sin_port = htons((u_short)DEFAULTPORT);
X
X if((s=socket(sa.sin_family, SOCK_STREAM, 0)) < 0)
X return(-1);
X if(connect(s, &sa, sizeof(sa)) < 0) {
X close(s);
X return(-1);
X }
X return(s);
X}
X
Xint dcc_socket(host,sock)
Xunsigned long int host;
Xint sock;
X{
Xstruct sockaddr_in sa;
Xint a, d;
X
X bzero(&sa, sizeof(sa));
X bcopy(&host, (char *)&sa.sin_addr, sizeof(host));
X sa.sin_family = AF_INET;
X sa.sin_port = htons((u_short)sock);
X
X if((d=socket(PF_INET, SOCK_STREAM, 0)) < 0)
X return(-1);
X if(connect(s, &sa, sizeof(sa)) < 0) {
X close(d);
X return(-1);
X }
Xreturn(d);
X}
X
X
Xint readln(buf)
X char *buf;
X{
X int to=0;
X char c;
X do { /* will never overflow 'cause
X server can't send more than 512 bytes */
X if(read(s, &c, 1)<1) return(0);
X buf[to++] = c;
X } while (c != '\n');
X buf[to-1] = '\0';
X return(1);
X}
X
Xint writeln(buf)
X char *buf;
X{
X int to=0;
X if( write(s, buf, strlen(buf)) < to )
X return(0);
X return(1);
X}
X
Xint dcc_getblock(so,fi)
Xchar *so,*fi;
X{ char r;
X if (r=read(so, dccbuf, 2048)) {
X dcclength += r;
X printf("[%08x]",dcclength);
X write(so, htons((unsigned long int) dcclength), sizeof(dcclength));
X write(fi, dccbuf, r);
X return(1);
X } /* if block is still there */
X close(fi); close(so);
X printf("DCC successful!\n");
X return (0); /* done */
X}
X
Xdojoin() /* had to separate because the language is dumb */
X{
X if(strcmp(token[0],IRCNAME)==0) {
X printf("*** Current channel is now %s",token[2]);
X strcpy(curchan,token[2]);
X } /* case change current channel (nick=ircnick) */
X else printf("*** %s has joined channel %s",token[0],token[2]);
X} /* end of dojoin */
X
Xdopart() /* see above */
X{
X if(strcmp(token[0],IRCNAME)==0) {
X if(strcmp(curchan,token[2])==0) { /* yur leaving your curent channel */
X printf("*** Current channel is now invalid until you use join");
X/* you could probably implement a get last channel in if you wanted */
X strcpy(curchan,"=invalid"); /* literally :-) */
X } /* case invalidate current channel */
X } /* damn I hate this */
X else printf("*** %s has left channel %s",token[0],token[2]);
X} /* end of part garbage */
X
Xdonick()
X{
Xif(strcmp(token[0],IRCNAME)==0) { strcpy(IRCNAME,token[2]);
X printf("*** You have changed your nickname to %s", token[2]);
X } /* if you're doing this to yourself */
X else printf("*** %s is now known as %s",token[0],token[2]);
X} /* I hate this language - if only it could read my mind */
X
Xdoprivmsg(tokencount)
Xint tokencount;
X{ int i;
X char *p;
X
X if(*(++token[3])=='\01') /* ctcp reply */
X printf("*** CTCP MESSAGE FROM %s: ",token[0]);
X else {
X printf("<%s-%s> ",token[0],token[2]);
X/* decrypt here */
X p=decode(token+3,tokencount-3);
X if(p) { /* if not encoded drop through */
X printf("%s",p);
X return;
X }
X }
X for(i=3;i<tokencount; i++) printf("%s ",token[i]);
X
X/* DO CTCP GOES HERE (INCLUDES DCC) */
X} /* privmsg */
X
Xdonotice(tokencount)
Xint tokencount;
X{ int i;
X if(*(++token[3])=='\01') /* ctcp reply */
X printf("*** CTCP REPLY FROM %s: ",token[0]);
X /* if there's a . in nick we KNOW it's not a user */
X else if (strchr(token[0],'.')==0) printf("-%s- ",token[0]);
X for(i=3;i<tokencount; i++) printf("%s ",token[i]);
X} /* notice */
X
Xint spitout(servstr) /* filter line to make more pleasing and spit out */
Xchar *servstr;
X{ int i;
X char *temp;
X int tokencount=0;
X if (strncmp(servstr,"PING",4)==0) { /* make pings/pongs transparent */
X temp=strncpy(servstr,"PO",2);
X return(writeln(strcat(temp,"\n"))); /* needs new line-gone before */
X }
X /* tokenize */
X token[0]=strtok(servstr," "); tokencount++;
X while(token[tokencount++]=strtok(NULL, " "));
X tokencount -= 1; /* need to fix for newline */
X /* each token contains exactly one word, and only one now */
X if(*token[0] != ':') { /* notice message from server usually */
X for(i=0;i<tokencount; i++) printf("%s ",token[i]);
X printf("\n");
X return(0);
X } /* if first char not : */
X else token[0]++; /* point at next char past colon */
X if(temp=strchr(token[0],'!')) *temp='\0'; /* strip address if there */
X
X/* main parsing stuff - follows parse.c in ircII pretty closely */
X
X if(strcmp(token[1],"PRIVMSG")==0) doprivmsg(tokencount);
X else if(strcmp(token[1],"NOTICE")==0) donotice(tokencount);
X else if(strlen(token[1])==3) /* server message, just print */
X for(i=3;i<tokencount; i++) printf("%s ",token[i]);
X else if(strcmp(token[1],"JOIN")==0) dojoin();
X else if(strcmp(token[1],"PART")==0) dopart();
X else if(strcmp(token[1],"QUIT")==0) {
X printf("*** signoff (%s)",token[0]);
X for(i=2;i<tokencount; i++) printf(" %s",token[i]);
X } /* if someone's leaving irc */
X else if(strcmp(token[1],"TOPIC")==0) {
X printf("*** %s has changed the topic on %s to",token[0],token[2]);
X for(i=3;i<tokencount; i++) printf(" %s",token[i]); }
X else if(strcmp(token[1],"INVITE")==0)
X printf("*** You have been invited to join channel %s by %s",token[2],
X token[0]);
X else if(strcmp(token[1],"NICK")==0) donick();
X else if(strcmp(token[1],"KILL")==0) /* Hmmm, never got one, but hell */
X printf("*** %s killed by %s",token[2],token[0]);
X else if(strcmp(token[1],"MODE")==0) /* well, there are mode changes */
X printf("*** Mode change on %s by %s to %s",token[2],token[0],token[3]);
X else if(strcmp(token[1],"KICK")==0)
X printf("*** %s has kicked %s from %s",token[0], token[2], token[3]);
X else if(strncmp(token[1],"ERROR",5)==0) {
X printf("*** ERROR:");
X for(i=2;i<tokencount; i++) printf(" %s",token[i]); }
X else /* if all else fails */
X { printf("***"); for(i=0;i<tokencount; i++) printf(" %s",token[i]); }
Xputchar('\n'); /* if you get a blank line at this point this code sucks */
Xreturn(0);
X}
X
Xint dottyinput()
X{
X char c;
X int to=0;
X do {
X if(read(1, &c, 1)<1) return(0);
X inputbuf[to++] = c;
X } while (c != '\n');
X inputbuf[to] = '\0';
X if (inputbuf[0]==COMMANDCHAR){
X if(strncmp(inputbuf+1,"key",3)==0)
X sendkey(inputbuf+4);
X else
X writeln(inputbuf+1);
X }
X else {
X
X/* encrypt here */
X sprintf(buf,"PRIVMSG %s %s",curchan,encode(inputbuf));
X writeln(buf);
X } /* no cmd character tried default */
X return(1);
X}
X
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X char hostname[64];
X char *logfile=NULL;
X int c, errflag;
X extern int optind, opterr;
X extern char *optarg;
X char line[512];
X
X int i;
X
X /* pick random 8 bit key -> K */
X /* encrypt crypt(K,K) -> serial number */
X /* pick random 8 bits L */
X /* encrypt crypt(L,K) -> our DES key */
X srand(time(0));
X for(i=0;i<KEYLEN;i++)
X keys[0][i]= (char)((rand()&0xff00)>>8);
X set_key(keys[0]);
X en_crypt(keys[0],KEYLEN,&i);
X sers[0] = (int) *((int *)keys[0]); /* pick serial number */
X /* if(sers[0]<0) sers[0]=-sers[0]; /* problem with negative ser #'s */
X for(i=0;i<KEYLEN;i++)
X keys[0][i]= (char)((rand()&0xff00)>>8);
X en_crypt(keys[0],KEYLEN,&i);
X
X if(getenv("IRCNICK")==NULL || getenv("LOGNAME")==NULL ||
X getenv("IRCNAME")==NULL) {
X printf("The following settings in your environment are not set properly:\n");
X if (getenv("IRCNICK")==NULL) printf("IRCNICK should be set with a nick\n");
X if (getenv("LOGNAME")==NULL) printf("LOGNAME should contain user id\n");
X if (getenv("IRCNAME")==NULL) printf("IRCNAME should contain real name\n");
X exit(0);
X }
Xif(argc>1) { /* assume only one param, hostname */
X if (strchr(argv[1],'.')==0) { /* shouldn't a host have a period? */
X fprintf(stderr,"usage: %s ircservername initialchannel\n", argv[0]);
X exit(0); }
X strcpy(hostname,argv[1]); }
X else strcpy(hostname,DEFAULTSERVER);
X gethostname(localhost, 64);
X if ((s=call_socket(hostname))==-1) {
X fprintf(stderr, "Could not connect to %s, aborting\n", hostname);
X exit(0);
X }
X sprintf(buf, "NICK %s\n", getenv("IRCNICK"));
X writeln(buf);
X sprintf(buf, "USER %s 1 1 %s\n", getenv("LOGNAME"), getenv("IRCNAME"));
X writeln(buf);
X strcpy(curchan,"=invalid");
X strncpy(IRCNAME,getenv("IRCNICK"),sizeof(IRCNAME));
X if(argc>2) /* well we'll call this the channel to join */
X { sprintf(buf, "JOIN %s\n", argv[2]); writeln(buf); }
X if(argc>3) { /* assume you don't know what the hell you want */
X fprintf(stderr,"usage: %s ircservername initialchannel\n", argv[0]);
X exit(0); }
X FD_ZERO(&readfs);
X FD_SET(s,&readfs);
X FD_SET(1,&readfs);
X orig = readfs;
X while(sok) {
X/* notice how when one character is there, we assume a whole line is
X waiting for us to read. This is because we're doing cooked i/o to
X keep resources minimal */
X if(select(FD_SETSIZE, &readfs, NULL, NULL, NULL)) {
X if(FD_ISSET(1,&readfs)) if(!dottyinput()) return(1);
X if(FD_ISSET(s,&readfs)) {
X sok = readln(line);
X if (sok) spitout(line);
X } /* if s */
X } /* if select */
Xreadfs = orig;
X}
X return(1); /* assume that these files will be properly closed */
X}
END_OF_FILE
if test 17161 -ne `wc -c <'Circ/sock2.c'`; then
echo shar: \"'Circ/sock2.c'\" unpacked with wrong size!
fi
# end of 'Circ/sock2.c'
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 3 archives.
rm -f ark[1-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...

Timothy Newsham

unread,
Jun 19, 1993, 3:31:05 AM6/19/93
to
Submitted-by: new...@wiliki.eng.hawaii.edu (Timothy Newsham)
Posting-number: Volume 38, Issue 11
Archive-name: circ/part02
Environment: C UNIX

#! /bin/sh


# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.

# Contents: Circ/README Circ/RSA/arith.c Circ/RSA/nio.c
# Circ/RSA/prim.c Circ/RSA/rsa.c Circ/crypt.irc Circ/d3des/d3des.h
# Circ/new.c
# Wrapped by alecm@uk-usenet on Sat Jun 19 08:26:21 1993


PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 2 (of 3)."'
if test -f 'Circ/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/README'\"
else
echo shar: Extracting \"'Circ/README'\" \(5888 characters\)
sed "s/^X//" >'Circ/README' <<'END_OF_FILE'
X
XThis is an encrypted protocol that runs on top of IRC.
XThis version has a binary and an ircII script, and is
Xdesigned to run within IRC-II (irc clients).
X
XThis is release 1.0, the first general release. It is
Xincompatible to pre-release versions since the encryption
Xwas changed from DES to triple-DES. Also RSA keys must
Xbe longer than the ones created by the last version since
XTriple-DES keys are three times longer (so any old RSA
Xkeys are no longer any good).
X
XIf you want a tiny (stand-alone) client, read README.old
X
XGENERAL DESCRIPTION:
X---------------------
X
XInterfaces to ircII clients through the scripting language.
XEncrypts messages in Triple-DES.
XKeeps a table of Triple-DES keys.
XAllows for key exchange using the RSA encryption algorithm.
X
X
XHOW DO I SET IT UP?
X--------------------
X
X1. set-up your ircII client. Hopefully you already have
X this done
X
X2. compile all the binaries you will need:
X make all
X this will make the binary 'new' and generate your
X keys. Alternatively you can do them seperately:
X make new
X and
X make keys
X this may come in handy later if you wish to make a new
X RSA key, or if you wish to remake 'new' without changing
X your key.
X The file names used for your keys will be printed to your
X screen: "secret" for your secret key and another one named
X after your login or $IRCNAME (or "public" if the script
X cant determine either of those).
X
X3. Send your public key (named after your IRCNICK ) to your
X friends, heck even your enemies... doesnt hurt. Security
X does not depend much on this key (having this key shouldnt
X help the bad guys decrypt your messages). You can do this
X a number of ways: mail and '/dcc send' (within irc) are
X two of them.
X
X4. If you have a directory with your friends public keys
X set up an environmental pointing to them. This is
X done differently in CSH and SH :
X CSH% setenv KEYDIR /path/to/key/dir
X SH$ KEYDIR=/path/to/key/dir
X SH$ export KEYDIR
X alternatively put all your keys into a directory named
X "pubkeys" under the current directory. This directory
X always gets checked.
X
X5. Start-up irc now.
X
X6. Once in load up the script file. While loading the script
X you *must* be in the same directory as the binary 'new'
X the files 'secret' and all the secret keys! You can
X do this by either starting IRC from within the directory,
X or using the IRCII command /cd directory to get there.
X
X /load crypt.irc
X
X (note due to discrepencies in scripting in newer IRCII
X clients there are two versions of the script. Users
X using older ircII clients should use "crypt.irc" and
X those using newer (I believe 2.2.4 and onward) should
X use "crypt.irc2" )
X
X7. You should now be ready to encrypt and receive encrypted
X messages. Join a channel with someone else who has encryption
X and send them your key:
X
X /join #crypto
X /key myfriend
X
X this will send them your (random) DES key and allow them
X to see you. When you send them encrypted messages now,
X it will be automatically decrypted on their end and put up
X on the screen with an E before it.
X
X To send an encrypted message to the current channel type
X /e message here
X Or to make all your messages encrypted:
X /crypt
X To undo that:
X /plain
X And to send plaintext messages while encrypted:
X /p message here
X To send encrypted messages:
X /emsg nick message here
X
XFor details on what goes on behind the scene, the protocol
Xspecifics, or anything more detailed than this, see
XREADME.old which refers to a previous (standalone) encrypted
Xclient.
X
X
XWATCH OUT FOR:
X--------------
X
X- if you dont want someone to see you: DONT /KEY THEIRNICK !!!
X anyone you /key can read what you type
X
X- if you want someone to see you: /key theirnick !!!
X while encrypted, only the people you have /key'ed can
X see what you type. (And only then if they have the
X client)
X
X- dont piss people off! Anyone who does not run this program
X will see *alot* of garbage on their screen while you are
X sending encrypted messages to their channel! Please keep
X encryption in channels were people have encrypted clients.
X
X- the /crypt and /plain alias's use /query. If you are /query'ing
X someone and type either /crypt or /plain it will cancel your
X old /query. If you are encrypted (/crypt) and you /query
X someone else it will take yout out of auto-encryption. You
X can tell when you are encrypted by the [query: %crypt] in
X the title bar (if you have a title bar :)
X
X- only messages that are sent with "/e" or "/emsg" or while
X in "/crypt" mode are encrypted. Not everything you type
X after "/load crypt.irc" is encrypted.
X
X- If you wish to reload the program, or stop it use /die. This
X will stop the server program ('new') and remove any /query's
X that are in effect (in case you where /crypt'ed).
X
X
XWEAKNESSES:
X-----------
X
XSecurity of all messages you type in any one session depends
Xon the secrecy of your Triple-DES key and the security of
Xthat algorithm.
X
XSecurity of any key exchanges depends on the RSA algorithm and
Xthe secrecy of your "secret" secret key file. The keys generated
Xare aproximately 512 bits long, but the random numbers are all
Xtaken from the rand() system call. This is a possible weakness.
X
XAs usual anything you do on another persons machine is not totally
Xsecure. Root can peek at your core image which has all the
Xsecret keys as well as some extra plaintext laying around. Root
Xcould go as far as to watch the pipe between irc and the 'new'
Xbinary. If you are dialing up and go through a Terminal Server
Xyou could be monitored at that point, or comming over the
Xnetwork.
X
X----
Xenjoy.. distribute freely. Feel free to add, give suggestions,
Xetc.
X
END_OF_FILE
if test 5888 -ne `wc -c <'Circ/README'`; then
echo shar: \"'Circ/README'\" unpacked with wrong size!
fi
# end of 'Circ/README'
fi
if test -f 'Circ/RSA/arith.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/arith.c'\"
else
echo shar: Extracting \"'Circ/RSA/arith.c'\" \(11667 characters\)
sed "s/^X//" >'Circ/RSA/arith.c' <<'END_OF_FILE'


X/*******************************************************************************
X* *
X* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
X* *
X* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
X* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
X* verwendet werden. *
X* *
X* mar...@trillian.megalon.de *
X* *
X*******************************************************************************/
X

X#include "arith.h"
X
X/*
X * !!!!!!!!!!!!!!!!!!!!!!!!!!!! ACHTUNG !!!!!!!!!!!!!!!!!!!!!!!!!!!!
X * Es findet keinerlei Ueberpruefung auf Bereichsueberschreitung
X * statt. Alle Werte muessen natuerliche Zahlen aus dem Bereich
X * 0 ... (MAXINT+1)^MAXLEN-1 sein.
X *
X *
X * Bei keiner Funktion oder Hilsfunktion werden Annahmen getroffen,
X * ueber die Verschiedenheit von Eingabe- & Ausgabe-Werten.
X *
X *
X * Funktionen:
X *
X * a_add( s1, s2, d )
X * NUMBER *s1,*s2,*d;
X * *d = *s1 + *s2;
X *
X * a_assign( *d, *s )
X * NUMBER *d,*s;
X * *d = *s;
X *
X * int a_cmp( c1, c2 )
X * NUMBER *c1,*c2;
X * 1 : falls *c1 > *c2
X * 0 : falls *c1 == *c2
X * -1 : falls *c1 < *c2
X *
X * a_div( d1, d2, q, r )
X * NUMBER *d1,*d2,*q,*r;
X * *q = *d1 / *d2 Rest *r;
X *
X * a_div2( n )
X * NUMBER *n;
X * *n /= 2;
X *
X * a_ggt( a, b, f )
X * NUMBER *a,*b,*f;
X * *f = ( *a, *b );
X *
X * a_imult( n, m, d )
X * NUMBER *n;
X * INT m;
X * NUMBER *d;
X * *d = *n * m
X *
X * a_mult( m1, m2, d )
X * NUMBER *m1,*m2,*d;
X * *d = *m1 * *m2;
X *
X * a_sub( s1, s2, d )
X * NUMBER *s1,*s2,*d;
X * *d = *s1 - *s2;
X *
X * Modulare Funktionen
X * m_init( n, o )
X * NUMBER *n,*o;
X * Initialsierung der Modularen Funktionen
X * o != 0 : *o = alter Wert
X *
X * m_add( s1, s2, d )
X * NUMBER *s1, *s2, *d;
X * *d = *s1 + *s2;
X *
X * m_mult( m1, m2, d )
X * NUMBER *m1,*m2,*d;
X *
X * m_exp( x, n, z )
X * NUMBER *x,*n,*z;
X * *z = *x exp *n;
X *
X *
X * Hilfs-Funktionen:
X *
X * int n_bits( n, b )
X * NUMBER *n;
X * int b;
X * return( unterste b Bits der Dualdarstellung von n)
X *
X * n_div( d1, z2, q, r )
X * NUMBER *d1,z2[MAXBIT],*q,*r;
X * *q = *d1 / z2[0] Rest *r;
X * z2[i] = z2[0] * 2^i, i=0..MAXBIT-1
X *
X * int n_cmp( i1, i2, l )
X * INT i1[l], i2[l];
X * 1 : falls i1 > i2
X * 0 : falls i1 == i2
X * -1 : falls i1 < i2
X *
X * int n_mult( n, m, d, l)
X * INT n[l], m, d[];
X * d = m * n;
X * return( sizeof(d) ); d.h. 'l' oder 'l+1'
X *
X * int n_sub( p1, p2, p3, l, lo )
X * INT p1[l], p2[lo], p3[];
X * p3 = p1 - p2;
X * return( sizeof(p3) ); d.h. '<= min(l,lo)'
X *
X * int n_bitlen( n )
X * NUMBER *n;
X * return( sizeof(n) in bits )
X *
X */
X
X
X/*
X * Konstante 1, 2
X */
XNUMBER a_one = {
X 1,
X { (INT)1, },
X};
X
XNUMBER a_two = {
X#if MAXINT == 1
X 2,
X { 0, (INT)1, },
X#else
X 1,
X { (INT)2, },
X#endif
X};
X
X
X/*
X * Vergleiche zwei INT arrays der Laenge l
X */
Xint n_cmp( i1, i2, l )
XINT *i1,*i2;
X{
X i1 += (l-1); /* Pointer ans Ende */
X i2 += (l-1);
X
X for (;l--;)
X if ( *i1-- != *i2-- )
X return( i1[1] > i2[1] ? 1 : -1 );


X
X return(0);
X}
X
X/*

X * Vergleiche zwei NUMBER
X */
Xint a_cmp( c1, c2 )
XNUMBER *c1,*c2;
X{
X int l;
X /* bei verschiedener Laenge klar*/
X if ( (l=c1->n_len) != c2->n_len)
X return( l - c2->n_len);
X
X /* vergleiche als arrays */
X return( n_cmp( c1->n_part, c2->n_part, l) );
X}
X
X/*
X * Zuweisung einer NUMBER (d = s)
X */
Xvoid a_assign( d, s )
XNUMBER *d,*s;
X{
X int l;
X
X if (s == d) /* nichts zu kopieren */
X return;
X
X if (l=s->n_len)
X memcpy( d->n_part, s->n_part, sizeof(INT)*l);
X
X d->n_len = l;
X}
X
X/*
X * Addiere zwei NUMBER (d = s1 + s2)
X */
Xvoid a_add( s1, s2, d )
XNUMBER *s1,*s2,*d;
X{
X int l,lo,ld,same;
X register LONG sum;
X register INT *p1,*p2,*p3;
X register INT b;
X
X /* setze s1 auch die groessere Zahl */
X l = s1->n_len;
X if ( (l=s1->n_len) < s2->n_len ) {
X NUMBER *tmp = s1;
X
X s1 = s2;
X s2 = tmp;
X
X l = s1->n_len;
X }
X
X ld = l;
X lo = s2->n_len;
X p1 = s1->n_part;
X p2 = s2->n_part;
X p3 = d->n_part;
X same = (s1 == d);
X sum = 0;
X
X while (l --) {
X if (lo) { /* es ist noch was von s2 da */
X lo--;
X b = *p2++;
X }
X else
X b = 0; /* ansonten 0 nehmen */
X
X sum += (LONG)*p1++ + (LONG)b;
X *p3++ = TOINT(sum);
X
X if (sum > (LONG)MAXINT) { /* carry merken */
X sum = 1;
X }
X else
X sum = 0;
X
X if (!lo && same && !sum) /* nichts mehr zu tuen */
X break;
X }
X
X if (sum) { /* letztes carry beruecksichtigen */
X ld++;
X *p3 = sum;
X }
X
X d->n_len = ld; /* Laenge setzen */
X}
X
X/*
X * Subtrahiere zwei INT arrays. return( Laenge Ergebniss )
X * l == Laenge p1
X * lo== Laenge p3
X */
Xint n_sub( p1, p2, p3, l, lo )
XINT *p1,*p2,*p3;
Xint l,lo;
X{
X int ld,lc,same;
X int over = 0;
X register LONG dif;
X LONG a,b;
X
X same = (p1 == p3); /* frueher Abbruch moeglich */
X
X for (lc=1, ld=0; l--; lc++) {
X a = (LONG)*p1++;
X if (lo) { /* ist noch was von p2 da ? */
X lo--;
X b = (LONG)*p2++;
X }
X else
X b=0; /* ansonten 0 nehmen */
X
X if (over) /* frueherer Overflow */
X b++;
X if ( b > a ) { /* jetzt Overflow ? */
X over = 1;
X dif = (MAXINT +1) + a;
X }
X else {
X over = 0;
X dif = a;
X }
X dif -= b;
X *p3++ = (INT)dif;
X
X if (dif) /* Teil != 0 : Laenge neu */
X ld = lc;
X if (!lo && same && !over) { /* nichts mehr zu tuen */
X if (l > 0) /* Laenge korrigieren */
X ld = lc + l;
X break;
X }
X }
X
X return( ld );
X}
X
X/*
X * Subtrahiere zwei NUMBER (d= s1 - s2)
X */
Xvoid a_sub( s1, s2, d )
XNUMBER *s1,*s2,*d;
X{
X d->n_len = n_sub( s1->n_part, s2->n_part, d->n_part
X ,s1->n_len, s2->n_len );
X}
X
X/*
X * Mulitipliziere INT array der Laenge l mit einer INT (d = n * m)
X * return neue Laenge
X */
Xint n_mult( n, m, d, l)
Xregister INT *n;
Xregister INT m;
XINT *d;
X{
X int i;
X register LONG mul;
X
X for (i=l,mul=0; i; i--) {
X mul += (LONG)m * (LONG)*n++;
X *d++ = TOINT(mul);
X mul = DIVMAX1( mul );
X }
X
X if (mul) { /* carry ? */
X l++;
X *d = mul;
X }
X
X return( l );
X}
X
X/*
X * Mulitipliziere eine NUMBER mit einer INT (d = n * m)
X */
Xvoid a_imult( n, m, d )
XNUMBER *n;
XINT m;
XNUMBER *d;
X{
X if (m == 0)
X d->n_len=0;
X else if (m == 1)
X a_assign( d, n );
X else
X d->n_len = n_mult( n->n_part, m, d->n_part, n->n_len );
X}
X
X/*
X * Multipliziere zwei NUMBER (d = m1 * m2)
X */
Xvoid a_mult( m1, m2, d )
XNUMBER *m1,*m2,*d;
X{
X static INT id[ MAXLEN ]; /* Zwischenspeicher */
X register INT *vp; /* Pointer darin */
X register LONG sum; /* Summe fuer jede Stelle */
X register LONG tp1; /* Zwischenspeicher fuer m1 */
X register INT *p2;
X INT *p1;
X int l1,l2,ld,lc,l,i,j;
X
X l1 = m1->n_len;
X l2 = m2->n_len;
X l = l1 + l2;
X if (l >= MAXLEN)
X abort();
X
X for (i=l, vp=id; i--;)
X *vp++ = 0;
X
X /* ohne Uebertrag in Zwischenspeicher multiplizieren */
X for ( p1 = m1->n_part, i=0; i < l1 ; i++, p1++ ) {
X
X tp1 = (LONG)*p1;
X vp = &id[i];
X sum = 0;
X for ( p2 = m2->n_part, j = l2; j--;) {
X sum += (LONG)*vp + (tp1 * (LONG)*p2++);
X *vp++ = TOINT( sum );
X sum = DIVMAX1(sum);
X }
X *vp++ += (INT)sum;
X }
X
X /* jetzt alle Uebertraege beruecksichtigen */
X ld = 0;
X for (lc=0, vp=id, p1=d->n_part; lc++ < l;) {
X if ( *p1++ = *vp++ )
X ld = lc;
X }
X
X d->n_len = ld;
X}
X
X
X/*
X * Dividiere Zwei NUMBER mit Rest (q= d1 / z2[0] Rest r)
X * z2[i] = z2[0] * 2^i, i=0..MAXBIT-1
X * r = 0 : kein Rest
X * q = 0 : kein Quotient
X */
Xvoid n_div( d1, z2, q, r )
XNUMBER *d1,*z2,*q,*r;
X{
X static NUMBER dummy_rest; /* Dummy Variable, falls r = 0 */
X static NUMBER dummy_quot; /* Dummy Variable, falla q = 0 */
X INT *i1,*i1e,*i3;
X int l2,ld,l,lq;
X#if MAXINT != 1
X INT z;
X int pw,l2t;
X#endif
X
X if (!z2->n_len)
X abort();
X
X if (!r)
X r = &dummy_rest;
X if (!q)
X q = &dummy_quot;
X
X a_assign( r, d1 ); /* Kopie von d1 in den Rest */
X
X l2= z2->n_len; /* Laenge von z2[0] */
X l = r->n_len - l2; /* Laenge des noch ''rechts'' liegenden
X Stuecks von d1 */
X lq= l +1; /* Laenge des Quotienten */
X i3= q->n_part + l;
X i1= r->n_part + l;
X ld = l2; /* aktuelle Laenge des ''Vergleichsstuecks''
X von d1 */
X i1e= i1 + (ld-1);
X
X for (; l >= 0; ld++, i1--, i1e--, l--, i3--) {
X *i3 = 0;
X
X if (ld == l2 && ! *i1e) {
X ld--;
X continue;
X }
X
X if ( ld > l2 || (ld == l2 && n_cmp( i1, z2->n_part, l2) >= 0 ) ) {
X#if MAXINT != 1
X /* nach 2er-Potenzen zerlegen */
X for (pw=MAXBIT-1, z=(INT)HIGHBIT; pw >= 0; pw--, z /= 2) {
X if ( ld > (l2t= z2[pw].n_len)
X || (ld == l2t
X && n_cmp( i1, z2[pw].n_part, ld) >= 0) ) {
X ld = n_sub( i1, z2[pw].n_part, i1, ld, l2t );
X (*i3) += z;
X }
X }
X#else
X /* bei MAXINT == 1 alles viel einfacher */
X ld = n_sub( i1, z2->n_part, i1, ld, l2 );
X (*i3) ++;
X#endif
X }
X }
X
X /* Korrektur, falls l von Anfang an Negativ war */
X l ++;
X lq -= l;
X ld += l;
X
X if (lq>0 && !q->n_part[lq -1]) /* evtl. Laenge korrigieren */
X lq--;
X
X q->n_len = lq;
X r->n_len = ld -1;
X}
X
X/*
X * Dividiere Zwei NUMBER mit Rest (q= d1 / z2[0] Rest r)
X * z2[i] = z2[0] * 2^i, i=0..MAXBIT-1
X * r = 0 : kein Rest
X * q = 0 : kein Quotient
X */
Xvoid a_div( d1, d2, q, r )
XNUMBER *d1,*d2,*q,*r;
X{
X#if MAXINT != 1
X NUMBER z2[MAXBIT];
X INT z;
X int i;
X
X a_assign( &z2[0], d2 );
X for (i=1,z=2; i < MAXBIT; i++, z *= 2)
X a_imult( d2, z, &z2[i] );
X
X d2 = z2;
X#endif
X
X n_div( d1, d2, q, r );
X}
X
X/*
X * Dividiere eine NUMBER durch 2
X */
Xvoid a_div2( n )
XNUMBER *n;
X{
X#if MAXBIT == LOWBITS
X register INT *p;
X int i;
X
X#if MAXINT != 1
X register INT h;
X register int c;
X
X c=0;
X i= n->n_len;
X p= &n->n_part[i-1];
X
X for (; i--;) {
X if (c) {
X c = (h= *p) & 1;
X h /= 2;
X h |= HIGHBIT;
X }
X else {
X c = (h= *p) & 1;
X h /= 2;
X }
X
X *p-- = h;
X }
X
X if ( (i= n->n_len) && n->n_part[i-1] == 0 )
X n->n_len = i-1;
X
X#else /* MAXBIT != 1 */
X p = n->n_part;
X i = n->n_len;
X
X if (i) {
X n->n_len = i-1;
X for (; --i ; p++)
X p[0] = p[1];
X }
X#endif /* MAXBIT != 1 */
X#else /* MAXBIT == LOWBITS */
X a_div( n, &a_two, n, NUM0P );
X#endif /* MAXBIT == LOWBITS */
X}
X
X
X/*
X * MODULO-FUNKTIONEN
X */
X
Xstatic NUMBER mod_z2[ MAXBIT ];
X
X/*
X * Init
X */
Xvoid m_init( n, o )
XNUMBER *n,*o;
X{
X INT z;
X int i;
X
X if (o)
X a_assign( o, &mod_z2[0] );
X
X if (! a_cmp( n, &mod_z2[0] ) )
X return;
X
X for (i=0,z=1; i < MAXBIT; i++, z *= 2)
X a_imult( n, z, &mod_z2[i] );
X}
X
Xvoid m_add( s1, s2, d )
XNUMBER *s1, *s2, *d;
X{
X a_add( s1, s2, d );
X if (a_cmp( d, mod_z2 ) >= 0)
X a_sub( d, mod_z2, d );
X}
X
Xvoid m_mult( m1, m2, d )
XNUMBER *m1,*m2,*d;
X{
X a_mult( m1, m2, d );
X n_div( d, mod_z2, NUM0P, d );
X}
X
X/*
X * Restklassen Exponent
X */
Xvoid m_exp( x, n, z )
XNUMBER *x,*n,*z;
X{
X NUMBER xt,nt;
X
X a_assign( &nt, n );
X a_assign( &xt, x );
X a_assign( z, &a_one );
X
X while (nt.n_len) {
X while ( ! (nt.n_part[0] & 1) ) {
X m_mult( &xt, &xt, &xt );
X a_div2( &nt );
X }
X m_mult( &xt, z, z );
X a_sub( &nt, &a_one, &nt );
X }
X}
X
X/*
X * GGT
X */
Xvoid a_ggt( a, b, f )
XNUMBER *a,*b,*f;
X{
X NUMBER t[2];
X int at,bt, tmp;
X
X a_assign( &t[0], a ); at= 0;
X a_assign( &t[1], b ); bt= 1;
X
X if ( a_cmp( &t[at], &t[bt] ) < 0 ) {
X tmp= at; at= bt; bt= tmp;
X }
X /* euklidischer Algorithmus */
X while ( t[bt].n_len ) {
X a_div( &t[at], &t[bt], NUM0P, &t[at] );
X tmp= at; at= bt; bt= tmp;
X }
X
X a_assign( f, &t[at] );
X}
X
X/*
X * die untersten b bits der Dualdarstellung von n
X * die bits muessen in ein int passen
X */
Xint n_bits(n,b)
XNUMBER *n;
X{
X INT *p;
X int l;
X unsigned r;
X int m = (1<<b) -1;
X
X if ( n->n_len == 0)
X return(0);
X
X if (LOWBITS >= b)
X return( n->n_part[0] & m );
X
X#if LOWBITS != 0
X l = (b-1) / LOWBITS;
X#else
X l = n->n_len -1;
X#endif
X for (p= &n->n_part[l],r=0; l-- >= 0 && b > 0; b-= LOWBITS, p--) {
X r = MULMAX1( r );
X r += (unsigned)*p;
X }
X
X return( r & m );
X}
X
X/*
X * Anzahl der bits von n bei Dualdarstellung
X */
Xint n_bitlen( n )
XNUMBER *n;
X{
X NUMBER b;
X int i;
X
X a_assign( &b, &a_one );
X
X for (i=0; a_cmp( &b, n ) <= 0; a_mult( &b, &a_two, &b ), i++)
X ;
X
X return(i);
X}
END_OF_FILE
if test 11667 -ne `wc -c <'Circ/RSA/arith.c'`; then
echo shar: \"'Circ/RSA/arith.c'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/arith.c'
fi
if test -f 'Circ/RSA/nio.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/nio.c'\"
else
echo shar: Extracting \"'Circ/RSA/nio.c'\" \(4308 characters\)
sed "s/^X//" >'Circ/RSA/nio.c' <<'END_OF_FILE'


X/*******************************************************************************
X* *
X* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
X* *
X* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
X* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
X* verwendet werden. *
X* *
X* mar...@trillian.megalon.de *
X* *
X*******************************************************************************/
X

X#include <stdio.h>
X#include <ctype.h>
X#include <string.h>
X
X#include "nio.h"
X
X/*
X * NUMBER io
X */
X
X/*
X * Funktionen
X *
X * int num_sput( n, s, l)
X * NUMBER *n;
X * char s[l];
X * schreibt *n als Hex-Zahl in s
X *
X * int num_fput( n, f )
X * NUMBER *n;
X * FILE *f;
X * schreibt *n als Hex-Zahl in File f
X *
X * int num_sget( n, s )
X * NUMBER *n;
X * char *s;
X * liest Hex-Zahl s in *n ein
X *
X * int num_fget( n, f )
X * NUMBER *n;
X * FILE *f;
X * liest eine Hex-Zahl von f in *n ein
X *
X */
X
X
Xstatic char *HEX="0123456789ABCDEF";
Xstatic char *hex="0123456789abcdef";
X
Xstatic NUMBER bits[9];
Xstatic NUMBER int16[16];
X
Xstatic int init = 0;
X
Xstatic num_init()


X{
X int i;
X

X a_assign( &bits[0], &a_one );
X for ( i=1; i<9; i++)
X a_add( &bits[i-1], &bits[i-1], &bits[i] );
X
X a_assign( &int16[0], &a_one );
X for ( i=1; i<16; i++)
X a_add( &int16[i-1], &a_one, &int16[i] );
X
X init = 1;
X}
X
X
Xint num_sput( n, s, l)
XNUMBER *n;
Xchar *s;
X{
X#if MAXINT == ( (1 << MAXBIT) - 1 )
X INT *p;
X int bi,ab,i;
X long b;
X int first = 1;
X
X bi = MAXBIT * n->n_len;
X ab = 4 - (bi + 3) % 4 -1;
X p = &n->n_part[n->n_len -1];
X
X if ( (bi+3) / 4 >= l )
X return(EOF);
X
X b = 0;
X while (bi) {
X b <<= (MAXBIT);
X b |= (unsigned long)*p--;
X bi -= MAXBIT;
X ab += MAXBIT;
X while (ab >= 4) {
X i = (b >> (ab - 4));
X b &= ( 1L << (ab - 4) ) -1L;
X ab -= 4;
X
X if (first && !i)
X continue;
X first = 0;
X *s++ = HEX[ i ];
X }
X }
X if (b)
X abort();
X *s = '\0';
X
X return (0);
X#else
X NUMBER r,q;
X int i,b,p,len,low,high;
X char *np;
X
X if (! init)
X num_init();
X
X a_assign( &q, n);
X len = l;
X np = s + l;
X
X for (; q.n_len && len > 1; len --) {
X a_div( &q, &bits[4], &q, &r );
X for (p=8, b=0, i=3; i >= 0; i--, p /= 2 ) {
X if ( a_cmp( &r, &bits[i] ) >= 0 ) {
X a_sub( &r, &bits[i], &r );
X b += p;
X }
X }
X *--np = HEX[ b ];
X }
X if (q.n_len)
X return(EOF);
X
X l -= len;
X len = l;
X for (; l--; )
X *s++ = *np++;
X
X *s = '\0';
X
X return (0);
X#endif
X}
X
X
Xint num_fput( n, f )
XNUMBER *n;
XFILE *f;
X{
X int j;
X char *np;
X unsigned char n_print[ STRLEN + 1 ];
X
X if ( num_sput( n, n_print, sizeof( n_print ) ) == EOF )
X return(EOF);
X
X for (j=0, np=(char *)n_print; *np ; np++, j++ ) {
X if (j==64) {
X fputs("\n",f);
X j = 0;
X }
X putc((int)*np,f);
X }
X
X if (j)
X putc('\n',f);


X
X return(0);
X}
X
X

Xint num_sget( n, s )
XNUMBER *n;
Xchar *s;
X{
X#if MAXINT == ( (1 << MAXBIT) - 1 )
X INT *p;
X char *hp;
X int bi,ab,i;
X long b;
X int first = 1;
X
X bi = 4 * strlen(s);
X ab = MAXBIT - (bi + MAXBIT -1) % MAXBIT -1;
X i = (bi + MAXBIT-1) / MAXBIT;
X p = &n->n_part[ i -1 ];
X n->n_len = i;
X
X if ( i > MAXLEN )
X return(EOF);
X
X b = 0;
X while (bi > 0) {
X if ( hp= strchr( HEX, *s ) )
X i = hp - HEX;
X else if ( hp= strchr( hex, *s ) )
X i = hp - hex;
X else
X return(EOF);
X s++;
X
X b <<= 4;
X b |= (unsigned long)i;
X bi -= 4;
X ab += 4;
X while (ab >= MAXBIT) {
X i = (b >> (ab - MAXBIT));
X b &= ( 1L << (ab - MAXBIT) ) -1L;
X ab -= MAXBIT;
X if (first && !i) {
X p--;
X n->n_len--;
X }
X else {
X first = 0;
X *p-- = i;
X }
X }
X }
X if (b)
X abort();
X *s = '\0';
X
X return (0);
X#else
X char *p;
X int i,c;
X
X if (! init)
X num_init();
X
X n->n_len = 0;
X while ( (c = *s++ & 0xFF) ) {
X if ( p= strchr( HEX, c ) )
X i = p - HEX;
X else if ( p= strchr( hex, c ) )
X i = p - hex;
X else
X return(EOF);
X
X a_mult( n, &bits[4], n );
X if (i)
X a_add( n, &int16[i-1], n );
X }
X
X return(0);
X#endif
X}
X
Xint num_fget( n, f )
XNUMBER *n;
XFILE *f;
X{
X int j,c;
X char *np;
X char n_print[ STRLEN + 1 ];
X
X np = n_print;
X j = sizeof(n_print);
X while ( (c=getc(f)) != EOF && ( isxdigit(c) || isspace(c) ) ) {
X if (isspace(c))
X continue;
X if (! --j)
X return(EOF);
X *np++ = (char)c;
X }
X *np = '\0';
X
X if (c != EOF)
X ungetc(c,f);
X
X if ( num_sget( n, n_print ) == EOF )
X return( EOF );


X
X return(0);
X}
X

END_OF_FILE
if test 4308 -ne `wc -c <'Circ/RSA/nio.c'`; then
echo shar: \"'Circ/RSA/nio.c'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/nio.c'
fi
if test -f 'Circ/RSA/prim.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/prim.c'\"
else
echo shar: Extracting \"'Circ/RSA/prim.c'\" \(4732 characters\)
sed "s/^X//" >'Circ/RSA/prim.c' <<'END_OF_FILE'


X/*******************************************************************************
X* *
X* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
X* *
X* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
X* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
X* verwendet werden. *
X* *
X* mar...@trillian.megalon.de *
X* *
X*******************************************************************************/
X

X#include "prim.h"
X
X/*
X * RSA
X *
X * p,q prim
X * p != q
X * n = p*q
X * phi = (p -1)*(q -1)
X * e,d aus 0...n-1
X * e*d == 1 mod phi
X *
X * m aus 0...n-1 sei eine Nachricht
X *
X * Verschluesseln:
X * E(x) = x^e mod n ( n,e oeffendlich )
X *
X * Entschluesseln:
X * D(x) = x^d mod n ( d geheim )
X *
X *
X * Sicherheit:
X *
X * p,q sollten bei mind. 10^100 liegen.
X * (d,phi) == 1, das gilt fuer alle Primzahlen > max(p,q).
X * Allerdings sollte d moeglichst gross sein ( d < phi-1 )
X * um direktes Suchen zu verhindern.
X */
X
X
X/*
X * FUNKTIONEN um RSA Schluessel zu generieren.
X *
X * int p_prim( n, m )
X * NUMBER *n;
X * int m;
X * 0 : n ist nicht prim
X * 1 : n ist mit Wahrscheinlichkeit (1-1/2^m) prim
X * ACHTUNG !!!!
X * p_prim benutzt m_init
X *
X * inv( d, phi, e )
X * NUMBER *d,*phi,*e;
X * *e = *d^-1 (mod phi)
X * ACHTUNG !!!!
X * p_prim benutzt m_init
X */
X
X/*
X * Prototypes
X */
Xstatic int jak_f( );
Xstatic int jak_g( );
Xstatic int jakobi( );
X
X/*
X * Hilfs-Funktion fuer jakobi
X */
Xstatic int jak_f( n )
XNUMBER *n;
X{
X int f,ret;
X
X f = n_bits( n, 3 );
X
X ret = ((f == 1) || (f == 7)) ? 1 : -1;
X
X return(ret);
X}
X
X/*
X * Hilfs-Funktuion fuer jakobi
X */
Xstatic int jak_g( a, n )
XNUMBER *a,*n;
X{
X int ret;
X
X if ( n_bits( n, 2 ) == 1 ||
X n_bits( a, 2 ) == 1 )
X ret = 1;
X else
X ret = -1;
X
X return(ret);
X}
X
X/*
X * Jakobi-Symbol
X */
Xstatic int jakobi( a, n )
XNUMBER *a,*n;
X{
X NUMBER t[2];
X int at,nt, ret;
X
X a_assign( &t[0], a ); at = 0;
X a_assign( &t[1], n ); nt = 1;
X
X /*
X * b > 1
X *
X * J( a, b) =
X * a == 1 : 1
X * a == 2 : f(n)
X * a == 2*b : J(b,n)*J(2,n) ( == J(b,n)*f(n) )
X * a == 2*b -1 : J(n % a,a)*g(a,n)
X *
X */
X
X ret = 1;
X while (1) {
X if (! a_cmp(&t[at],&a_one) ) {
X break;
X }
X if (! a_cmp(&t[at],&a_two) ) {
X ret *= jak_f( &t[nt] );
X break;
X }
X if ( ! t[at].n_len ) /* Fehler :-) */
X abort();
X if ( t[at].n_part[0] & 1 ) { /* a == 2*b -1 */
X int tmp;
X
X ret *= jak_g( &t[at], &t[nt] );
X a_div( &t[nt], &t[at], NUM0P, &t[nt] );
X tmp = at; at = nt; nt = tmp;
X }
X else { /* a == 2*b */
X ret *= jak_f( &t[nt] );
X a_div2( &t[at] );
X }
X
X }
X
X return(ret);
X}
X
X/*
X * Probabilistischer Primzahltest
X *
X * 0 -> n nicht prim
X * 1 -> n prim mit (1-1/2^m) Wahrscheinlichkeit.
X *
X * ACHTUNG !!!!!!
X * p_prim benutzt m_init !!
X *
X */
Xint p_prim( n, m )
XNUMBER *n;
X{
X NUMBER gt,n1,n2,a;
X INT *p;
X int i,w,j;
X long lrand48();
X
X if (a_cmp(n,&a_two) <= 0 || m <= 0)
X abort();
X
X a_sub( n, &a_one, &n1 ); /* n1 = -1 mod n */
X a_assign( &n2, &n1 );
X a_div2( &n2 ); /* n2 = ( n -1 ) / 2 */
X
X m_init( n, NUM0P );
X
X w = 1;
X for (; w && m; m--) {
X /* ziehe zufaellig a aus 2..n-1 */
X do {
X for (i=n->n_len-1, p=a.n_part; i; i--)
X *p++ = (INT)lrand48();
X if ( i=n->n_len )
X *p = (INT)( lrand48() % ((unsigned long)n->n_part[i-1] +1) );
X while ( i && ! *p )
X p--,i--;
X a.n_len = i;
X } while ( a_cmp( &a, n ) >= 0 || a_cmp( &a, &a_two ) < 0 );
X
X /* jetzt ist a fertig */
X
X /*
X * n ist nicht prim wenn gilt:
X * (a,n) != 1
X * oder
X * a^( (n-1)/2 ) != J(a,n) mod n
X *
X */
X
X a_ggt( &a, n, &gt );
X if ( a_cmp( &gt, &a_one ) == 0 ) {
X
X j= jakobi( &a, n );
X m_exp( &a, &n2, &a );
X
X if ( ( a_cmp( &a, &a_one ) == 0 && j == 1 )
X || ( a_cmp( &a, &n1 ) == 0 && j == -1 ) )
X w = 1;
X else
X w = 0;
X }
X else
X w = 0;
X }
X
X return( w );
X}
X
X/*
X * Berechne mulitiplikatives Inverses zu d (mod phi)
X * d relativ prim zu phi ( d < phi )
X * d.h. (d,phi) == 1
X *
X * ACHTUNG !!!!
X * inv benutzt m_init
X */
Xvoid inv( d, phi, e )
XNUMBER *d,*phi,*e;
X{
X int k, i0, i1, i2;
X NUMBER r[3],p[3],c;
X
X /*
X * Berlekamp-Algorithmus
X * ( fuer diesen Spezialfall vereinfacht )
X */
X
X if (a_cmp(phi,d) <= 0)
X abort();
X
X m_init( phi, NUM0P );
X
X p[1].n_len = 0;
X a_assign( &p[2], &a_one );
X a_assign( &r[1], phi );
X a_assign( &r[2], d );
X
X k = -1;
X do {
X k++;
X i0=k%3; i1=(k+2)%3; i2=(k+1)%3;
X a_div( &r[i2], &r[i1], &c, &r[i0] );
X m_mult( &c, &p[i1], &p[i0] );
X m_add( &p[i0], &p[i2], &p[i0] );
X } while (r[i0].n_len);
X
X if ( a_cmp( &r[i1], &a_one ) ) /* r[i1] == (d,phi) muss 1 sein */
X abort();
X
X if ( k & 1 ) /* falsches ''Vorzeichen'' */
X a_sub( phi, &p[i1], e );
X else
X a_assign( e, &p[i1] );
X}
END_OF_FILE
if test 4732 -ne `wc -c <'Circ/RSA/prim.c'`; then
echo shar: \"'Circ/RSA/prim.c'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/prim.c'
fi
if test -f 'Circ/RSA/rsa.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/rsa.c'\"
else
echo shar: Extracting \"'Circ/RSA/rsa.c'\" \(4406 characters\)
sed "s/^X//" >'Circ/RSA/rsa.c' <<'END_OF_FILE'


X/*******************************************************************************
X* *
X* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
X* *
X* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
X* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
X* verwendet werden. *
X* *
X* mar...@trillian.megalon.de *
X* *
X*******************************************************************************/
X

X#include <stdio.h>
X#include <string.h>
X#ifndef AMIGA
X#include <memory.h>
X#endif AMIGA
X
X#include "arith.h"
X#include "nio.h"
X
X#define ENCODE "rsaencode"
X#define DECODE "rsadecode"
X
Xchar *prog;
X
Xint clear_siz; /* clear-text blocksize */
Xint enc_siz; /* encoded blocksize */
X /* clear_siz < enc_siz */
X
Xdo_crypt( s, d, len, e )
Xchar *s;
Xchar *d;
XNUMBER *e;
X{
X static char hex[] = "0123456789ABCDEF";
X NUMBER n;
X char buf[ STRLEN + 1 ];
X char *pb,*ph;
X int i,c;
X
X ph = buf + STRLEN;
X ph[1] = '\0';
X
X for (i=len; i; i--) {
X c = *s++;
X *ph-- = hex[ (c >> 4) & 0xF ];
X *ph-- = hex[ c & 0xF ];
X }
X ph++;
X
X num_sget( &n, ph );
X
X m_exp( &n, e, &n );
X
X num_sput( &n, buf, STRLEN +1 );
X
X ph = buf + (i=strlen(buf)) -1;
X
X for (; len; len--) {
X if (i-- > 0) {
X c = (strchr( hex, *ph ) - hex) << 4;
X ph--;
X }
X else
X c=0;
X if (i-- > 0) {
X c |= strchr( hex, *ph ) - hex;
X ph--;
X }
X
X *d++ = c;
X }
X}
X
X#ifdef STANDALONE
Xint get_clear( p )
Xchar *p;
X{
X int n;
X
X n = fread( p, 1, clear_siz, stdin );
X
X if (n <= 0)
X return(0);
X
X
X return(1);
X}
X
Xint get_enc( p )
Xchar *p;
X{
X int n;
X
X n = fread( p, 1, enc_siz, stdin );
X
X if (n != enc_siz)
X return(0);
X
X return(1);
X}
X
Xint put_clear( p )
Xchar *p;
X{
X int n;
X
X n = fwrite( p, 1, clear_siz, stdout );
X
X if (n != clear_siz)
X return(0);
X
X return(1);
X}
X
Xint put_enc( p )
Xchar *p;
X{
X int n;
X
X n = fwrite( p, 1, enc_siz, stdout );
X
X if (n != enc_siz)
X return(0);
X
X return(1);
X}
X
X
Xmain( argc, argv )
Xchar **argv;
X{
X char buf[ STRLEN*2 ];
X NUMBER n,e;
X FILE *keys;
X int (*inp)() = 0;
X int (*out)() = 0;
X
X if ( ! (prog=strrchr( argv[0], '/' )) )
X prog=argv[0];
X
X
X if ( ! strcmp( prog, DECODE ) ) {
X inp = get_enc;
X out = put_clear;
X }
X if ( ! strcmp( prog, ENCODE ) ) {
X inp = get_clear;
X out = put_enc;
X }
X
X if (! inp) {
X fprintf(stderr,"%s: don't know who i am (%s or %s)\n",prog,ENCODE,DECODE);
X exit(1);
X }
X
X if (argc != 2) {
X fprintf(stderr,"usage: %s keyfile\n",prog);
X exit(1);
X }
X if ( !( keys= fopen(argv[1],"r")) ) {
X perror(argv[1]);
X exit(1);
X }
X
X num_fget( &n, keys ); getc(keys);
X num_fget( &e, keys );
X if (a_cmp(&n,&e) <= 0 || e.n_len == 0 || getc(keys) != EOF) {
X fprintf(stderr,"%s: corrupt keyfile\n",prog);
X fprintf(stderr,"keyfile format:\n");
X fprintf(stderr,"\t<n in hex>\n");
X fprintf(stderr,"\t<delimiter> (1 char)\n");
X fprintf(stderr,"\t<e/d in hex>\n");
X fprintf(stderr,"white spaces are ignored\n");
X exit(1);
X }
X
X enc_siz = ( n_bitlen( &n ) + 7 ) / 8;
X clear_siz = enc_siz -1;
X
X m_init( &n, NUM0P );
X
X while ( (*inp)( buf ) ) {
X do_crypt( buf, buf, enc_siz, &e );
X if (! (*out)( buf ) ) {
X perror("output");
X exit(1);
X }
X }
X
X exit(0);
X}
X
X#else STANDALONE
X
Xdo_rsa(keyfile,buffer,buflen,maxlen )
Xint buflen;
Xchar *keyfile,*buffer;
X{
X NUMBER n,e;
X FILE *keys;
X
X if ( !( keys= fopen(keyfile,"r")) ) {
X/* perror(keyfile); /* quiet, no errors */
X return(-1);
X }
X
X num_fget( &n, keys ); getc(keys);
X num_fget( &e, keys );
X if (a_cmp(&n,&e) <= 0 || e.n_len == 0 || getc(keys) != EOF) {
X /*
X fprintf(stderr,"%s: corrupt keyfile\n",prog);
X fprintf(stderr,"keyfile format:\n");
X fprintf(stderr,"\t<n in hex>\n");
X fprintf(stderr,"\t<delimiter> (1 char)\n");
X fprintf(stderr,"\t<e/d in hex>\n");
X fprintf(stderr,"white spaces are ignored\n");
X */
X return(-11);
X }
X
X enc_siz = ( n_bitlen( &n ) + 7 ) / 8;
X clear_siz = enc_siz -1;
X
X m_init( &n, NUM0P );
X
X if(buflen > enc_siz) {
X /*
X fprintf(stderr,"Public Key must be larger than data!\n");
X */
X return(-1);
X }
X if(maxlen < enc_siz) {
X /*
X fprintf(stderr,"Public key is too big for buffer.\n");
X */
X return(-1);
X }
X memset( buffer+buflen, 0, enc_siz - buflen ); /* pad out block */
X do_crypt( buffer, buffer, enc_siz, &e );
X return(enc_siz);
X
X}
X
X#endif STANDALONE
X
END_OF_FILE
if test 4406 -ne `wc -c <'Circ/RSA/rsa.c'`; then
echo shar: \"'Circ/RSA/rsa.c'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/rsa.c'
fi
if test -f 'Circ/crypt.irc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/crypt.irc'\"
else
echo shar: Extracting \"'Circ/crypt.irc'\" \(1324 characters\)
sed "s/^X//" >'Circ/crypt.irc' <<'END_OF_FILE'
X# Start up the proggie
X/^exec -name crypt exec new
X
X# automatically pick out protocol messages
X# crypt processor gets: !send nick!CLIPPER:...etc
X# or !our nick!SKPJACK:...etc
X/on ^public "* CLIPPER:*" /msg %crypt !$0!$1-
X/on ^public "* SKPJACK:*" /msg %crypt OURNICK:$N;/msg %crypt !$0!$1-
X/on ^public_other "* * CLIPPER:*" /msg %crypt !$0:$1!$2-
X/on ^public_other "* * SKPJACK:*" /msg %crypt OURNICK:$N;/msg %crypt !$0:$1!$2-
X
X/on ^msg "* CLIPPER:*" /msg %crypt !*$0*!$1-
X/on ^msg "* SKPJACK:*" /msg %crypt OURNICK:$N;/msg %crypt !*$0*!$1-
X
X# messages comming back from crypt, to server or screen?
X/on ^exec "crypt TCHANNL: *" /msg $C $2-
X/on ^exec "crypt TSCREEN: *" /echo $2-
X/on ^exec "crypt TNICKNM: *" /msg $2 $3-
X
X# our irc commands:
X# /key nick or /key nick filename
X# /die
X# /e message to be encrypted
X# /p message to be plaintext
X# /crypt (turn on automatic encryption)
X# /plain (turn off automatic encryption)
X# /emsg nick text send an encrypted message
X/alias key /echo K->*$0* Sending Key;/^msg %crypt SENDKEY: $0-
X/alias die /^msg %crypt QUITDIE:;/query
X/alias e /echo E> $0-;/^msg %crypt CRYPTME:$0-
X/alias p /msg $C $0-
X/alias crypt /query %crypt
X/alias plain /query
X/alias emsg /echo E->*$0* $1-;/^msg %crypt !$0!CRYPTME:$1-
X
X/echo *** Encrypted Irc Protocol loaded.
END_OF_FILE
if test 1324 -ne `wc -c <'Circ/crypt.irc'`; then
echo shar: \"'Circ/crypt.irc'\" unpacked with wrong size!
fi
# end of 'Circ/crypt.irc'
fi
if test -f 'Circ/d3des/d3des.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/d3des/d3des.h'\"
else
echo shar: Extracting \"'Circ/d3des/d3des.h'\" \(4546 characters\)
sed "s/^X//" >'Circ/d3des/d3des.h' <<'END_OF_FILE'
X/* d3des.h -
X *
X * Headers and defines for d3des.c
X * Graven Imagery, 1992.


X *
X * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge

X * (GEnie : OUTER; CIS : [71755,204])

X */
X
X#define D2_DES /* include double-length support */
X#define D3_DES /* include triple-length support */
X
X#ifdef D3_DES
X#ifndef D2_DES
X#define D2_DES /* D2_DES is needed for D3_DES */
X#endif
X#endif
X
X#define EN0 0 /* MODE == encrypt */
X#define DE1 1 /* MODE == decrypt */
X
X/* A useful alias on 68000-ish machines, but NOT USED HERE. */
X
Xtypedef union {
X unsigned long blok[2];
X unsigned short word[4];
X unsigned char byte[8];
X } M68K;
X
Xextern void deskey(/* unsigned char *, short */);
X/* hexkey[8] MODE
X * Sets the internal key register according to the hexadecimal
X * key contained in the 8 bytes of hexkey, according to the DES,
X * for encryption or decryption according to MODE.
X */
X
Xextern void usekey(/* unsigned long * */);
X/* cookedkey[32]
X * Loads the internal key register with the data in cookedkey.
X */
X
Xextern void cpkey(/* unsigned long * */);
X/* cookedkey[32]
X * Copies the contents of the internal key register into the storage
X * located at &cookedkey[0].
X */
X
Xextern void des(/* unsigned char *, unsigned char * */);
X/* from[8] to[8]
X * Encrypts/Decrypts (according to the key currently loaded in the
X * internal key register) one block of eight bytes at address 'from'
X * into the block at address 'to'. They can be the same.
X */
X
X#ifdef D2_DES
X
X#define desDkey(a,b) des2key((a),(b))
Xextern void des2key(/* unsigned char *, short */);
X/* hexkey[16] MODE
X * Sets the internal key registerS according to the hexadecimal
X * keyS contained in the 16 bytes of hexkey, according to the DES,
X * for DOUBLE encryption or decryption according to MODE.
X * NOTE: this clobbers all three key registers!
X */
X
Xextern void Ddes(/* unsigned char *, unsigned char * */);
X/* from[8] to[8]
X * Encrypts/Decrypts (according to the keyS currently loaded in the
X * internal key registerS) one block of eight bytes at address 'from'
X * into the block at address 'to'. They can be the same.
X */
X
Xextern void D2des(/* unsigned char *, unsigned char * */);
X/* from[16] to[16]
X * Encrypts/Decrypts (according to the keyS currently loaded in the
X * internal key registerS) one block of SIXTEEN bytes at address 'from'
X * into the block at address 'to'. They can be the same.
X */
X
Xextern void makekey(/* char *, unsigned char * */);
X/* *password, single-length key[8]
X * With a double-length default key, this routine hashes a NULL-terminated
X * string into an eight-byte random-looking key, suitable for use with the
X * deskey() routine.
X */
X
X#define makeDkey(a,b) make2key((a),(b))
Xextern void make2key(/* char *, unsigned char * */);
X/* *password, double-length key[16]
X * With a double-length default key, this routine hashes a NULL-terminated
X * string into a sixteen-byte random-looking key, suitable for use with the
X * des2key() routine.
X */


X
X#ifndef D3_DES /* D2_DES only */
X

X#define useDkey(a) use2key((a))
X#define cpDkey(a) cp2key((a))
X
Xextern void use2key(/* unsigned long * */);
X/* cookedkey[64]
X * Loads the internal key registerS with the data in cookedkey.
X * NOTE: this clobbers all three key registers!
X */
X
Xextern void cp2key(/* unsigned long * */);
X/* cookedkey[64]
X * Copies the contents of the internal key registerS into the storage
X * located at &cookedkey[0].
X */
X


X#else /* D3_DES too */
X

X#define useDkey(a) use3key((a))
X#define cpDkey(a) cp3key((a))
X
Xextern void des3key(/* unsigned char *, short */);
X/* hexkey[24] MODE
X * Sets the internal key registerS according to the hexadecimal
X * keyS contained in the 24 bytes of hexkey, according to the DES,
X * for DOUBLE encryption or decryption according to MODE.
X */
X
Xextern void use3key(/* unsigned long * */);
X/* cookedkey[96]
X * Loads the 3 internal key registerS with the data in cookedkey.
X */
X
Xextern void cp3key(/* unsigned long * */);
X/* cookedkey[96]
X * Copies the contents of the 3 internal key registerS into the storage
X * located at &cookedkey[0].
X */
X
Xextern void make3key(/* char *, unsigned char * */);
X/* *password, triple-length key[24]
X * With a triple-length default key, this routine hashes a NULL-terminated
X * string into a twenty-four-byte random-looking key, suitable for use with
X * the des3key() routine.
X */


X
X#endif /* D3_DES */
X#endif /* D2_DES */
X

X/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
X ********************************************************************/
END_OF_FILE
if test 4546 -ne `wc -c <'Circ/d3des/d3des.h'`; then
echo shar: \"'Circ/d3des/d3des.h'\" unpacked with wrong size!
fi
# end of 'Circ/d3des/d3des.h'
fi
if test -f 'Circ/new.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/new.c'\"
else
echo shar: Extracting \"'Circ/new.c'\" \(11955 characters\)
sed "s/^X//" >'Circ/new.c' <<'END_OF_FILE'
X
X#include <stdio.h>
X#include <unistd.h> /* R_OK */
X#include <sys/dir.h> /* MAXFNAMLEN */
X


Xchar *en_crypt(),*de_crypt(); /* external, in crypt.c */
X

X/* defines for encoding and decoding */
X#define KEYLEN 24+1 /* size of keys */
X#define MAXKEYS 30 /* number of keys we keep track of */
X#define HUGE 1024 /* big size for buffers */


X#define SECKEY "secret" /* secret key file, should be a variable */

X#define LINELEN 65 /* must be less than 90, line wrap */
X /* why? irc message length limits */
X
X/* keys database */
Xchar keys[MAXKEYS][KEYLEN]; /* the actual keys */


Xunsigned int sers[MAXKEYS]; /* serial numbers */
X

X/* globals for irc interface */
Xint nickvalid = 0; /* tells if 'nick' has valid data */
Xchar *nick,ournick[50]; /* dest nick and our nick */
X
X/* strings sent to ircII script */
X#define S_TOSCREEN "TSCREEN:"
X#define S_TONICK "TNICKNM:"
X#define S_TOCHAN "TCHANNL:"
X/* output routines */
X#define TO_SCREEN(str) (printf("%s %s\n",S_TOSCREEN,(str)))
X#define TO_SCRKEY(str) (printf("%s K<%s> %s\n",S_TOSCREEN,\
X (nickvalid)?nick:"???",(str)))
X#define TO_SCRENC(str) (printf("%s E<%s> %s\n",S_TOSCREEN,\
X (nickvalid)?nick:"???",(str)))
X#define TO_REMOTE(str) ((nickvalid)?\
X printf("%s %s %s\n",S_TONICK,nick,(str)):\
X printf("%s %s\n",S_TOCHAN,(str)))
X
X
X/* find_path()
X * return path to file if can find it.
X * look in current dir first, then in $KEYDIR then in
X * ./pubkeys directory.
X * if not found.. return null
X */
Xchar *find_path(name)
Xchar *name;
X{
X char *path;
X static char fname[MAXNAMLEN];
X
X if(access(name,R_OK)==0) return(name);
X if(path=(char *)getenv("KEYDIR")) {
X sprintf(fname,"%s/%s",path,name);
X if(access(fname,R_OK)==0) return(fname);
X }
X sprintf(fname,"pubkeys/%s",name);
X if(access(fname,R_OK)==0) return(fname);

X if((rand()&0x03) == 0) buf[i++]=' '; /* wow, now it has spaces! */


X }
X buf[i]='\0';
X return(buf);
X}
X
X/* encode(str)
X str - an ascii null-terminated string

X encoding:
X CLIPPER:xxxx:yyyyyyyyyyyyy
X xxxx - serial number of key used
X yyyyy- ascii coded, encrypted text message

X Note: only prints LINELEN characters per message. does
X line wrap.
X return - nothing, prints results to remote
X */
Xencode(str)
Xchar *str;
X{
X int l,ser,a,i;
X char buf[HUGE];
X char tmp[LINELEN+5];

X char *p;
X
X set_key(keys[0]); /* use our key and our serial number */

X a=strlen(str);
X while (a>LINELEN) { /* do line wrap */
X for(i=LINELEN;i>0;i--)
X if(isspace(str[i])) break;
X if(i==0)
X i=LINELEN; /* couldnt break at a space */
X else
X i++; /* put spaces on the same line */
X strncpy(tmp,str,i);
X tmp[i]='\0';
X p=en_crypt(tmp,i+2,&l);
X sprintf(buf,"CLIPPER:%d:%s",sers[0],bintoasc(p,l));
X TO_REMOTE(buf);
X a-=i; /* skip over what we just outputed */
X str+=i;
X }
X p=en_crypt(str ,a+1,&l); /* add 1 so we get the NULL too */
X sprintf(buf,"CLIPPER:%d:%s",sers[0],bintoasc(p,l));
X TO_REMOTE(buf);
X}
X
X/* decode(str)
X str - ascii string, null terminated


X coding: see encode()
X error codes are returned as human readable strings.
X
X CLIPPER:xxxx:yyyyyy
X x - ascii serial number
X y - ascii encoded binary data, crypted
X SKPJACK:xxxx:yyyy:zzzz
X x - nick name of destination
X y - serial number of key being received
X z - ascii encoded binary data, encrypted with rsa
X in 'nick's public key , contains the key
X needed to read messages from nick

X returned - nothing, results output to screen
X */
Xdecode(str)
Xchar *str;


X{
X char *p; /* lots of chars */

X char buf[HUGE];
X int i,ser,l,a,itsakey=0,len;
X
X if(strncmp(str,"SKPJACK:",8)==0)

X itsakey=1; /* someones sending a key */

X else if(strncmp(str,"CLIPPER:",8))

X return(0); /* not encoded */

X for(i=8;str[i]!=':'&&str[i]!='\0';i++); /* jump past ser # */
X if(str[i]!=':') {
X TO_SCRENC("*Badly Formed*");
X return(0);
X }
X str[i++]='\0';
X ser=atoi(str+8); /* this is ser # */
X
X if(itsakey && casecmp(str+8,ournick)==0) { /* new key sent to us */
X ser=atoi(str+i);
X for(;str[i]!=':'&&str[i]!='\0';i++) ;
X if(str[i++]!=':') {
X TO_SCRKEY("*Newkey: badly formed*");
X return(0);
X }
X p=asctobin(str+i,&len);
X if(!p) {
X TO_SCRKEY("*new key: bad coding*");
X return(0);
X }


X memcpy(buf,p,len); /* copy binary data */

X p=find_path(SECKEY);
X if (!p) {
X TO_SCRKEY("*Newkey: 'secret' not found!*");
X return(0);
X }
X if(do_rsa(p,buf,len,HUGE)<0) {
X TO_SCRKEY("*new key: couldnt decrypt (rsa)*");
X return(0);


X }
X for(i=0;i<MAXKEYS;i++)

X if(sers[i]==0 || sers[i]==ser) break;

X if(i==MAXKEYS) {
X TO_SCRKEY("*new key: out of table entries*");
X return(0);
X }
X if(sers[i]==ser) {


X /* *never* receive a key we already have */
X /* this could be a trick */

X TO_SCRKEY("*new key: already have it!*");
X return(0);
X }


X sers[i]= ser;
X memcpy(keys[i],buf,KEYLEN);

X TO_SCRKEY("*New Key installed*");
X return(0);
X }
X if (itsakey) {
X sprintf(buf,"*Saw key for %s*",str+8);
X TO_SCRKEY(buf);
X return(0);
X }


X
X /* else its a message , try to decode */
X
X a=key(ser); /* find the key */

X if(a==-1) {
X TO_SCRENC("*Dont Have the Key*");
X return(0);
X }
X set_key(keys[a]);
X p=asctobin(str+i,&len); /* decrypt it */
X if(!p) {
X TO_SCRENC("*Bad Encoding*");
X return(0);
X }
X TO_SCRENC(de_crypt(p,len,&l));
X return(0);
X}
X


X/* key(ser)
X ser = serial number
X returned - index to the key with serial number ser, else -1
X */
Xint key(ser)
Xint ser;
X{
X int i;
X
X for(i=0;i<MAXKEYS;i++)
X if(ser == sers[i]) return(i);
X return(-1);
X}
X
X/* sendkey(line)
X line - char *, everything after /key on the command line
X parsed to 'nick' and the optional 'filename'
X filename is set to nick if it doesnt exist.

X returned - nothing, outputs to remote (errors to screen)


X encodes our key and serial number with nick's public
X key and sends it over the current channel for him
X to receive
X */
Xsendkey(line) /* handle /key nick [filename] */
Xchar *line;
X{

X char *file,*p;


X char buf[1024];
X int len;
X
X while(*line==' ') line++;
X nick=line;
X while(*line!=' '&&*line!='\0'&&*line!='\n') line++;
X if(*line=='\n') *line='\0';
X if(*line=='\0')
X file=nick;
X else {
X *line++='\0';
X file=line;
X while(*line!=' '&&*line!='\0'&&*line!='\n') line++;
X *line='\0';
X }
X if(*nick=='\0') {

X TO_SCREEN("*ERROR* nick missing, /key nick [file]");


X return;
X }
X
X memcpy(buf,keys[0],KEYLEN);

X p=find_path(file);
X if(!p) {
X sprintf(buf,"*Error* public key file '%s' not found",file);
X TO_SCREEN(buf);
X return(0);
X }
X len=do_rsa(p,buf,KEYLEN,1024);
X if(len<0) {
X sprintf(buf,"*ERROR* public key file corrupt for %s",file);
X TO_SCREEN(buf);
X return(0); /* couldnt send it, RSA failed */
X }
X p=bintoasc(buf,len);
X sprintf(buf,"SKPJACK:%s:%d:%s",
X nick,sers[0],p);
X nickvalid=1; /* send it to their nick */
X TO_REMOTE(buf);
X}
X
X/* everything above this line (excluding some #include's and #defines)
X is for encoding and decoding messages.
X */


Xmain(argc, argv)
X int argc;
X char **argv;
X{

X int i;
X
X /* pick random key -> K */


X /* encrypt crypt(K,K) -> serial number */

X /* pick random L */


X /* encrypt crypt(L,K) -> our DES key */
X
X srand(time(0));
X for(i=0;i<KEYLEN;i++)
X keys[0][i]= (char)((rand()&0xff00)>>8);
X set_key(keys[0]);
X en_crypt(keys[0],KEYLEN,&i);
X sers[0] = (int) *((int *)keys[0]); /* pick serial number */
X /* if(sers[0]<0) sers[0]=-sers[0]; /* problem with negative ser #'s */
X for(i=0;i<KEYLEN;i++)
X keys[0][i]= (char)((rand()&0xff00)>>8);
X en_crypt(keys[0],KEYLEN,&i);
X

X strcpy(ournick,"*invalid*"); /* dont know yet */
X
X do_it();
X}
X
X/* gets messages from ircII, sends em back to ircII
X messages can be from either user, or remote users
X and to local screen or to remote users.
X to distinguish, client stuff passes it to use with
X special headers:
X optionally preceeded by:
X !nick! nickname of sending party for
X CLIPPER: and SKIPJACK:
X nickname of destination for key SENDKEY:
X CRYPTME:
X to us from remote users
X CLIPPER: encrypted message
X SKPJACK: key exchange
X to us from local user
X CRYPTME: to be encrypted
X SENDKEY: send key to another user
X QUITDIE: shut down.. die, etc.
X OURNICK: tell us what our current nick is
X to ircII
X TSCREEN: to users screen
X TCHANNL: to current channel
X TNICKNM: to specified (following) nickname
X */
X
X#define NUMTOK 6
Xchar *tok[NUMTOK] = {
X "CLIPPER:","SKPJACK:","CRYPTME:","SENDKEY:","QUITDIE:","OURNICK:",
X};
X
Xdo_it() /* main loop here */
X{
X char buf[1024],*str;
X char temp[1024];
X int i;
X
X while(1) {
X if(gets(buf)==NULL) /* input line from irc */
X return;
X str=buf;
X nickvalid=0;
X if(*str == '!') {
X nick= ++str;
X while(*str!='!' && *str!='\0') str++;
X if (*str!='\0')
X *str++='\0';
X nickvalid=1;
X } else nick="!dunno!";
X for(i=0;i<NUMTOK;i++)
X if(strncmp(str,tok[i],8)==0) break;
X switch(i) {
X case 0: /* encrypted message */
X case 1: /* new key sent to us */
X decode(str);
X break;
X case 2: /* message to be encrypted */
X encode(str+8);
X break;
X case 3: /* send a key to a user */
X sendkey(str+8);
X break;
X case 4: /* get out of dodge, and quick */
X return;
X case 5: /* update ournick */
X strcpy(ournick,str+8);
X break;
X
X case NUMTOK:
X default: /* no prefix, encrypt it */
X encode(str);
X break;
X }
X fflush(stdout);
X }
X}
X
END_OF_FILE
if test 11955 -ne `wc -c <'Circ/new.c'`; then
echo shar: \"'Circ/new.c'\" unpacked with wrong size!
fi
# end of 'Circ/new.c'
fi
echo shar: End of archive 2 \(of 3\).
cp /dev/null ark2isdone

Timothy Newsham

unread,
Jun 19, 1993, 3:31:31 AM6/19/93
to
Submitted-by: new...@wiliki.eng.hawaii.edu (Timothy Newsham)
Posting-number: Volume 38, Issue 12
Archive-name: circ/part03
Environment: C UNIX

#! /bin/sh


# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.

# Contents: Circ/LOG Circ/Makefile Circ/RSA/MANIFEST
# Circ/RSA/Make.amiga Circ/RSA/Make.unix Circ/RSA/Makefile
# Circ/RSA/README Circ/RSA/README.english Circ/RSA/WARNING
# Circ/RSA/arith.h Circ/RSA/genprim.c Circ/RSA/genrsa.c
# Circ/RSA/makekey Circ/RSA/nio.h Circ/RSA/patchlevel.h
# Circ/RSA/prim.h Circ/RSA/rnd.c Circ/RSA/rnd.h Circ/RSA/rsa.hdr
# Circ/RSA/test.c Circ/crypt.c Circ/crypt.irc2 Circ/d3des/main.c
# Circ/d3des/readme Circ/ignore.irc Circ/pubkeys/al Circ/sock.h
# POSTER
# Wrapped by alecm@uk-usenet on Sat Jun 19 08:26:21 1993


PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 3 (of 3)."'
if test -f 'Circ/LOG' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/LOG'\"
else
echo shar: Extracting \"'Circ/LOG'\" \(20 characters\)
sed "s/^X//" >'Circ/LOG' <<'END_OF_FILE'
X16 cycles
X25 cycles
END_OF_FILE
if test 20 -ne `wc -c <'Circ/LOG'`; then
echo shar: \"'Circ/LOG'\" unpacked with wrong size!
fi
# end of 'Circ/LOG'
fi
if test -f 'Circ/Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/Makefile'\"
else
echo shar: Extracting \"'Circ/Makefile'\" \(1048 characters\)
sed "s/^X//" >'Circ/Makefile' <<'END_OF_FILE'
X
X# Make:
X# all - make 'new' and make keys.
X# sock - make 'sock'
X# new - make 'new'
X# clean - remove .o's and core
X# clobber - remove everything that can be made with Make
X# archive - archive into a tar.Z in directory above us.
X
X# $IRCNICK should hold your irc nickname, change this
X# if you dont have $IRCNICK set already (else will use $LOGNAME)
XNICK = public
X
Xnew : new.o d3des.o crypt.o RSA/do_rsa.o
X cc new.o d3des.o crypt.o RSA/do_rsa.o -o new
X
Xall : new keys
X
Xsock : sock2.o d3des.o crypt.o RSA/do_rsa.o
X cc sock2.o d3des.o crypt.o RSA/do_rsa.o -o sock
X
Xkeys : RSA/genprim RSA/genrsa
X cd RSA;makekey $(NICK)
X
XRSA/genprim :
X cd RSA;make genprim
X
XRSA/genrsa :
X cd RSA;make genrsa
X
Xsock2.o : sock2.c sock.h
X
Xnew.o : new.c
X
Xd3des.o : d3des/d3des.c d3des/d3des.h
X cc -O -c d3des/d3des.c
X
Xcrypt.o : crypt.c
X
XRSA/do_rsa.o : RSA/rsa.c
X cd RSA;make do_rsa.o
X
Xclean :
X rm -f RSA/*.o *.o core
X
Xclobber :
X rm -f RSA/*.o *.o new sock secret RSA/genrsa RSA/genprim core
X
Xarchive :
X cd ..;tar -cf irc.tar irc;compress irc.tar
END_OF_FILE
if test 1048 -ne `wc -c <'Circ/Makefile'`; then
echo shar: \"'Circ/Makefile'\" unpacked with wrong size!
fi
# end of 'Circ/Makefile'
fi
if test -f 'Circ/RSA/MANIFEST' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/MANIFEST'\"
else
echo shar: Extracting \"'Circ/RSA/MANIFEST'\" \(389 characters\)
sed "s/^X//" >'Circ/RSA/MANIFEST' <<'END_OF_FILE'
XMakefile
Xconf.h gundlegende Definitionen
Xarith.c grundlegende arithmetische Routinen
Xarith.h
Xprim.c Routinen zur probabilistischen Primzahl-Berechnung
Xprim.h
Xnio.c IO-Routinen
Xnio.h
Xrnd.c Zufalls-Zahl Erzeugungs Routinen
Xrnd.h
Xgenprim.c Erzeugung von Primzahlen mit vorgegebener Stellenzahl
Xgenrsa.c Erzeugung der oeffendlichen/geheimen Schluessel
Xrsa.c Ver/Entschluesselung
END_OF_FILE
if test 389 -ne `wc -c <'Circ/RSA/MANIFEST'`; then
echo shar: \"'Circ/RSA/MANIFEST'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/MANIFEST'
fi
if test -f 'Circ/RSA/Make.amiga' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/Make.amiga'\"
else
echo shar: Extracting \"'Circ/RSA/Make.amiga'\" \(768 characters\)
sed "s/^X//" >'Circ/RSA/Make.amiga' <<'END_OF_FILE'
X
XCFLAGS = -dAUTOKEY -dSTANDALONE
X
Xall: genprim genrsa rsa
X
Xgenprim: genprim.o rnd.o prim.o nio.o arith.o
X blink from lib:c.o,genprim.o,rnd.o,nio.o,prim.o,arith.o to genprim lib lib:lc.lib,lib:amiga.lib,lib:lcm.lib
X
Xgenrsa: genrsa.o rnd.o prim.o nio.o arith.o
X blink from lib:c.o,genrsa.o,rnd.o,nio.o,prim.o,arith.o to genrsa lib lib:lc.lib,lib:amiga.lib,lib:lcm.lib
X
X
Xrsa: rsa.o nio.o arith.o
X blink lib:c.o,rsa.o,nio.o,arith.o to rsa lib lib:lc.lib,lib:amiga.lib
X copy rsa rsaencode #ln rsa rsaencode
X copy rsa rsadecode #ln rsa rsadecode
X
X#rsa.o genrsa.o genprim.o nio.o prim.o arith.o: conf.h
X#rsa.o genrsa.o genprim.o nio.o prim.o arith.o: arith.h
X#rsa.o genrsa.o genprim.o nio.o: nio.h
X#genrsa.o genprim.o prim.o: prim.h
X#genrsa.o genprim.o rnd.o: rnd.h
X
X
X
END_OF_FILE
if test 768 -ne `wc -c <'Circ/RSA/Make.amiga'`; then
echo shar: \"'Circ/RSA/Make.amiga'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/Make.amiga'
fi
if test -f 'Circ/RSA/Make.unix' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/Make.unix'\"
else
echo shar: Extracting \"'Circ/RSA/Make.unix'\" \(1013 characters\)
sed "s/^X//" >'Circ/RSA/Make.unix' <<'END_OF_FILE'
X
X# if you want an executable, -DSTANDALONE while compiling
X# rsa.c, and uncomment the ln's below
X
XSHELL=/bin/sh
X
X# add -DSTANDALONE to CFLAGS if you want a standalone
X#CFLAGS= -O +Aa
XCFLAGS= -DAUTOKEY -O # -g
XLDFLAGS=
X
Xall: genprim genrsa rsa # do_rsa.o
X
Xgenprim: genprim.o rnd.o prim.o nio.o arith.o
X $(CC) $(LDFLAGS) -o genprim genprim.o rnd.o nio.o prim.o arith.o
X
Xgenrsa: genrsa.o rnd.o prim.o nio.o arith.o
X $(CC) $(LDFLAGS) -o genrsa genrsa.o rnd.o nio.o prim.o arith.o
X
Xdo_rsa.o: rsa.o nio.o arith.o
X $(CC) $(LDFLAGS) -C -o do_rsa.o rsa.o nio.o arith.o
X
Xrsa: test.o rsa.c nio.o arith.o
X $(CC) $(LDFLAGS) -o rsa -DSTANDALONE rsa.c nio.o arith.o
X ln rsa rsaencode
X ln rsa rsadecode
X
Xrsa.o genrsa.o genprim.o nio.o prim.o arith.o: conf.h
Xrsa.o genrsa.o genprim.o nio.o prim.o arith.o: arith.h
Xrsa.o genrsa.o genprim.o nio.o: nio.h
Xgenrsa.o genprim.o prim.o: prim.h
Xgenrsa.o genprim.o rnd.o: rnd.h
X
Xclean:
X rm -f *.bak *.ba *~ \#* core *.o
X
Xclobber: clean
X rm -f genrsa genprim rsa rsadecode rsaencode
END_OF_FILE
if test 1013 -ne `wc -c <'Circ/RSA/Make.unix'`; then
echo shar: \"'Circ/RSA/Make.unix'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/Make.unix'
fi
if test -f 'Circ/RSA/Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/Makefile'\"
else
echo shar: Extracting \"'Circ/RSA/Makefile'\" \(1021 characters\)
sed "s/^X//" >'Circ/RSA/Makefile' <<'END_OF_FILE'
X
X# if you want an executable, -DSTANDALONE while compiling
X# rsa.c, and uncomment the ln's below
X
XSHELL=/bin/sh
X
X# add -DSTANDALONE to CFLAGS if you want a standalone
X#CFLAGS= -O +Aa
XCFLAGS= -DAUTOKEY -O # -g
XLDFLAGS=
XLD = ld
X
Xall: genprim genrsa rsa # do_rsa.o
X
Xgenprim: genprim.o rnd.o prim.o nio.o arith.o
X $(CC) $(LDFLAGS) -o genprim genprim.o rnd.o nio.o prim.o arith.o
X
Xgenrsa: genrsa.o rnd.o prim.o nio.o arith.o
X $(CC) $(LDFLAGS) -o genrsa genrsa.o rnd.o nio.o prim.o arith.o
X
Xdo_rsa.o: rsa.o nio.o arith.o
X $(LD) $(LDFLAGS) -r -o do_rsa.o rsa.o nio.o arith.o
X
Xrsa: test.o rsa.c nio.o arith.o
X $(CC) $(LDFLAGS) -o rsa -DSTANDALONE rsa.c nio.o arith.o
X ln rsa rsaencode
X ln rsa rsadecode
X
Xrsa.o genrsa.o genprim.o nio.o prim.o arith.o: conf.h
Xrsa.o genrsa.o genprim.o nio.o prim.o arith.o: arith.h
Xrsa.o genrsa.o genprim.o nio.o: nio.h
Xgenrsa.o genprim.o prim.o: prim.h
Xgenrsa.o genprim.o rnd.o: rnd.h
X
Xclean:
X rm -f *.bak *.ba *~ \#* core *.o
X
Xclobber: clean
X rm -f genrsa genprim rsa rsadecode rsaencode
END_OF_FILE
if test 1021 -ne `wc -c <'Circ/RSA/Makefile'`; then
echo shar: \"'Circ/RSA/Makefile'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/Makefile'
fi
if test -f 'Circ/RSA/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/README'\"
else
echo shar: Extracting \"'Circ/RSA/README'\" \(4029 characters\)
sed "s/^X//" >'Circ/RSA/README' <<'END_OF_FILE'
X
X********************************************************************************
X* *
X* R S A - Verfahren *
X* *
X********************************************************************************
X
XDie Schluessel-Generierung laeuft in 2 Stufen ab.
X
XA) Es muessen 2 Primzahlen mit genprim berechnet werden. Die
X Groessenordnung dieser Zahlen sollte 80-130 sein, und sich um
X eine unterscheiden. Diese Zahlen muessen in einer Datei, mit
X einem beliebigen Trennzeichen (z.B. '#') dazwischen, abgelegt
X werden.
X
X Alle Zahlen werden als Hexadezimalzahlen (fuer
X Puristen: Sedizimal :-) ein-/ausgegeben. Bei
X Ein-/Ausgabe sind White-Spaces (Blank,Tab,Newline)
X nicht signifikant.
X
X Der zweite Parameter von genprim gibt die Wahrscheinlichkeit an,
X mit der die gefundene Zahl wirklich eine Primzahl ist. Fuer
X eine Parameter n ist die Wahrscheinlichkeit 1-0.5^n. Fuer n=20
X ist ein Programierfehler von mir schon wahrscheinlicher :-).
X Das der Test nur probabilistisch ist, verringert bei vernuenftiger
X Wahl von n die Aussagekraeftigkeit nur unwesendlich.
X
XB) Genrsa generiert daraus eine Datei mit oeffendlichem/geheimen
X Schluessel. Diese Datei enthaelt 3 Zahlen. Aus dieser Datei
X gewinnt man die geheime, in dem man die letzte Zahl (mit Trenn-
X zeichen) entfernt. Den oeffendlichen erhaelt man duch Entfernung
X der zweiten Zahl.
X
XBeispiel:
X $ genrsa 10 20 >p1 # erste Primzahl
X $ cat p1
X 2023A0B0BE5
X $ genrsa 11 20 >p2 # zweite Primzahl
X $ cat p2
X 537A985EC975
X $ echo "#" | cat p1 - p2 >pd # Eingabe fuer genrsa
X $ genrsa <pd >rd # Alle Zahlen fertig
X $ cat rd
X A7AF134EFB73D789793CA9
X #
X 9245F9009636D26B7CA5ED
X #
X 80F408891D5932D10C2585
X
XDieses File rd muss man auf 2 Files verteilen:
X
X $ cat geheim
X A7AF134EFB73D789793CA9
X #
X 9245F9009636D26B7CA5ED
X $ cat oeffendlich
X A7AF134EFB73D789793CA9
X #
X 80F408891D5932D10C2585
X
XDie Dateien p1,p2,pd und rd sollte man schnell wieder loeschen.
X
X $ rsaencode oeffendlich <data >crypt # Verschluesseln
X $ rsadecode geheim <crypt >clear # Entschluesseln
X
XDie Verschluesselung laeuft in Bloecken ab, deren Groesse von der der
Xersten Zahl des Schluessels Abhaengt. Alle Bloecke werden als binaere
XDaten behandelt. Allerdings wird beim Entschluesseln der letzte Block
Xmit ASCII-NULL aufgefuellt. Dieses ist kein Fehler des RSA-Verfahrens,
Xsondern liegt an meiner Verwendung. Das RSA-Verfahren verschluesselt
Xeinfach Zahlen. Meiner Umwandlung von Daten in Zahlen ist das Manko
Xanzulasten. Deshalb muss auch der verschluesselte Text mit btoa oder
Xaehnlichem mailbar gemacht werden. Zur Reduktion der Blockanzahl kann
Xman natuerlich vorher den Text compressen, da er sowieso binaer behandelt
Xwird.
X
XBei mir (386-er mit 20 MHz) dauert die Ver-/Entschluesselung eines
XBlocks (aus 125 & 124 stelliger Primzahl) 20 Minuten !!!!!!
XDafuer laeuft die Primzahlberechnung in 1-20 Stunden ab :-) !!!!!
XDas haengt von dem zufaelligen Startpunkt der Suche ab.
X
XWer Lust hat, die Verschluesselung so zu modifizieren, dass nur ein
XBlock mit RSA verschluesselt wird, und alle anderen, mit einem darin
Xuebergebenen weiteren Schuessel, mit DES zu verschluesseln, der ist
Xherzlich eingeladen ein solches Programm analog rsa.c zu erstellen.
XDie eigendliche Verschluesselung ist mit den Routinen aus arith.c
Xtrivial. Es kostet allerding Zeit :-).
X
XAls Warnung fuer Leute, die mit den Routinen arbeiten wollen:
X
XAlle Routinen sind auf Laufzeit optimiert, und enthalten fast keine
XUeberpruefungen auf Ueberlauf o.ae. . Wenn ein Fehler entdeckt wird
X(was selten ist :-), gibts eine core. Alle Zahlen muessen >= 0 sein.
X
XMein Wissen ueber RSA und die anderen verwendeten Verfahren hab ich
Xaus:
X Horster, Patrick:
X Kryptologie / von Patrick Horster. - Mannheim;
X Wien; Zuerich: Bibliographisches Institut, 1985.
X (Reihe Informatik; 47)
X ISBN 3-411-03106-9
X NE: GT
X
XMartin Nicolay ( mar...@trillian.megalon.de )
XFliederstr. 23
X4100 Duisburg 1
XW-Germany
X
XPS: Falls rand.h nicht vorhanden ist: darin sind nur die Funktionen
X wie drand48 usw. deklariert.
END_OF_FILE
if test 4029 -ne `wc -c <'Circ/RSA/README'`; then
echo shar: \"'Circ/RSA/README'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/README'
fi
if test -f 'Circ/RSA/README.english' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/README.english'\"
else
echo shar: Extracting \"'Circ/RSA/README.english'\" \(1320 characters\)
sed "s/^X//" >'Circ/RSA/README.english' <<'END_OF_FILE'
XI don't know german. But, with the help of a friend of mine who speaks
Xgerman as his first language I managed to make this program work and
Xit worked truly well indeed. Here are very brief instructions to start with
Xthis little beastie:
X
X* generate two primes 10 and 11 digits long, prime with 1/2^20
X probabilistic precision:
X
X $ genprim 10 20 >p1 # the first prime
X $ cat p1
X 2023A0B0BE5
X $ genprim 11 20 >p2 # the second one
X $ cat p2
X 537A985EC975
X $ echo "#" | cat p1 - p2 >pd # Put a `#' between the two primes
X
X* generate public and private key:
X $ genrsa <pd >rd
X $ cat rd
X A7AF134EFB73D789793CA9
X #
X 9245F9009636D26B7CA5ED
X #
X 80F408891D5932D10C2585
X
X* you have to edit the `rd' file. The secret key is obtained by
X taking the first and the second number. The public key is
X obtained by taking the first and third number.
X
X $ cat secret
X A7AF134EFB73D789793CA9
X #
X 9245F9009636D26B7CA5ED
X $ cat public
X A7AF134EFB73D789793CA9
X #
X 80F408891D5932D10C2585
X
X* now you are able to crypt / encrypt your data:
X
X $ rsaencode public <data >crypt # encryption
X $ rsadecode secret <crypt >plaintext # decryption
X
X* pure RSA encryption is used. I mean, we don't use DES or any other
X cipher to speed up the process. This means that the encryption
X process is slow.
X
X
XEnjoy! vi...@ghost.dsi.unimi.it
END_OF_FILE
if test 1320 -ne `wc -c <'Circ/RSA/README.english'`; then
echo shar: \"'Circ/RSA/README.english'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/README.english'
fi
if test -f 'Circ/RSA/WARNING' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/WARNING'\"
else
echo shar: Extracting \"'Circ/RSA/WARNING'\" \(1398 characters\)
sed "s/^X//" >'Circ/RSA/WARNING' <<'END_OF_FILE'
XThere are most certainly legal problems with using this software in the U.S.A.,
Xand probably also in several other countries, relating to a patent which
Xcovers the techniques used here.
X
XALSO BE SURE TO LOOK AT THE FILE PATCHES IN THIS DIRECTORY!!!
X
XThe following comes directly from PKP on the use of RSA within the
XU.S. and Canada. It seems to indicate that we may use RSA without
Xa licence for non-commercial purposes. I presume this applies to PGP
Xwhich is an RSA based system, but I really don't know. At least it
Xapplies to RSAREF, the library being made available by RSA Inc
Xto North American users.
X
XFor information on RSAREF send mail to rsa...@rsa.com. They'll send
Xit to you provided you state that you are either an American
Xor Canadian citizen or U.S. Permanent Resident located in the U.S.
Xor Canada and state that you agree to comply with the licence
Xagreement.
X
X"In North America, a license is needed to ``make, use or sell'' RSA. However,
XPKP has a policy that anyone may use RSA non-commercially for a
Xpersonal, academic or intellectual reason without a license; an example
Xof such use would be the implementation of RSA as a programming project
Xfor a computer class. RSA Laboratories has made available (in the U.S. and
XCanada) at no charge a collection of cryptographic routines in
Xsource code, including the RSA algorithm; it can be used for non-commercial
Xpurposes"
X
END_OF_FILE
if test 1398 -ne `wc -c <'Circ/RSA/WARNING'`; then
echo shar: \"'Circ/RSA/WARNING'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/WARNING'
fi
if test -f 'Circ/RSA/arith.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/arith.h'\"
else
echo shar: Extracting \"'Circ/RSA/arith.h'\" \(1464 characters\)
sed "s/^X//" >'Circ/RSA/arith.h' <<'END_OF_FILE'


X/*******************************************************************************
X* *
X* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
X* *
X* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
X* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
X* verwendet werden. *
X* *
X* mar...@trillian.megalon.de *
X* *
X*******************************************************************************/
X

X#ifndef _arith_h_
X#define _arith_h_
X
X#ifndef _conf_h_
X#include "conf.h"
X#endif
X
Xextern NUMBER a_one,a_two;


X
X/*
X * Prototypes
X */
X

Xvoid a_add P(( NUMBER*, NUMBER*, NUMBER* ));
Xvoid a_assign P(( NUMBER*, NUMBER* ));
Xint a_cmp P(( NUMBER*, NUMBER* ));
Xvoid a_div P(( NUMBER*, NUMBER*, NUMBER*, NUMBER* ));
Xvoid a_div2 P(( NUMBER* ));
Xvoid a_ggt P(( NUMBER*, NUMBER*, NUMBER* ));
Xvoid a_imult P(( NUMBER*, INT, NUMBER* ));
Xvoid a_mult P(( NUMBER*, NUMBER*, NUMBER* ));
Xvoid a_sub P(( NUMBER*, NUMBER*, NUMBER* ));
Xvoid m_init P(( NUMBER*, NUMBER* ));
Xvoid m_add P(( NUMBER*, NUMBER*, NUMBER* ));
Xvoid m_mult P(( NUMBER*, NUMBER*, NUMBER* ));
Xvoid m_exp P(( NUMBER*, NUMBER*, NUMBER* ));
Xint n_bits P(( NUMBER*, int));
Xvoid n_div P(( NUMBER*, NUMBER*, NUMBER*, NUMBER* ));
Xint n_cmp P(( INT*, INT*, int ));
Xint n_mult P(( INT*, INT, INT*, int ));
Xint n_sub P(( INT*, INT*, INT*, int, int ));
Xint n_bitlen P(( NUMBER* ));
X
X#endif
END_OF_FILE
if test 1464 -ne `wc -c <'Circ/RSA/arith.h'`; then
echo shar: \"'Circ/RSA/arith.h'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/arith.h'
fi
if test -f 'Circ/RSA/genprim.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/genprim.c'\"
else
echo shar: Extracting \"'Circ/RSA/genprim.c'\" \(1416 characters\)
sed "s/^X//" >'Circ/RSA/genprim.c' <<'END_OF_FILE'


X/*******************************************************************************
X* *
X* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
X* *
X* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
X* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
X* verwendet werden. *
X* *
X* mar...@trillian.megalon.de *
X* *
X*******************************************************************************/
X

X#include <stdio.h>
X
X#include "arith.h"
X#include "prim.h"
X#include "nio.h"
X#include "rnd.h"
X
Xchar *prog;
X
XNUMBER a_three,a_four;
X
Xusage()
X{
X fprintf(stderr,"usage: %s digits [probability]\n",prog);
X exit (1);


X}
X
Xmain( argc, argv )
Xchar **argv;
X{

X NUMBER prim;
X int len,i,prob;
X
X prog = argv[0];
X
X if ( argc < 2 || 3 < argc )
X usage();
X
X len = atoi( argv[1] );
X if (argc > 2)
X prob = atoi( argv[2] );
X else
X prob = 10;
X
X a_add( &a_one, &a_two, &a_three );
X a_add( &a_two, &a_two, &a_four );
X
X init_rnd();
X
X do {
X gen_number( len, &prim );
X } while ( !prim.n_len );
X
X a_mult( &prim, &a_two, &prim );
X a_mult( &prim, &a_three, &prim );
X a_add( &prim, &a_one, &prim );
X
X for (i=1 ;; i++) {
X if (p_prim( &prim, prob ))
X break;
X if (i % 2)
X a_add( &prim, &a_four, &prim );
X else
X a_add( &prim, &a_two, &prim );
X }
X fprintf(stderr,"%d cycles\n",i);
X
X num_fput( &prim, stdout );
X}
END_OF_FILE
if test 1416 -ne `wc -c <'Circ/RSA/genprim.c'`; then
echo shar: \"'Circ/RSA/genprim.c'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/genprim.c'
fi
if test -f 'Circ/RSA/genrsa.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/genrsa.c'\"
else
echo shar: Extracting \"'Circ/RSA/genrsa.c'\" \(2515 characters\)
sed "s/^X//" >'Circ/RSA/genrsa.c' <<'END_OF_FILE'


X/*******************************************************************************
X* *
X* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
X* *
X* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
X* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
X* verwendet werden. *
X* *
X* mar...@trillian.megalon.de *
X* *
X*******************************************************************************/
X

X#include <stdio.h>


X
X#include "arith.h"
X#include "nio.h"

X#include "prim.h"
X#include "rnd.h"
X
X/* files that we use if we are on autopilot */
X#ifdef AUTOKEY
X#define PUBLIC "public"
X#define PRIVATE "secret"
X#include <fcntl.h>
X#endif AUTOKEY
X
Xmain()
X{
X NUMBER p1,p2,n,d,e,phi,*max_p;
X int len;
X#ifdef AUTOKEY
X FILE *fdpub,*fdpriv;
X FILE *fd;
X
X if((fdpub=fopen(PUBLIC,"w"))==0) {
X perror(PUBLIC);
X exit(1);
X }
X if((fdpriv=fopen(PRIVATE,"w"))==0) {
X perror(PRIVATE);
X exit(1);
X }
X system("genprim 63 20 >ptemp"); /* 63 and 65 x4 bit primes */
X system("echo '#' >>ptemp"); /* 252 + 260 = 512 bit modulus */
X system("genprim 65 20 >>ptemp");
X
X fd=fopen("ptemp","r");
X if(fd==NULL) {
X printf("Cant open temp file\n");
X exit(1);
X }
X num_fget( &p1, fd ); getc(fd);
X num_fget( &p2, fd );
X fclose(fd);
X system("rm -f ptemp\n");
X#else
X num_fget( &p1, stdin ); getchar();
X num_fget( &p2, stdin );
X#endif AUTOKEY
X
X if ( !a_cmp( &p1, &p2 ) ) {
X fprintf(stderr,"the prime numbers must not be identical!\n");
X exit(1);
X }
X
X if (a_cmp( &p1, &p2 ) > 0)
X max_p = &p1;
X else
X max_p = &p2;
X
X a_mult( &p1, &p2, &n );
X
X a_sub( &p1, &a_one, &phi );
X a_sub( &p2, &a_one, &e );
X a_mult( &phi, &e, &phi );
X
X len = n_bitlen( &phi );
X len = ( len + 3 ) / 4;
X
X a_assign( &p1, &phi );
X a_sub( &p1, &a_one, &p1 );
X init_rnd();
X do {
X do {
X gen_number( len, &d );
X } while (a_cmp( &d, max_p ) <= 0 || a_cmp( &d, &p1 ) >= 0);
X
X a_ggt( &d, &phi, &e );
X } while ( a_cmp( &e, &a_one ) );
X
X
X inv( &d, &phi, &e );
X
X#ifndef AUTOKEY
X num_fput( &n, stdout ); puts("#"); fflush(stdout);
X num_fput( &d, stdout ); puts("#"); fflush(stdout);
X num_fput( &e, stdout );
X#else AUTOKEY
X /* priv is first and second of above, */
X /* public is first and third of above */
X num_fput( &n, fdpub ); fprintf(fdpub,"#\n");
X num_fput( &n, fdpriv ); fprintf(fdpriv,"#\n");
X num_fput( &d, fdpriv );
X num_fput( &e, fdpub );
X
X fclose(fdpub);
X fclose(fdpriv);
X#endif AUTOKEY
X}
X
END_OF_FILE
if test 2515 -ne `wc -c <'Circ/RSA/genrsa.c'`; then
echo shar: \"'Circ/RSA/genrsa.c'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/genrsa.c'
fi
if test -f 'Circ/RSA/makekey' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/makekey'\"
else
echo shar: Extracting \"'Circ/RSA/makekey'\" \(420 characters\)
sed "s/^X//" >'Circ/RSA/makekey' <<'END_OF_FILE'
X#!/bin/sh
X
XNICK=$1
X
Xif [ $IRCNICK ]
Xthen
X NICK=$IRCNICK;
Xelse
X if [ $LOGNAME ]
X then
X NICK=$LOGNAME;
X else
X if [ $USER ]
X then
X NICK=$USER
X fi
X fi
Xfi
Xecho "Making keys."
Xecho "Putting secret key in file 'secret' and"
Xecho "public key in file '$NICK'"
Xecho "This takes a while. Putting the job in the background."
X (genrsa 2>../LOG; mv public ../$NICK; mv secret ..; echo "Done making keys" ) &
X
END_OF_FILE
if test 420 -ne `wc -c <'Circ/RSA/makekey'`; then
echo shar: \"'Circ/RSA/makekey'\" unpacked with wrong size!
fi
chmod +x 'Circ/RSA/makekey'
# end of 'Circ/RSA/makekey'
fi
if test -f 'Circ/RSA/nio.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/nio.h'\"
else
echo shar: Extracting \"'Circ/RSA/nio.h'\" \(780 characters\)
sed "s/^X//" >'Circ/RSA/nio.h' <<'END_OF_FILE'


X/*******************************************************************************
X* *
X* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
X* *
X* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
X* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
X* verwendet werden. *
X* *
X* mar...@trillian.megalon.de *
X* *
X*******************************************************************************/
X

X#ifndef _nio_h_
X#define _nio_h_
X
X#ifndef _arith_h_
X#include "arith.h"
X#endif
X
X/*
X * Prototypes
X */
X
Xint num_sput P(( NUMBER*, char*, int ));
Xint num_fput P(( NUMBER*, FILE* ));
Xint num_sget P(( NUMBER*, char* ));
Xint num_fget P(( NUMBER*, FILE* ));
X
X#endif
END_OF_FILE
if test 780 -ne `wc -c <'Circ/RSA/nio.h'`; then
echo shar: \"'Circ/RSA/nio.h'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/nio.h'
fi
if test -f 'Circ/RSA/patchlevel.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/patchlevel.h'\"
else
echo shar: Extracting \"'Circ/RSA/patchlevel.h'\" \(32 characters\)
sed "s/^X//" >'Circ/RSA/patchlevel.h' <<'END_OF_FILE'
X#define PATCHLEVEL 1
END_OF_FILE
if test 32 -ne `wc -c <'Circ/RSA/patchlevel.h'`; then
echo shar: \"'Circ/RSA/patchlevel.h'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/patchlevel.h'
fi
if test -f 'Circ/RSA/prim.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/prim.h'\"
else
echo shar: Extracting \"'Circ/RSA/prim.h'\" \(688 characters\)
sed "s/^X//" >'Circ/RSA/prim.h' <<'END_OF_FILE'


X/*******************************************************************************
X* *
X* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
X* *
X* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
X* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
X* verwendet werden. *
X* *
X* mar...@trillian.megalon.de *
X* *
X*******************************************************************************/
X

X#ifndef _prim_h_
X#define _prim_h_
X
X#ifndef _arith_h_
X#include "arith.h"
X#endif
X
Xint p_prim P(( NUMBER*, int ));
Xvoid inv P(( NUMBER*, NUMBER*, NUMBER* ));
X
X#endif
END_OF_FILE
if test 688 -ne `wc -c <'Circ/RSA/prim.h'`; then
echo shar: \"'Circ/RSA/prim.h'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/prim.h'
fi
if test -f 'Circ/RSA/rnd.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/rnd.c'\"
else
echo shar: Extracting \"'Circ/RSA/rnd.c'\" \(1177 characters\)
sed "s/^X//" >'Circ/RSA/rnd.c' <<'END_OF_FILE'


X/*******************************************************************************
X* *
X* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
X* *
X* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
X* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
X* verwendet werden. *
X* *
X* mar...@trillian.megalon.de *
X* *
X*******************************************************************************/
X

X#include <stdio.h>
X
X#include "rnd.h"
X
X#include "nio.h"
X
Xvoid gen_number( len, n )
XNUMBER *n;
X{
X char *hex = "0123456789ABCDEF" ;
X char num[ MAXLEN*MAXBIT/4 +1 ];
X char *p;
X int i,l;
X
X p= &num[ sizeof(num) -1];
X *p-- = '\0';
X
X for (l=len; l--; p-- ) {
X i = lrand48() % 16;
X *p = hex[ i ];
X }
X p++;
X
X while (len-- && *p == '0')
X p++;
X
X num_sget( n, p );
X}
X
X#ifdef AMIGA
Xint getpid() /* we got no getpid on amiga */
X{
X return(time((long *)0));
X}
X#endif
X
Xvoid init_rnd()
X{
X long time();
X short seed[3];
X
X seed[0] = time((long *)0) & 0xFFFF;
X seed[1] = getpid() & 0xFFFF;
X seed[2] = (time((long *)0) >> 16) & 0xFFFF;
X (void)seed48( seed );
X}
X
X
END_OF_FILE
if test 1177 -ne `wc -c <'Circ/RSA/rnd.c'`; then
echo shar: \"'Circ/RSA/rnd.c'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/rnd.c'
fi
if test -f 'Circ/RSA/rnd.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/rnd.h'\"
else
echo shar: Extracting \"'Circ/RSA/rnd.h'\" \(673 characters\)
sed "s/^X//" >'Circ/RSA/rnd.h' <<'END_OF_FILE'


X/*******************************************************************************
X* *
X* Copyright (c) Martin Nicolay, 22. Nov. 1988 *
X* *
X* Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten *
X* bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter *
X* verwendet werden. *
X* *
X* mar...@trillian.megalon.de *
X* *
X*******************************************************************************/
X

X#ifndef _rnd_h_
X#define _rnd_h_
X
X#ifndef _arith_h_
X#include "arith.h"
X#endif
X
Xvoid gen_number P(( int, NUMBER* ));
Xvoid init_rnd P(( void ));
X
X#endif
END_OF_FILE
if test 673 -ne `wc -c <'Circ/RSA/rnd.h'`; then
echo shar: \"'Circ/RSA/rnd.h'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/rnd.h'
fi
if test -f 'Circ/RSA/rsa.hdr' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/rsa.hdr'\"
else
echo shar: Extracting \"'Circ/RSA/rsa.hdr'\" \(1342 characters\)
sed "s/^X//" >'Circ/RSA/rsa.hdr' <<'END_OF_FILE'
XFrom: mar...@trillian.UUCP (Martin Nicolay)
XNewsgroups: sub.sources.unix,sub.sources.misc
XSubject: RSA-Routinen
XDate: 22 Nov 88 02:24:25 GMT
XReply-To: mar...@trillian.megalon.de (Martin Nicolay)
XOrganization: Home
XXref: lan sub.sources.unix:2 sub.sources.misc:10
X
XIch hab eine Implementation des RSA-Verfahrens (Public-Key-Crypt) zusammen
Xgestrickt. Enthalten sind dafuer auch Funktionen fuer Arithmetik mit grossen
XZahlen (obere Schranke ist Compile-Option).
X
XJetzt kann endlich kein Sysop mehr die private Post lesen :-).
X
XDas Programm, dass den Text verschluesselt, ist noch verbesserungswuerdig.
XZ.B. nur einen Block mit RSA (weil rechenintensiv) verschluesseln und darin
Xeine Key uebergeben, mit dem der Rest mit DES verschluesselt wird.
X
XViel Spass bei der sicheren Mail!
X
XPS: Mein oeffendlicher Schluessel ist :
X 10875FDCBBC59099500630B241458A52B1830D35E6816A739C74534E8017E3F1
X B9ACB73BDC84C47F954047EAFFBE0EFD5499B4431C815130766E78ED0F1E671D
X F926171D67BDECB92374AAB07629C5F0263FCCDCD920F7D90779A8CF439538B1
X 6FAF35CE95A06051A6BFD3A7D7AF8B51FE8545C439E4C9F0ADAB7E13303
X #
X C6A65AE2A755FFE2026134AF1B8EC469017D0D9F3884F4D1132D273F066DBE57
X 86960811590F6873E52792D387604168183A7C22AA9FDF0F401454C4E65CE274
X 78C94992F154F380886E2F410707209665B5629864A358EDE68E0C11F94DA275
X 4C84D5F8BE6D7A6DC516FB6C4A4D7ABF13E701CCB2B8ED937E50438C2D
X
END_OF_FILE
if test 1342 -ne `wc -c <'Circ/RSA/rsa.hdr'`; then
echo shar: \"'Circ/RSA/rsa.hdr'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/rsa.hdr'
fi
if test -f 'Circ/RSA/test.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/RSA/test.c'\"
else
echo shar: Extracting \"'Circ/RSA/test.c'\" \(453 characters\)
sed "s/^X//" >'Circ/RSA/test.c' <<'END_OF_FILE'
X
X#include <fcntl.h>
X
Xmain()
X{
X char buf[8192];
X char *data="hey there\n";
X int a,x,log1,log2;
X
X log1=open("log1",O_CREAT|O_WRONLY);
X log2=open("log2",O_CREAT|O_WRONLY);
X a=(char)strlen(data);
X strcpy(buf+1,"hey there.\n");
X buf[0]=a;
X x=do_rsa("public",buf,a+1,8192);
X write(log1,buf,8192);
X do_rsa("secret",buf,x);
X write(log2,buf,8192);
X close(log1);
X close(log2);
X write(1,buf+1,(int) buf[0]);
X write(1,"\n",1);
X
X}
END_OF_FILE
if test 453 -ne `wc -c <'Circ/RSA/test.c'`; then
echo shar: \"'Circ/RSA/test.c'\" unpacked with wrong size!
fi
# end of 'Circ/RSA/test.c'
fi
if test -f 'Circ/crypt.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/crypt.c'\"
else
echo shar: Extracting \"'Circ/crypt.c'\" \(608 characters\)
sed "s/^X//" >'Circ/crypt.c' <<'END_OF_FILE'
X
X#include "d3des/d3des.h"
X
X#define HUGE 1024
X
Xunsigned long enkey[96],dekey[96];
X
Xchar *en_crypt(buf,len,len2)
Xchar *buf;
Xint len,*len2;
X{
X static char ret[HUGE];
X int i;
X
X use3key(enkey);
X for(i=0;i<len;i+=8)
X Ddes(buf+i,ret+i);
X *len2=i;
X return(ret);
X}
X
Xchar *de_crypt(buf,len,len2)
Xchar *buf;
Xint len,*len2;
X{
X static char ret[HUGE];
X int i;
X
X use3key(dekey);
X for(i=0;i<len;i+=8)
X Ddes(buf+i,ret+i);
X *len2=i;
X return(ret);
X}
X
Xset_key(key)
Xchar *key;
X{
X des3key(key,0);
X cp3key(enkey); /* set encryption key */
X des3key(key,1);
X cp3key(dekey); /* set decryption key */
X}
X
END_OF_FILE
if test 608 -ne `wc -c <'Circ/crypt.c'`; then
echo shar: \"'Circ/crypt.c'\" unpacked with wrong size!
fi
# end of 'Circ/crypt.c'
fi
if test -f 'Circ/crypt.irc2' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/crypt.irc2'\"
else
echo shar: Extracting \"'Circ/crypt.irc2'\" \(1550 characters\)
sed "s/^X//" >'Circ/crypt.irc2' <<'END_OF_FILE'
X# this is ver ircII 2.2.4
X# for some reason, /on ^public acts differently
X


X# Start up the proggie
X/^exec -name crypt exec new
X
X# automatically pick out protocol messages
X# crypt processor gets: !send nick!CLIPPER:...etc
X# or !our nick!SKPJACK:...etc

X# under 2.2.4 public has: nick channel message
X# the version I use has nick message
X# this is the difference between the two script versions
X/on ^public "* * CLIPPER:*" /msg %crypt !$0!$2-
X/on ^public "* * SKPJACK:*" /msg %crypt OURNICK:$N;/msg %crypt !$0!$2-

if test 1550 -ne `wc -c <'Circ/crypt.irc2'`; then
echo shar: \"'Circ/crypt.irc2'\" unpacked with wrong size!
fi
# end of 'Circ/crypt.irc2'
fi
if test -f 'Circ/d3des/main.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/d3des/main.c'\"
else
echo shar: Extracting \"'Circ/d3des/main.c'\" \(711 characters\)
sed "s/^X//" >'Circ/d3des/main.c' <<'END_OF_FILE'
X
X#include "d3des.h"
Xunsigned long enkey[96],dekey[96];
Xunsigned long e1[32],e2[32],e3[32];
Xunsigned long d1[32],d2[32],d3[32];
X
Xmain()
X{
X char *a,b[100],*k,*k1,*k2,*k3;
X
X strcpy(b,"this is a test");
X k="testing123423456789212345678";
X k1="testing1";
X k2="23423456";
X k3="78921234";
X deskey(k1,0); cpkey(e1);
X deskey(k2,1); cpkey(d2);
X deskey(k3,0); cpkey(e3);
X des3key(k,0); cp3key(enkey); /* set up long keys , encrypt */
X des3key(k,1); cp3key(dekey); /* decrypt */
X use3key(enkey); Ddes(b,b); /* encrypt b */
X write(1,b,16);
X use3key(dekey); Ddes(b,b); /* decrypt b */
X write(1,b,16);
X
X usekey(e1); des(b,b);
X usekey(d2); des(b,b);
X usekey(e3); des(b,b);
X write(1,b,16);
X}
X
END_OF_FILE
if test 711 -ne `wc -c <'Circ/d3des/main.c'`; then
echo shar: \"'Circ/d3des/main.c'\" unpacked with wrong size!
fi
# end of 'Circ/d3des/main.c'
fi
if test -f 'Circ/d3des/readme' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/d3des/readme'\"
else
echo shar: Extracting \"'Circ/d3des/readme'\" \(286 characters\)
sed "s/^X//" >'Circ/d3des/readme' <<'END_OF_FILE'
XThis code by Richard Outerbridge implements DES with optional
Xdouble and triple encryption. I think it's pretty fast, and
Xit doesn't take up much memory at runtime.
XRichard leaves a copyright notice on the code but encourages
Xfree use of the code.
X
XMark Riordan m...@scss3.cl.msu.edu
END_OF_FILE
if test 286 -ne `wc -c <'Circ/d3des/readme'`; then
echo shar: \"'Circ/d3des/readme'\" unpacked with wrong size!
fi
# end of 'Circ/d3des/readme'
fi
if test -f 'Circ/ignore.irc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/ignore.irc'\"
else
echo shar: Extracting \"'Circ/ignore.irc'\" \(156 characters\)
sed "s/^X//" >'Circ/ignore.irc' <<'END_OF_FILE'
X/on ^public "* CLIPPER:*" /comment
X/on ^public "* SKPJACK:*" /comment
X/on ^public_other "* * CLIPPER:*" /comment
X/on ^public_other "* * SKPJACK:*" /comment
END_OF_FILE
if test 156 -ne `wc -c <'Circ/ignore.irc'`; then
echo shar: \"'Circ/ignore.irc'\" unpacked with wrong size!
fi
# end of 'Circ/ignore.irc'
fi
if test -f 'Circ/pubkeys/al' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/pubkeys/al'\"
else
echo shar: Extracting \"'Circ/pubkeys/al'\" \(261 characters\)
sed "s/^X//" >'Circ/pubkeys/al' <<'END_OF_FILE'
XC21265D382D4E4F2C01C6CAEAEDF0278843A06DF78F4A4BA79FC09607471336B
X085AF92ED74A442160B5D3A8DA75F255E30E05C6D564633524DBBB9B614B7C99
X#
XDA4803B1FFE436844CBE6EFDA5405005B76BC8E90C575DD391723ACF8F9079BE
X277B1992A12EB70AA3C84FE460ACDAFA22EA71C4306EC79F9B7B398E6ABFDF5
END_OF_FILE
if test 261 -ne `wc -c <'Circ/pubkeys/al'`; then
echo shar: \"'Circ/pubkeys/al'\" unpacked with wrong size!
fi
# end of 'Circ/pubkeys/al'
fi
if test -f 'Circ/sock.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Circ/sock.h'\"
else
echo shar: Extracting \"'Circ/sock.h'\" \(1318 characters\)
sed "s/^X//" >'Circ/sock.h' <<'END_OF_FILE'
X#define DEFAULTSERVER "netsys1.netsys.com"
X
X/*
X Please fix these for your site: A FEW US SERVERS:
X csd.bu.edu mit.irc.edu cm22.eng.umd.edu ccwf.cc.utexas.edu
X nic.funet.fi cs.hut.fi wpi.wpi.edu chaos.cs.brandeis.edu
X emoryu1.cc.emory.edu kvart.ifi.uio.no vesuv.unisg.ch ircserv.imp.ch
X stork.doc.ic.ac.uk alf.uib.no irc.nada.kth.se eff.org st6000.sct.edu
X husc10.harvard.edu phoenix.princeton.edu penfold.ece.uiuc.edu
X ucsu.colorado.EDU badger.ugcs.caltech.edu freedom.nmsu.edu nuscc.nus.sg
X kum.kaist.ac.kr silver.ucs.indiana.edu sapienza.roma.it
X bigvax.cs.biu.ac.il hermes.tcad.ee.ufl.edu tjeeves.acc.virginia.edu
X
X Try to pick one CLOSEST to your domain if not in your domain. There are
X MANY more, but this is just ment to get you started, I just tried to give
X a smattering of sites across the world. I tried to cover every suffix
X that I could think of. These are off the top of my head, so it's by no
X means complete. Use one if yours isn't listed and when you get on irc
X ask someone if there's a closer site, try /who *.your.domain to find
X people closest to you.
X
X Notice how documentation is bigger than the code? :)
X */
X#define DEFAULTPORT 6667
X#define COMMANDCHAR '/'
X
X/* couple fixes for non-ansi-c systems */
X#ifdef pyr
X#define strchr index
X#endif
X
END_OF_FILE
if test 1318 -ne `wc -c <'Circ/sock.h'`; then
echo shar: \"'Circ/sock.h'\" unpacked with wrong size!
fi
# end of 'Circ/sock.h'
fi
if test -f 'POSTER' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'POSTER'\"
else
echo shar: Extracting \"'POSTER'\" \(982 characters\)
sed "s/^X//" >'POSTER' <<'END_OF_FILE'
XFrom: Timothy Newsham <new...@wiliki.eng.hawaii.edu>
XSubject: Re: Circ - encrypted irc package
X
XThe following (in uuencoded tar-Z format) is The first release (V1.0) of
Xthe Circ package. It works in conjunction with the ircII client (chat
Xprogram: available at csd.bu.edu in pub/irc/clients)
X
XThe program allows for key management, key exchange and the exchange of
Xencrypted messages in real time over the IRC chat network.
X
XThe current version has been tested on Ultrix (decstation) and HPUX 9.0
X(hp9000) machines. Previous versions have been tested on other
Xplatforms, the code is mostly made up of STDIO routines and should
Xcompile on most unix machines.
X
XAll code written by me is released into the public domain.
X
XThe code in the RSA and d3des directories were not authored by me but
Xare freely distributable.
X
X--
XModerators note:
XCirc was supplied to me as a single 127Kb shar file. Since this was too
Xlarge to post directly, I've split it into 3 separate issues.
X
X+Alec-
END_OF_FILE
if test 982 -ne `wc -c <'POSTER'`; then
echo shar: \"'POSTER'\" unpacked with wrong size!
fi
# end of 'POSTER'
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone

0 new messages