home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume38 / circ / part02 < prev    next >
Encoding:
Internet Message Format  |  1993-08-11  |  54.4 KB

  1. From: newsham@wiliki.eng.hawaii.edu (Timothy Newsham)
  2. Newsgroups: comp.sources.misc
  3. Subject: v38i011: circ - encrypted irc package, Part02/03
  4. Date: 19 Jun 1993 08:31:05 +0100
  5. Sender: aem@aber.ac.uk
  6. Approved: aem@aber.ac.uk
  7. Message-ID: <1vufbp$jkv@uk-usenet.UK.Sun.COM>
  8. X-Md4-Signature: 8f4133c8e6b72f352e9a52b762cacd1e
  9.  
  10. Submitted-by: newsham@wiliki.eng.hawaii.edu (Timothy Newsham)
  11. Posting-number: Volume 38, Issue 11
  12. Archive-name: circ/part02
  13. Environment: C UNIX
  14.  
  15. #! /bin/sh
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  19. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  20. # Contents:  Circ/README Circ/RSA/arith.c Circ/RSA/nio.c
  21. #   Circ/RSA/prim.c Circ/RSA/rsa.c Circ/crypt.irc Circ/d3des/d3des.h
  22. #   Circ/new.c
  23. # Wrapped by alecm@uk-usenet on Sat Jun 19 08:26:21 1993
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 2 (of 3)."'
  27. if test -f 'Circ/README' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'Circ/README'\"
  29. else
  30.   echo shar: Extracting \"'Circ/README'\" \(5888 characters\)
  31.   sed "s/^X//" >'Circ/README' <<'END_OF_FILE'
  32. X
  33. XThis is an encrypted protocol that runs on top of IRC.
  34. XThis version has a binary and an ircII script, and is
  35. Xdesigned to run within IRC-II (irc clients).
  36. X
  37. XThis is release 1.0, the first general release.  It is 
  38. Xincompatible to pre-release versions since the encryption
  39. Xwas changed from DES to triple-DES.  Also RSA keys must
  40. Xbe longer than the ones created by the last version since
  41. XTriple-DES keys are three times longer (so any old RSA
  42. Xkeys are no longer any good).
  43. X
  44. XIf you want a tiny (stand-alone) client, read README.old
  45. X
  46. XGENERAL DESCRIPTION:
  47. X---------------------
  48. X
  49. XInterfaces to ircII clients through the scripting language.
  50. XEncrypts messages in Triple-DES.
  51. XKeeps a table of Triple-DES keys.
  52. XAllows for key exchange using the RSA encryption algorithm.
  53. X
  54. X
  55. XHOW DO I SET IT UP?
  56. X--------------------
  57. X
  58. X1.  set-up your ircII client.  Hopefully you already have 
  59. X    this done
  60. X
  61. X2.  compile all the binaries you will need:
  62. X       make all    
  63. X    this will make the binary 'new' and generate your
  64. X    keys.  Alternatively you can do them seperately:
  65. X       make new
  66. X     and
  67. X       make keys
  68. X    this may come in handy later if you wish to make a new
  69. X    RSA key, or if you wish to remake 'new' without changing
  70. X    your key.
  71. X    The file names used for your keys will be printed to your
  72. X    screen:  "secret" for your secret key and another one named
  73. X    after your login or $IRCNAME (or "public" if the script
  74. X    cant determine either of those).  
  75. X
  76. X3.  Send your public key (named after your IRCNICK ) to your
  77. X    friends, heck even your enemies... doesnt hurt.  Security
  78. X    does not depend much on this key (having this key shouldnt
  79. X    help the bad guys decrypt your messages).   You can do this
  80. X    a number of ways:  mail and '/dcc send' (within irc) are
  81. X    two of them.
  82. X
  83. X4.  If you have a directory with your friends public keys
  84. X    set up an environmental pointing to them.  This is
  85. X    done differently in CSH and SH :
  86. X     CSH%  setenv KEYDIR /path/to/key/dir
  87. X      SH$  KEYDIR=/path/to/key/dir
  88. X      SH$  export KEYDIR
  89. X    alternatively put all your keys into a directory named
  90. X    "pubkeys" under the current directory.  This directory
  91. X    always gets checked.
  92. X
  93. X5.  Start-up irc now.
  94. X
  95. X6.  Once in load up the script file.  While loading the script
  96. X    you *must* be in the same directory as the binary 'new'
  97. X    the files 'secret' and all the secret keys!  You can
  98. X    do this by either starting IRC from within the directory,
  99. X    or using the IRCII command /cd directory to get there.
  100. X
  101. X         /load crypt.irc
  102. X
  103. X   (note due to discrepencies in scripting in newer IRCII
  104. X    clients there are two versions of the script.  Users
  105. X    using older ircII clients should use "crypt.irc" and
  106. X    those using newer (I believe 2.2.4 and onward) should
  107. X    use "crypt.irc2" )
  108. X
  109. X7.  You should now be ready to encrypt and receive encrypted
  110. X    messages.  Join a channel with someone else who has encryption
  111. X    and send them your key:
  112. X
  113. X         /join #crypto
  114. X         /key myfriend
  115. X
  116. X     this will send them your (random) DES key and allow them
  117. X     to see you.  When you send them encrypted messages now,
  118. X     it will be automatically decrypted on their end and put up
  119. X     on the screen with an E before it.
  120. X
  121. X     To send an encrypted message to the current channel type
  122. X         /e message here
  123. X     Or to make all your messages encrypted:
  124. X         /crypt
  125. X     To undo that:
  126. X         /plain
  127. X     And to send plaintext messages while encrypted:
  128. X         /p message here
  129. X     To send encrypted messages:
  130. X         /emsg nick message here
  131. X
  132. XFor details on what goes on behind the scene,  the protocol
  133. Xspecifics, or anything more detailed than this, see 
  134. XREADME.old which refers to a previous (standalone) encrypted
  135. Xclient.
  136. X
  137. X
  138. XWATCH OUT FOR:
  139. X--------------
  140. X
  141. X-  if you dont want someone to see you: DONT /KEY THEIRNICK !!!
  142. X   anyone you /key can read what you type
  143. X
  144. X-  if you want someone to see you:  /key theirnick !!!
  145. X   while encrypted, only the people you have /key'ed can
  146. X   see what you type.  (And only then if they have the
  147. X   client)
  148. X
  149. X-  dont piss people off!  Anyone who does not run this program
  150. X   will see *alot* of garbage on their screen while you are
  151. X   sending encrypted messages to their channel!  Please keep
  152. X   encryption in channels were people have encrypted clients.
  153. X
  154. X-  the /crypt and /plain  alias's use /query.   If you are /query'ing
  155. X   someone and type either /crypt or /plain it will cancel your
  156. X   old /query.  If you are encrypted (/crypt) and you /query
  157. X   someone else it will take yout out of auto-encryption.  You
  158. X   can tell when you are encrypted by the [query: %crypt] in
  159. X   the title bar (if you have a title bar :)
  160. X
  161. X-  only messages that are sent with "/e" or "/emsg" or while
  162. X   in "/crypt" mode are encrypted.  Not everything you type
  163. X   after "/load crypt.irc" is encrypted.
  164. X
  165. X-  If you wish to reload the program, or stop it use /die.  This
  166. X   will stop the server program ('new') and remove any /query's
  167. X   that are in effect (in case you where /crypt'ed).  
  168. X
  169. X
  170. XWEAKNESSES:
  171. X-----------
  172. X
  173. XSecurity of all messages you type in any one session depends
  174. Xon the secrecy of your Triple-DES key and the security of
  175. Xthat algorithm.
  176. X
  177. XSecurity of any key exchanges depends on the RSA algorithm and
  178. Xthe secrecy of your "secret" secret key file.  The keys generated
  179. Xare aproximately 512 bits long,  but the random numbers are all
  180. Xtaken from the rand() system call.  This is a possible weakness.
  181. XAs usual anything you do on another persons machine is not totally
  182. Xsecure.  Root can peek at your core image which has all the
  183. Xsecret keys as well as some extra plaintext laying around.  Root
  184. Xcould go as far as to watch the pipe between irc and the 'new'
  185. Xbinary.  If you are dialing up and go through a Terminal Server
  186. Xyou could be monitored at that point, or comming over the
  187. Xnetwork.
  188. X
  189. X----
  190. Xenjoy..  distribute freely.  Feel free to add, give suggestions,
  191. Xetc.
  192. X  
  193. END_OF_FILE
  194.   if test 5888 -ne `wc -c <'Circ/README'`; then
  195.     echo shar: \"'Circ/README'\" unpacked with wrong size!
  196.   fi
  197.   # end of 'Circ/README'
  198. fi
  199. if test -f 'Circ/RSA/arith.c' -a "${1}" != "-c" ; then 
  200.   echo shar: Will not clobber existing file \"'Circ/RSA/arith.c'\"
  201. else
  202.   echo shar: Extracting \"'Circ/RSA/arith.c'\" \(11667 characters\)
  203.   sed "s/^X//" >'Circ/RSA/arith.c' <<'END_OF_FILE'
  204. X/*******************************************************************************
  205. X*                                           *
  206. X*    Copyright (c) Martin Nicolay,  22. Nov. 1988                   *
  207. X*                                           *
  208. X*    Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten   *
  209. X*    bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter    *
  210. X*    verwendet werden.                               *
  211. X*                                           *
  212. X*    martin@trillian.megalon.de                           *
  213. X*                                           *
  214. X*******************************************************************************/
  215. X
  216. X#include    "arith.h"
  217. X
  218. X/*
  219. X *    !!!!!!!!!!!!!!!!!!!!!!!!!!!! ACHTUNG !!!!!!!!!!!!!!!!!!!!!!!!!!!!
  220. X *    Es findet keinerlei Ueberpruefung auf Bereichsueberschreitung
  221. X *    statt. Alle Werte muessen natuerliche Zahlen aus dem Bereich
  222. X *        0 ... (MAXINT+1)^MAXLEN-1 sein.
  223. X *    
  224. X *    
  225. X *    Bei keiner Funktion oder Hilsfunktion werden Annahmen getroffen,
  226. X *    ueber die Verschiedenheit von Eingabe- & Ausgabe-Werten.
  227. X *
  228. X *
  229. X *        Funktionen:
  230. X *
  231. X *    a_add( s1, s2, d )
  232. X *        NUMBER *s1,*s2,*d;
  233. X *            *d = *s1 + *s2;
  234. X *
  235. X *    a_assign( *d, *s )
  236. X *        NUMBER *d,*s;
  237. X *            *d = *s;
  238. X *
  239. X * int    a_cmp( c1, c2 )
  240. X *        NUMBER *c1,*c2;
  241. X *             1 :    falls *c1 >  *c2
  242. X *             0 :    falls *c1 == *c2
  243. X *            -1 :    falls *c1 <  *c2
  244. X *
  245. X *    a_div( d1, d2, q, r )
  246. X *        NUMBER *d1,*d2,*q,*r;
  247. X *            *q = *d1 / *d2 Rest *r;
  248. X *
  249. X *    a_div2( n )
  250. X *        NUMBER *n;
  251. X *            *n /= 2;
  252. X *
  253. X *    a_ggt( a, b, f )
  254. X *        NUMBER *a,*b,*f;
  255. X *            *f = ( *a, *b );
  256. X *
  257. X *    a_imult( n, m, d )
  258. X *        NUMBER *n;
  259. X *        INT m;
  260. X *        NUMBER *d;
  261. X *            *d = *n * m
  262. X *
  263. X *    a_mult( m1, m2, d )
  264. X *        NUMBER *m1,*m2,*d;
  265. X *            *d = *m1 * *m2;
  266. X *
  267. X *    a_sub( s1, s2, d )
  268. X *        NUMBER *s1,*s2,*d;
  269. X *            *d = *s1 - *s2;
  270. X *
  271. X *        Modulare Funktionen
  272. X *    m_init( n, o )
  273. X *        NUMBER *n,*o;
  274. X *            Initialsierung der Modularen Funktionen
  275. X *            o != 0 : *o = alter Wert
  276. X *
  277. X *    m_add( s1, s2, d )
  278. X *        NUMBER *s1, *s2, *d;
  279. X *            *d = *s1 + *s2;
  280. X *
  281. X *    m_mult( m1, m2, d )
  282. X *        NUMBER *m1,*m2,*d;
  283. X *
  284. X *    m_exp( x, n, z )
  285. X *        NUMBER *x,*n,*z;
  286. X *            *z = *x exp *n;
  287. X *
  288. X *
  289. X *        Hilfs-Funktionen:
  290. X *
  291. X * int    n_bits( n, b )
  292. X *        NUMBER *n;
  293. X *        int b;
  294. X *            return( unterste b Bits der Dualdarstellung von n)
  295. X *
  296. X *    n_div( d1, z2, q, r )
  297. X *        NUMBER *d1,z2[MAXBIT],*q,*r;
  298. X *            *q = *d1 / z2[0] Rest *r;
  299. X *            z2[i] = z2[0] * 2^i,  i=0..MAXBIT-1
  300. X *
  301. X * int    n_cmp( i1, i2, l )
  302. X *        INT i1[l], i2[l];
  303. X *             1 :    falls i1 >  i2
  304. X *             0 :    falls i1 == i2
  305. X *            -1 :    falls i1 <  i2
  306. X *
  307. X * int    n_mult( n, m, d, l)
  308. X *        INT n[l], m, d[];
  309. X *            d = m * n;
  310. X *            return( sizeof(d) ); d.h. 'l' oder 'l+1'
  311. X *
  312. X * int    n_sub( p1, p2, p3, l, lo )
  313. X *        INT p1[l], p2[lo], p3[];
  314. X *            p3 = p1 - p2;
  315. X *            return( sizeof(p3) ); d.h. '<= min(l,lo)'
  316. X *
  317. X * int    n_bitlen( n )
  318. X *         NUMBER *n;
  319. X *            return( sizeof(n) in bits )
  320. X *
  321. X */
  322. X
  323. X
  324. X/*
  325. X * Konstante 1, 2
  326. X */
  327. XNUMBER a_one = {
  328. X    1,
  329. X    { (INT)1, },
  330. X};
  331. X
  332. XNUMBER a_two = {
  333. X#if MAXINT == 1
  334. X    2,
  335. X    { 0, (INT)1, },
  336. X#else
  337. X    1,
  338. X    { (INT)2, },
  339. X#endif
  340. X};
  341. X
  342. X
  343. X/*
  344. X * Vergleiche zwei INT arrays der Laenge l
  345. X */
  346. Xint n_cmp( i1, i2, l )
  347. XINT *i1,*i2;
  348. X{
  349. X    i1 += (l-1);            /* Pointer ans Ende        */ 
  350. X    i2 += (l-1);
  351. X     
  352. X    for (;l--;)
  353. X        if ( *i1-- != *i2-- )
  354. X            return( i1[1] > i2[1] ? 1 : -1 );
  355. X    
  356. X    return(0);
  357. X}
  358. X
  359. X/*
  360. X * Vergleiche zwei NUMBER
  361. X */
  362. Xint a_cmp( c1, c2 )
  363. XNUMBER *c1,*c2;
  364. X{
  365. X    int l;
  366. X                    /* bei verschiedener Laenge klar*/
  367. X    if ( (l=c1->n_len) != c2->n_len)
  368. X        return( l - c2->n_len);
  369. X    
  370. X                    /* vergleiche als arrays    */
  371. X    return( n_cmp( c1->n_part, c2->n_part, l) );
  372. X}
  373. X
  374. X/*
  375. X * Zuweisung einer NUMBER (d = s)
  376. X */
  377. Xvoid a_assign( d, s )
  378. XNUMBER *d,*s;
  379. X{
  380. X    int l;
  381. X    
  382. X    if (s == d)            /* nichts zu kopieren        */
  383. X        return;
  384. X    
  385. X    if (l=s->n_len)
  386. X        memcpy( d->n_part, s->n_part, sizeof(INT)*l);
  387. X    
  388. X    d->n_len = l;
  389. X}
  390. X
  391. X/*
  392. X * Addiere zwei NUMBER (d = s1 + s2)
  393. X */
  394. Xvoid a_add( s1, s2, d )
  395. XNUMBER *s1,*s2,*d;
  396. X{
  397. X    int l,lo,ld,same;
  398. X    register LONG sum;
  399. X    register INT *p1,*p2,*p3;
  400. X    register INT b;
  401. X    
  402. X                /* setze s1 auch die groessere Zahl    */
  403. X    l = s1->n_len;
  404. X    if ( (l=s1->n_len) < s2->n_len ) {
  405. X        NUMBER *tmp = s1;
  406. X        
  407. X        s1 = s2;
  408. X        s2 = tmp;
  409. X        
  410. X        l = s1->n_len;
  411. X    }
  412. X
  413. X    ld = l;
  414. X    lo = s2->n_len;
  415. X    p1 = s1->n_part;
  416. X    p2 = s2->n_part;
  417. X    p3 = d->n_part;
  418. X    same = (s1 == d);
  419. X    sum = 0;
  420. X    
  421. X    while (l --) {
  422. X        if (lo) {        /* es ist noch was von s2 da    */
  423. X            lo--;
  424. X            b = *p2++;
  425. X        }
  426. X        else
  427. X            b = 0;        /* ansonten 0 nehmen        */
  428. X        
  429. X        sum += (LONG)*p1++ + (LONG)b;
  430. X        *p3++ = TOINT(sum);
  431. X
  432. X        if (sum > (LONG)MAXINT) {    /* carry merken        */
  433. X            sum = 1;
  434. X        }
  435. X        else
  436. X            sum = 0;
  437. X
  438. X        if (!lo && same && !sum)    /* nichts mehr zu tuen    */
  439. X            break;
  440. X    }
  441. X    
  442. X    if (sum) {        /* letztes carry beruecksichtigen    */
  443. X        ld++;
  444. X        *p3 = sum;
  445. X    }
  446. X    
  447. X    d->n_len = ld;            /* Laenge setzen        */
  448. X}
  449. X
  450. X/*
  451. X * Subtrahiere zwei INT arrays. return( Laenge Ergebniss )
  452. X * l == Laenge p1
  453. X * lo== Laenge p3
  454. X */
  455. Xint n_sub( p1, p2, p3, l, lo )
  456. XINT *p1,*p2,*p3;
  457. Xint l,lo;
  458. X{
  459. X    int ld,lc,same;
  460. X    int over = 0;
  461. X    register LONG dif;
  462. X    LONG a,b;
  463. X    
  464. X    same = (p1 == p3);            /* frueher Abbruch moeglich */
  465. X    
  466. X    for (lc=1, ld=0; l--; lc++) {
  467. X        a = (LONG)*p1++;
  468. X        if (lo) {            /* ist noch was von p2 da ? */
  469. X            lo--;
  470. X            b = (LONG)*p2++;
  471. X        }
  472. X        else
  473. X            b=0;            /* ansonten 0 nehmen    */
  474. X
  475. X        if (over)            /* frueherer Overflow    */
  476. X            b++;
  477. X        if ( b > a ) {            /* jetzt Overflow ?    */
  478. X            over = 1;
  479. X            dif = (MAXINT +1) + a;
  480. X        }
  481. X        else {
  482. X            over = 0;
  483. X            dif = a;
  484. X        }
  485. X        dif -= b;
  486. X        *p3++ = (INT)dif;
  487. X        
  488. X        if (dif)            /* Teil != 0 : Laenge neu */
  489. X            ld = lc;
  490. X        if (!lo && same && !over) {    /* nichts mehr zu tuen    */
  491. X            if (l > 0)        /* Laenge korrigieren    */
  492. X                ld = lc + l;
  493. X            break;
  494. X        }
  495. X    }
  496. X
  497. X    return( ld );
  498. X}
  499. X
  500. X/*
  501. X * Subtrahiere zwei NUMBER (d= s1 - s2)
  502. X */
  503. Xvoid a_sub( s1, s2, d )
  504. XNUMBER *s1,*s2,*d;
  505. X{
  506. X    d->n_len = n_sub( s1->n_part, s2->n_part, d->n_part
  507. X             ,s1->n_len, s2->n_len );
  508. X}
  509. X
  510. X/*
  511. X * Mulitipliziere INT array der Laenge l mit einer INT (d = n * m)
  512. X * return neue Laenge
  513. X */
  514. Xint n_mult( n, m, d, l)
  515. Xregister INT *n;
  516. Xregister INT m;
  517. XINT *d;
  518. X{
  519. X    int i;
  520. X    register LONG mul;
  521. X    
  522. X    for (i=l,mul=0; i; i--) {
  523. X        mul += (LONG)m * (LONG)*n++;
  524. X        *d++ = TOINT(mul);
  525. X        mul  = DIVMAX1( mul );
  526. X    }
  527. X    
  528. X    if (mul) {        /* carry  ? */
  529. X        l++;
  530. X        *d = mul;
  531. X    }
  532. X    
  533. X    return( l );
  534. X}
  535. X
  536. X/*
  537. X * Mulitipliziere eine NUMBER mit einer INT (d = n * m)
  538. X */
  539. Xvoid a_imult( n, m, d )
  540. XNUMBER *n;
  541. XINT m;
  542. XNUMBER *d;
  543. X{
  544. X    if (m == 0)
  545. X        d->n_len=0;
  546. X    else if (m == 1)
  547. X        a_assign( d, n );
  548. X    else
  549. X        d->n_len = n_mult( n->n_part, m, d->n_part, n->n_len );
  550. X}
  551. X  
  552. X/*
  553. X * Multipliziere zwei NUMBER (d = m1 * m2) 
  554. X */
  555. Xvoid a_mult( m1, m2, d )
  556. XNUMBER *m1,*m2,*d;
  557. X{
  558. X    static INT id[ MAXLEN ];        /* Zwischenspeicher    */
  559. X    register INT *vp;            /* Pointer darin    */
  560. X    register LONG sum;            /* Summe fuer jede Stelle */
  561. X    register LONG tp1;            /* Zwischenspeicher fuer m1 */
  562. X    register INT *p2;
  563. X    INT *p1;
  564. X    int l1,l2,ld,lc,l,i,j;
  565. X    
  566. X    l1 = m1->n_len;
  567. X    l2 = m2->n_len;
  568. X    l = l1 + l2;
  569. X    if (l >= MAXLEN)
  570. X        abort();
  571. X
  572. X    for (i=l, vp=id; i--;)
  573. X        *vp++ = 0;
  574. X    
  575. X            /* ohne Uebertrag in Zwischenspeicher multiplizieren */
  576. X    for ( p1 = m1->n_part, i=0; i < l1 ; i++, p1++ ) {
  577. X
  578. X        tp1 = (LONG)*p1;        
  579. X        vp = &id[i];
  580. X        sum = 0;
  581. X        for ( p2 = m2->n_part, j = l2; j--;) {
  582. X            sum += (LONG)*vp + (tp1 * (LONG)*p2++);
  583. X            *vp++ = TOINT( sum );
  584. X            sum = DIVMAX1(sum);
  585. X        }
  586. X        *vp++ += (INT)sum;
  587. X    }
  588. X
  589. X            /* jetzt alle Uebertraege beruecksichtigen    */
  590. X    ld = 0;
  591. X    for (lc=0, vp=id, p1=d->n_part; lc++ < l;) {
  592. X        if ( *p1++ = *vp++ )
  593. X            ld = lc;
  594. X    }
  595. X    
  596. X    d->n_len = ld;
  597. X}
  598. X
  599. X
  600. X/*
  601. X * Dividiere Zwei NUMBER mit Rest (q= d1 / z2[0] Rest r)
  602. X * z2[i] = z2[0] * 2^i,  i=0..MAXBIT-1
  603. X * r = 0 : kein Rest
  604. X * q = 0 : kein Quotient
  605. X */
  606. Xvoid n_div( d1, z2, q, r )
  607. XNUMBER *d1,*z2,*q,*r;
  608. X{
  609. X    static    NUMBER dummy_rest;  /* Dummy Variable, falls r = 0 */
  610. X    static    NUMBER dummy_quot;  /* Dummy Variable, falla q = 0 */
  611. X    INT *i1,*i1e,*i3;
  612. X    int l2,ld,l,lq;
  613. X#if MAXINT != 1
  614. X    INT z;
  615. X    int pw,l2t;
  616. X#endif
  617. X
  618. X    if (!z2->n_len)
  619. X        abort();
  620. X        
  621. X    if (!r)
  622. X        r = &dummy_rest;
  623. X    if (!q)
  624. X        q = &dummy_quot;
  625. X    
  626. X    a_assign( r, d1 );    /* Kopie von d1 in den Rest        */
  627. X    
  628. X    l2= z2->n_len;        /* Laenge von z2[0]            */
  629. X    l = r->n_len - l2;    /* Laenge des noch ''rechts'' liegenden
  630. X                    Stuecks von d1            */
  631. X    lq= l +1;        /* Laenge des Quotienten        */
  632. X    i3= q->n_part + l;
  633. X    i1= r->n_part + l;
  634. X    ld = l2;        /* aktuelle Laenge des ''Vergleichsstuecks''
  635. X                    von d1                */
  636. X    i1e= i1 + (ld-1);
  637. X    
  638. X    for (; l >= 0; ld++, i1--, i1e--, l--, i3--) {
  639. X        *i3 = 0;
  640. X
  641. X        if (ld == l2 && ! *i1e) {
  642. X            ld--;
  643. X            continue;
  644. X        }
  645. X        
  646. X        if ( ld > l2 || (ld == l2 && n_cmp( i1, z2->n_part, l2) >= 0 ) ) {
  647. X#if MAXINT != 1
  648. X                /* nach 2er-Potenzen zerlegen    */
  649. X            for (pw=MAXBIT-1, z=(INT)HIGHBIT; pw >= 0; pw--, z /= 2) {
  650. X                if ( ld > (l2t= z2[pw].n_len)
  651. X                    || (ld == l2t
  652. X                        && n_cmp( i1, z2[pw].n_part, ld) >= 0) ) {
  653. X                    ld = n_sub( i1, z2[pw].n_part, i1, ld, l2t );
  654. X                    (*i3) += z;
  655. X                }
  656. X            }
  657. X#else
  658. X                /* bei MAXINT == 1 alles viel einfacher    */
  659. X            ld = n_sub( i1, z2->n_part, i1, ld, l2 );
  660. X            (*i3) ++;
  661. X#endif
  662. X        }
  663. X    }
  664. X    
  665. X            /* Korrektur, falls l von Anfang an Negativ war */
  666. X    l ++;
  667. X    lq -= l;
  668. X    ld += l;
  669. X    
  670. X    if (lq>0 && !q->n_part[lq -1])    /* evtl. Laenge korrigieren    */
  671. X        lq--;
  672. X    
  673. X    q->n_len = lq;
  674. X    r->n_len = ld -1;
  675. X}
  676. X
  677. X/*
  678. X * Dividiere Zwei NUMBER mit Rest (q= d1 / z2[0] Rest r)
  679. X * z2[i] = z2[0] * 2^i,  i=0..MAXBIT-1
  680. X * r = 0 : kein Rest
  681. X * q = 0 : kein Quotient
  682. X */
  683. Xvoid a_div( d1, d2, q, r )
  684. XNUMBER *d1,*d2,*q,*r;
  685. X{
  686. X#if MAXINT != 1
  687. X    NUMBER z2[MAXBIT];
  688. X    INT z;
  689. X    int i;
  690. X    
  691. X    a_assign( &z2[0], d2 );
  692. X    for (i=1,z=2; i < MAXBIT; i++, z *= 2)
  693. X        a_imult( d2, z, &z2[i] );
  694. X    
  695. X    d2 = z2;
  696. X#endif
  697. X
  698. X    n_div( d1, d2, q, r );
  699. X}
  700. X
  701. X/*
  702. X * Dividiere eine NUMBER durch 2
  703. X */
  704. Xvoid a_div2( n )
  705. XNUMBER *n;
  706. X{
  707. X#if MAXBIT == LOWBITS
  708. X    register INT *p;
  709. X    int i;
  710. X
  711. X#if MAXINT != 1
  712. X    register INT h;
  713. X    register int c;
  714. X
  715. X    c=0;
  716. X    i= n->n_len;
  717. X    p= &n->n_part[i-1];
  718. X    
  719. X    for (; i--;) {
  720. X        if (c) {
  721. X            c = (h= *p) & 1;
  722. X            h /= 2;
  723. X            h |= HIGHBIT;
  724. X        }
  725. X        else {
  726. X            c = (h= *p) & 1;
  727. X            h /= 2;
  728. X        }
  729. X        
  730. X        *p-- = h;
  731. X    }
  732. X    
  733. X    if ( (i= n->n_len) && n->n_part[i-1] == 0 )
  734. X        n->n_len = i-1;
  735. X
  736. X#else  /* MAXBIT != 1 */
  737. X    p = n->n_part;
  738. X    i = n->n_len;
  739. X    
  740. X    if (i) {
  741. X        n->n_len = i-1;
  742. X        for (; --i ; p++)
  743. X            p[0] = p[1];
  744. X    }
  745. X#endif /* MAXBIT != 1 */
  746. X#else  /* MAXBIT == LOWBITS */
  747. X    a_div( n, &a_two, n, NUM0P );
  748. X#endif /* MAXBIT == LOWBITS */
  749. X}
  750. X
  751. X
  752. X/*
  753. X *    MODULO-FUNKTIONEN
  754. X */
  755. X
  756. Xstatic NUMBER mod_z2[ MAXBIT ];
  757. X
  758. X/*
  759. X * Init
  760. X */
  761. Xvoid m_init( n, o )
  762. XNUMBER *n,*o;
  763. X{
  764. X    INT z;
  765. X    int i;
  766. X    
  767. X    if (o)
  768. X        a_assign( o, &mod_z2[0] );
  769. X    
  770. X    if (! a_cmp( n, &mod_z2[0] ) )
  771. X        return;
  772. X    
  773. X    for (i=0,z=1; i < MAXBIT; i++, z *= 2)
  774. X        a_imult( n, z, &mod_z2[i] );
  775. X}
  776. X
  777. Xvoid m_add( s1, s2, d )
  778. XNUMBER *s1, *s2, *d;
  779. X{
  780. X    a_add( s1, s2, d );
  781. X    if (a_cmp( d, mod_z2 ) >= 0)
  782. X        a_sub( d, mod_z2, d );
  783. X}
  784. X
  785. Xvoid m_mult( m1, m2, d )
  786. XNUMBER *m1,*m2,*d;
  787. X{
  788. X    a_mult( m1, m2, d );
  789. X    n_div( d, mod_z2, NUM0P, d );
  790. X}
  791. X
  792. X/*
  793. X * Restklassen Exponent
  794. X */
  795. Xvoid m_exp( x, n, z )
  796. XNUMBER *x,*n,*z;
  797. X{
  798. X    NUMBER xt,nt;
  799. X    
  800. X    a_assign( &nt, n );
  801. X    a_assign( &xt, x );
  802. X    a_assign( z, &a_one );
  803. X    
  804. X    while (nt.n_len) {
  805. X        while ( ! (nt.n_part[0] & 1) ) {
  806. X            m_mult( &xt, &xt, &xt );
  807. X            a_div2( &nt );
  808. X        }
  809. X        m_mult( &xt, z, z );
  810. X        a_sub( &nt, &a_one, &nt );
  811. X    }
  812. X}
  813. X
  814. X/*
  815. X * GGT
  816. X */
  817. Xvoid a_ggt( a, b, f )
  818. XNUMBER *a,*b,*f;
  819. X{
  820. X    NUMBER t[2];
  821. X    int at,bt, tmp;
  822. X    
  823. X    a_assign( &t[0], a ); at= 0;
  824. X    a_assign( &t[1], b ); bt= 1;
  825. X    
  826. X    if ( a_cmp( &t[at], &t[bt] ) < 0 ) {
  827. X        tmp= at; at= bt; bt= tmp;
  828. X    }
  829. X                /* euklidischer Algorithmus        */
  830. X    while ( t[bt].n_len ) {
  831. X        a_div( &t[at], &t[bt], NUM0P, &t[at] );
  832. X        tmp= at; at= bt; bt= tmp;
  833. X    }
  834. X    
  835. X    a_assign( f, &t[at] );
  836. X}
  837. X    
  838. X/*
  839. X * die untersten b bits der Dualdarstellung von n
  840. X * die bits muessen in ein int passen
  841. X */
  842. Xint n_bits(n,b)
  843. XNUMBER *n;
  844. X{
  845. X    INT *p;
  846. X    int l;
  847. X    unsigned r;
  848. X    int m = (1<<b) -1;
  849. X
  850. X    if ( n->n_len == 0)
  851. X        return(0);
  852. X    
  853. X    if (LOWBITS >= b)
  854. X        return( n->n_part[0] & m );
  855. X
  856. X#if LOWBITS != 0
  857. X    l = (b-1) / LOWBITS;
  858. X#else
  859. X    l = n->n_len -1;
  860. X#endif
  861. X    for (p= &n->n_part[l],r=0; l-- >= 0 && b > 0; b-= LOWBITS, p--) {
  862. X        r  = MULMAX1( r );
  863. X        r += (unsigned)*p;
  864. X    }
  865. X
  866. X    return( r & m );
  867. X}
  868. X
  869. X/*
  870. X * Anzahl der bits von n bei Dualdarstellung
  871. X */
  872. Xint n_bitlen( n )
  873. XNUMBER *n;
  874. X{
  875. X    NUMBER b;
  876. X    int i;
  877. X    
  878. X    a_assign( &b, &a_one );
  879. X    
  880. X    for (i=0; a_cmp( &b, n ) <= 0; a_mult( &b, &a_two, &b ), i++)
  881. X        ;
  882. X    
  883. X    return(i);
  884. X}
  885. END_OF_FILE
  886.   if test 11667 -ne `wc -c <'Circ/RSA/arith.c'`; then
  887.     echo shar: \"'Circ/RSA/arith.c'\" unpacked with wrong size!
  888.   fi
  889.   # end of 'Circ/RSA/arith.c'
  890. fi
  891. if test -f 'Circ/RSA/nio.c' -a "${1}" != "-c" ; then 
  892.   echo shar: Will not clobber existing file \"'Circ/RSA/nio.c'\"
  893. else
  894.   echo shar: Extracting \"'Circ/RSA/nio.c'\" \(4308 characters\)
  895.   sed "s/^X//" >'Circ/RSA/nio.c' <<'END_OF_FILE'
  896. X/*******************************************************************************
  897. X*                                           *
  898. X*    Copyright (c) Martin Nicolay,  22. Nov. 1988                   *
  899. X*                                           *
  900. X*    Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten   *
  901. X*    bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter    *
  902. X*    verwendet werden.                               *
  903. X*                                           *
  904. X*    martin@trillian.megalon.de                           *
  905. X*                                           *
  906. X*******************************************************************************/
  907. X
  908. X#include    <stdio.h>
  909. X#include    <ctype.h>
  910. X#include    <string.h>
  911. X
  912. X#include    "nio.h"
  913. X
  914. X/*
  915. X *    NUMBER io
  916. X */
  917. X
  918. X/*
  919. X *        Funktionen
  920. X *
  921. X * int    num_sput( n, s, l)
  922. X *        NUMBER *n;
  923. X *        char s[l];
  924. X *            schreibt *n als Hex-Zahl in s
  925. X *
  926. X * int    num_fput( n, f )
  927. X *        NUMBER *n;
  928. X *        FILE *f;
  929. X *            schreibt *n als Hex-Zahl in File f
  930. X *
  931. X * int    num_sget( n, s )
  932. X *        NUMBER *n;
  933. X *        char *s;
  934. X *            liest Hex-Zahl s in *n ein
  935. X *
  936. X * int    num_fget( n, f )
  937. X *        NUMBER *n;
  938. X *        FILE *f;
  939. X *            liest eine Hex-Zahl von f in *n ein
  940. X *
  941. X */
  942. X
  943. X
  944. Xstatic char *HEX="0123456789ABCDEF";
  945. Xstatic char *hex="0123456789abcdef";
  946. X
  947. Xstatic NUMBER bits[9];
  948. Xstatic NUMBER int16[16];
  949. X
  950. Xstatic int init = 0;
  951. X
  952. Xstatic num_init()
  953. X{
  954. X    int i;
  955. X    
  956. X    a_assign( &bits[0], &a_one );
  957. X    for ( i=1; i<9; i++)
  958. X        a_add( &bits[i-1], &bits[i-1], &bits[i] );
  959. X
  960. X    a_assign( &int16[0], &a_one );
  961. X    for ( i=1; i<16; i++)
  962. X        a_add( &int16[i-1], &a_one, &int16[i] );
  963. X    
  964. X    init = 1;
  965. X}
  966. X
  967. X
  968. Xint num_sput( n, s, l)
  969. XNUMBER *n;
  970. Xchar *s;
  971. X{
  972. X#if MAXINT == ( (1 << MAXBIT) - 1 )
  973. X    INT *p;
  974. X    int bi,ab,i;
  975. X    long b;
  976. X    int first = 1;
  977. X    
  978. X    bi = MAXBIT * n->n_len;
  979. X    ab = 4 - (bi + 3) % 4 -1;
  980. X    p  = &n->n_part[n->n_len -1];
  981. X
  982. X    if ( (bi+3) / 4 >= l )
  983. X        return(EOF);
  984. X    
  985. X    b  = 0;
  986. X    while (bi) {
  987. X        b <<= (MAXBIT);
  988. X        b |= (unsigned long)*p--;
  989. X        bi -= MAXBIT;
  990. X        ab += MAXBIT;
  991. X        while (ab >= 4) {
  992. X            i = (b >> (ab - 4));
  993. X            b &= ( 1L << (ab - 4) ) -1L;
  994. X            ab -= 4;
  995. X
  996. X            if (first && !i)
  997. X                continue;
  998. X            first = 0;
  999. X            *s++ = HEX[ i ];
  1000. X        }
  1001. X    }
  1002. X    if (b)
  1003. X        abort();
  1004. X    *s = '\0';
  1005. X
  1006. X    return (0);
  1007. X#else            
  1008. X    NUMBER r,q;
  1009. X    int i,b,p,len,low,high;
  1010. X    char *np;
  1011. X    
  1012. X    if (! init)
  1013. X        num_init();
  1014. X    
  1015. X    a_assign( &q, n);
  1016. X    len = l;
  1017. X    np = s + l;
  1018. X
  1019. X    for (; q.n_len && len > 1; len --) {
  1020. X        a_div( &q, &bits[4], &q, &r );
  1021. X        for (p=8, b=0, i=3; i >= 0; i--, p /= 2 ) {
  1022. X            if ( a_cmp( &r, &bits[i] ) >= 0 ) {
  1023. X                a_sub( &r, &bits[i], &r );
  1024. X                b += p;
  1025. X            }
  1026. X        }
  1027. X        *--np = HEX[ b ];
  1028. X    }
  1029. X    if (q.n_len)
  1030. X        return(EOF);
  1031. X
  1032. X    l -= len;
  1033. X    len = l;
  1034. X    for (; l--; )
  1035. X        *s++ = *np++;
  1036. X    
  1037. X    *s = '\0';
  1038. X
  1039. X    return (0);
  1040. X#endif
  1041. X}
  1042. X
  1043. X
  1044. Xint num_fput( n, f )
  1045. XNUMBER *n;
  1046. XFILE *f;
  1047. X{
  1048. X    int j;
  1049. X    char *np;
  1050. X    unsigned char n_print[ STRLEN + 1 ];
  1051. X    
  1052. X    if ( num_sput( n, n_print, sizeof( n_print ) ) == EOF )
  1053. X        return(EOF);
  1054. X    
  1055. X    for (j=0, np=(char *)n_print; *np ; np++, j++ ) {
  1056. X        if (j==64) {
  1057. X            fputs("\n",f);
  1058. X            j = 0;
  1059. X        }
  1060. X        putc((int)*np,f);
  1061. X    }
  1062. X
  1063. X    if (j)
  1064. X        putc('\n',f);
  1065. X
  1066. X    return(0);
  1067. X}
  1068. X
  1069. X
  1070. Xint num_sget( n, s )
  1071. XNUMBER *n;
  1072. Xchar *s;
  1073. X{
  1074. X#if MAXINT == ( (1 << MAXBIT) - 1 )
  1075. X    INT *p;
  1076. X    char *hp;
  1077. X    int bi,ab,i;
  1078. X    long b;
  1079. X    int first = 1;
  1080. X    
  1081. X    bi = 4 * strlen(s);
  1082. X    ab = MAXBIT - (bi + MAXBIT -1) % MAXBIT -1;
  1083. X    i  =  (bi + MAXBIT-1) / MAXBIT;
  1084. X    p  = &n->n_part[ i -1 ];
  1085. X    n->n_len = i;
  1086. X
  1087. X    if ( i > MAXLEN )
  1088. X        return(EOF);
  1089. X    
  1090. X    b  = 0;
  1091. X    while (bi > 0) {
  1092. X        if ( hp= strchr( HEX, *s ) )
  1093. X            i = hp - HEX;
  1094. X        else if ( hp= strchr( hex, *s ) )
  1095. X            i = hp - hex;
  1096. X        else
  1097. X            return(EOF);
  1098. X        s++;
  1099. X        
  1100. X        b <<= 4;
  1101. X        b |= (unsigned long)i;
  1102. X        bi -= 4;
  1103. X        ab += 4;
  1104. X        while (ab >= MAXBIT) {
  1105. X            i = (b >> (ab - MAXBIT));
  1106. X            b &= ( 1L << (ab - MAXBIT) ) -1L;
  1107. X            ab -= MAXBIT;
  1108. X            if (first && !i) {
  1109. X                p--;
  1110. X                n->n_len--;
  1111. X            }
  1112. X            else {
  1113. X                first = 0;
  1114. X                *p-- = i;
  1115. X            }
  1116. X        }
  1117. X    }
  1118. X    if (b)
  1119. X        abort();
  1120. X    *s = '\0';
  1121. X
  1122. X    return (0);
  1123. X#else            
  1124. X    char *p;
  1125. X    int i,c;
  1126. X
  1127. X    if (! init)
  1128. X        num_init();
  1129. X    
  1130. X    n->n_len = 0;
  1131. X    while ( (c = *s++ & 0xFF) ) {
  1132. X        if ( p= strchr( HEX, c ) )
  1133. X            i = p - HEX;
  1134. X        else if ( p= strchr( hex, c ) )
  1135. X            i = p - hex;
  1136. X        else
  1137. X            return(EOF);
  1138. X        
  1139. X        a_mult( n, &bits[4], n );
  1140. X        if (i)
  1141. X            a_add( n, &int16[i-1], n );
  1142. X    }
  1143. X    
  1144. X    return(0);
  1145. X#endif
  1146. X}
  1147. X
  1148. Xint num_fget( n, f )
  1149. XNUMBER *n;
  1150. XFILE *f;
  1151. X{
  1152. X    int j,c;
  1153. X    char *np;
  1154. X    char n_print[ STRLEN + 1 ];
  1155. X
  1156. X    np = n_print;
  1157. X    j = sizeof(n_print);
  1158. X    while ( (c=getc(f)) != EOF && ( isxdigit(c) || isspace(c) ) ) {
  1159. X        if (isspace(c))
  1160. X            continue;
  1161. X        if (! --j)
  1162. X            return(EOF);
  1163. X        *np++ = (char)c;
  1164. X    }
  1165. X    *np = '\0';
  1166. X
  1167. X    if (c != EOF)
  1168. X        ungetc(c,f);
  1169. X    
  1170. X    if ( num_sget( n, n_print ) == EOF )
  1171. X        return( EOF );
  1172. X    
  1173. X    return(0);
  1174. X}
  1175. X
  1176. END_OF_FILE
  1177.   if test 4308 -ne `wc -c <'Circ/RSA/nio.c'`; then
  1178.     echo shar: \"'Circ/RSA/nio.c'\" unpacked with wrong size!
  1179.   fi
  1180.   # end of 'Circ/RSA/nio.c'
  1181. fi
  1182. if test -f 'Circ/RSA/prim.c' -a "${1}" != "-c" ; then 
  1183.   echo shar: Will not clobber existing file \"'Circ/RSA/prim.c'\"
  1184. else
  1185.   echo shar: Extracting \"'Circ/RSA/prim.c'\" \(4732 characters\)
  1186.   sed "s/^X//" >'Circ/RSA/prim.c' <<'END_OF_FILE'
  1187. X/*******************************************************************************
  1188. X*                                           *
  1189. X*    Copyright (c) Martin Nicolay,  22. Nov. 1988                   *
  1190. X*                                           *
  1191. X*    Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten   *
  1192. X*    bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter    *
  1193. X*    verwendet werden.                               *
  1194. X*                                           *
  1195. X*    martin@trillian.megalon.de                           *
  1196. X*                                           *
  1197. X*******************************************************************************/
  1198. X
  1199. X#include    "prim.h"
  1200. X
  1201. X/*
  1202. X *        RSA
  1203. X *
  1204. X *    p,q prim
  1205. X *    p != q
  1206. X *    n = p*q
  1207. X *    phi = (p -1)*(q -1)
  1208. X *    e,d aus 0...n-1
  1209. X *    e*d == 1 mod phi
  1210. X *
  1211. X *    m aus 0...n-1 sei eine Nachricht
  1212. X *
  1213. X *    Verschluesseln:
  1214. X *        E(x) = x^e mod n        ( n,e oeffendlich )
  1215. X *
  1216. X *    Entschluesseln:
  1217. X *        D(x) = x^d mod n        ( d geheim )
  1218. X *
  1219. X *
  1220. X *    Sicherheit:
  1221. X *
  1222. X *        p,q sollten bei mind. 10^100 liegen.
  1223. X *        (d,phi) == 1, das gilt fuer alle Primzahlen > max(p,q).
  1224. X *        Allerdings sollte d moeglichst gross sein ( d < phi-1 )
  1225. X *        um direktes Suchen zu verhindern.
  1226. X */
  1227. X
  1228. X
  1229. X/*
  1230. X *        FUNKTIONEN um RSA Schluessel zu generieren.
  1231. X *
  1232. X * int    p_prim( n, m )
  1233. X *        NUMBER *n;
  1234. X *        int m;
  1235. X *            0 : n ist nicht prim
  1236. X *            1 : n ist mit Wahrscheinlichkeit (1-1/2^m) prim
  1237. X *        ACHTUNG !!!!
  1238. X *        p_prim benutzt m_init
  1239. X *
  1240. X *    inv( d, phi, e )
  1241. X *        NUMBER *d,*phi,*e;
  1242. X *            *e = *d^-1 (mod phi)
  1243. X *        ACHTUNG !!!!
  1244. X *        p_prim benutzt m_init
  1245. X */
  1246. X
  1247. X/*
  1248. X * Prototypes
  1249. X */
  1250. Xstatic int    jak_f(  );    
  1251. Xstatic int    jak_g(  );    
  1252. Xstatic int    jakobi(  );
  1253. X
  1254. X/*
  1255. X * Hilfs-Funktion fuer jakobi
  1256. X */
  1257. Xstatic int jak_f( n )
  1258. XNUMBER *n;
  1259. X{
  1260. X    int f,ret;
  1261. X    
  1262. X    f = n_bits( n, 3 );
  1263. X    
  1264. X    ret = ((f == 1) || (f == 7)) ? 1 : -1;
  1265. X    
  1266. X    return(ret);
  1267. X}
  1268. X
  1269. X/*
  1270. X * Hilfs-Funktuion fuer jakobi
  1271. X */    
  1272. Xstatic int jak_g( a, n )
  1273. XNUMBER *a,*n;
  1274. X{
  1275. X    int ret;
  1276. X    
  1277. X    if ( n_bits( n, 2 ) == 1 ||
  1278. X            n_bits( a, 2 ) == 1 )
  1279. X        ret = 1;
  1280. X    else
  1281. X        ret = -1;
  1282. X    
  1283. X    return(ret);
  1284. X}
  1285. X        
  1286. X/*
  1287. X * Jakobi-Symbol
  1288. X */
  1289. Xstatic int jakobi( a, n )
  1290. XNUMBER *a,*n;
  1291. X{
  1292. X    NUMBER t[2];
  1293. X    int at,nt, ret;
  1294. X    
  1295. X    a_assign( &t[0], a ); at = 0;
  1296. X    a_assign( &t[1], n ); nt = 1;
  1297. X
  1298. X    /*
  1299. X     * b > 1
  1300. X     *
  1301. X     * J( a, b) =
  1302. X     * a == 1    :    1
  1303. X     * a == 2    :    f(n)
  1304. X     * a == 2*b    :    J(b,n)*J(2,n) ( == J(b,n)*f(n) )
  1305. X     * a == 2*b -1    :    J(n % a,a)*g(a,n)
  1306. X     *
  1307. X     */
  1308. X     
  1309. X    ret = 1;
  1310. X    while (1) {
  1311. X        if (! a_cmp(&t[at],&a_one) ) {
  1312. X            break;
  1313. X        }
  1314. X        if (! a_cmp(&t[at],&a_two) ) {
  1315. X            ret *= jak_f( &t[nt] );
  1316. X            break;
  1317. X        }
  1318. X        if ( ! t[at].n_len )        /* Fehler :-)    */
  1319. X            abort();
  1320. X        if ( t[at].n_part[0] & 1 ) {    /* a == 2*b -1    */
  1321. X            int tmp;
  1322. X            
  1323. X            ret *= jak_g( &t[at], &t[nt] );
  1324. X            a_div( &t[nt], &t[at], NUM0P, &t[nt] );
  1325. X            tmp = at; at = nt; nt = tmp;
  1326. X        }
  1327. X        else {                /* a == 2*b    */
  1328. X            ret *= jak_f( &t[nt] );
  1329. X            a_div2( &t[at] );
  1330. X        }
  1331. X
  1332. X    }
  1333. X    
  1334. X    return(ret);
  1335. X}
  1336. X        
  1337. X/*
  1338. X * Probabilistischer Primzahltest
  1339. X *
  1340. X *  0 -> n nicht prim
  1341. X *  1 -> n prim mit  (1-1/2^m) Wahrscheinlichkeit.
  1342. X *
  1343. X *    ACHTUNG !!!!!!
  1344. X *    p_prim benutzt m_init !!
  1345. X *
  1346. X */
  1347. Xint p_prim( n, m )
  1348. XNUMBER *n;
  1349. X{
  1350. X    NUMBER gt,n1,n2,a;
  1351. X    INT *p;
  1352. X    int i,w,j;
  1353. X    long lrand48();
  1354. X
  1355. X    if (a_cmp(n,&a_two) <= 0 || m <= 0)
  1356. X        abort();
  1357. X        
  1358. X    a_sub( n, &a_one, &n1 );    /* n1 = -1    mod n        */
  1359. X    a_assign( &n2, &n1 );
  1360. X    a_div2( &n2 );            /* n2 = ( n -1 ) / 2        */
  1361. X    
  1362. X    m_init( n, NUM0P );
  1363. X    
  1364. X    w = 1;
  1365. X    for (; w && m; m--) {
  1366. X                /* ziehe zufaellig a aus 2..n-1        */
  1367. X        do {
  1368. X            for (i=n->n_len-1, p=a.n_part; i; i--)
  1369. X                *p++ = (INT)lrand48();
  1370. X            if ( i=n->n_len )
  1371. X                *p = (INT)( lrand48() % ((unsigned long)n->n_part[i-1] +1) );
  1372. X            while ( i && ! *p )
  1373. X                p--,i--;
  1374. X            a.n_len = i;
  1375. X        } while ( a_cmp( &a, n ) >= 0 || a_cmp( &a, &a_two ) < 0 );
  1376. X
  1377. X                /* jetzt ist a fertig            */
  1378. X
  1379. X        /*
  1380. X         * n ist nicht prim wenn gilt:
  1381. X         *    (a,n) != 1
  1382. X         * oder
  1383. X         *    a^( (n-1)/2 ) != J(a,n)   mod n
  1384. X         *
  1385. X         */
  1386. X         
  1387. X        a_ggt( &a, n, > );
  1388. X        if ( a_cmp( >, &a_one ) == 0 ) {
  1389. X
  1390. X            j= jakobi( &a, n );
  1391. X            m_exp( &a, &n2, &a );
  1392. X
  1393. X            if  (   ( a_cmp( &a, &a_one ) == 0 && j ==  1 )
  1394. X                 || ( a_cmp( &a, &n1    ) == 0 && j == -1 ) )
  1395. X                w = 1;
  1396. X            else
  1397. X                w = 0;
  1398. X        }
  1399. X        else
  1400. X            w = 0;
  1401. X    }
  1402. X
  1403. X    return( w );
  1404. X}
  1405. X
  1406. X/*
  1407. X * Berechne mulitiplikatives Inverses zu d (mod phi)
  1408. X *    d relativ prim zu phi ( d < phi )
  1409. X *    d.h. (d,phi) == 1
  1410. X *
  1411. X *    ACHTUNG !!!!
  1412. X *    inv benutzt m_init
  1413. X */
  1414. Xvoid inv( d, phi, e )
  1415. XNUMBER *d,*phi,*e;
  1416. X{
  1417. X    int k, i0, i1, i2;
  1418. X    NUMBER r[3],p[3],c;
  1419. X    
  1420. X    /*
  1421. X     * Berlekamp-Algorithmus
  1422. X     *    ( fuer diesen Spezialfall vereinfacht )
  1423. X     */
  1424. X
  1425. X    if (a_cmp(phi,d) <= 0)
  1426. X        abort();
  1427. X    
  1428. X    m_init( phi, NUM0P );
  1429. X    
  1430. X    p[1].n_len = 0;
  1431. X    a_assign( &p[2], &a_one );
  1432. X    a_assign( &r[1], phi );
  1433. X    a_assign( &r[2], d );
  1434. X    
  1435. X    k = -1;
  1436. X    do {
  1437. X        k++;
  1438. X        i0=k%3; i1=(k+2)%3; i2=(k+1)%3;
  1439. X        a_div( &r[i2], &r[i1], &c, &r[i0] );
  1440. X        m_mult( &c, &p[i1], &p[i0] );
  1441. X        m_add( &p[i0], &p[i2], &p[i0] );
  1442. X    } while (r[i0].n_len);
  1443. X
  1444. X    if ( a_cmp( &r[i1], &a_one ) )    /* r[i1] == (d,phi) muss 1 sein    */
  1445. X        abort();
  1446. X        
  1447. X    if ( k & 1 )    /* falsches ''Vorzeichen''    */
  1448. X        a_sub( phi, &p[i1], e );
  1449. X    else
  1450. X        a_assign( e, &p[i1] );
  1451. X}
  1452. END_OF_FILE
  1453.   if test 4732 -ne `wc -c <'Circ/RSA/prim.c'`; then
  1454.     echo shar: \"'Circ/RSA/prim.c'\" unpacked with wrong size!
  1455.   fi
  1456.   # end of 'Circ/RSA/prim.c'
  1457. fi
  1458. if test -f 'Circ/RSA/rsa.c' -a "${1}" != "-c" ; then 
  1459.   echo shar: Will not clobber existing file \"'Circ/RSA/rsa.c'\"
  1460. else
  1461.   echo shar: Extracting \"'Circ/RSA/rsa.c'\" \(4406 characters\)
  1462.   sed "s/^X//" >'Circ/RSA/rsa.c' <<'END_OF_FILE'
  1463. X/*******************************************************************************
  1464. X*                                           *
  1465. X*    Copyright (c) Martin Nicolay,  22. Nov. 1988                   *
  1466. X*                                           *
  1467. X*    Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten   *
  1468. X*    bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter    *
  1469. X*    verwendet werden.                               *
  1470. X*                                           *
  1471. X*    martin@trillian.megalon.de                           *
  1472. X*                                           *
  1473. X*******************************************************************************/
  1474. X
  1475. X#include    <stdio.h>
  1476. X#include    <string.h>
  1477. X#ifndef AMIGA
  1478. X#include    <memory.h>
  1479. X#endif  AMIGA
  1480. X
  1481. X#include    "arith.h"
  1482. X#include    "nio.h"
  1483. X
  1484. X#define    ENCODE    "rsaencode"
  1485. X#define    DECODE    "rsadecode"
  1486. X
  1487. Xchar *prog;
  1488. X
  1489. Xint    clear_siz;            /* clear-text blocksize        */
  1490. Xint    enc_siz;            /* encoded blocksize        */
  1491. X                    /* clear_siz < enc_siz        */
  1492. X
  1493. Xdo_crypt( s, d, len, e )
  1494. Xchar *s;
  1495. Xchar *d;
  1496. XNUMBER *e;
  1497. X{
  1498. X    static char hex[] = "0123456789ABCDEF";
  1499. X    NUMBER n;
  1500. X    char buf[ STRLEN + 1 ];
  1501. X    char *pb,*ph;
  1502. X    int i,c;
  1503. X    
  1504. X    ph = buf + STRLEN;
  1505. X    ph[1] = '\0';
  1506. X    
  1507. X    for (i=len; i; i--) {
  1508. X        c = *s++;
  1509. X        *ph-- = hex[ (c >> 4) & 0xF ];
  1510. X        *ph-- = hex[ c & 0xF ];
  1511. X    }
  1512. X    ph++;
  1513. X    
  1514. X    num_sget( &n, ph );
  1515. X    
  1516. X    m_exp( &n, e, &n );
  1517. X    
  1518. X    num_sput( &n, buf, STRLEN +1 );
  1519. X    
  1520. X    ph = buf + (i=strlen(buf)) -1;
  1521. X    
  1522. X    for (; len; len--) {
  1523. X        if (i-- > 0) {
  1524. X            c = (strchr( hex, *ph ) - hex) << 4;
  1525. X            ph--;
  1526. X        }
  1527. X        else
  1528. X            c=0;
  1529. X        if (i-- > 0) {
  1530. X            c |= strchr( hex, *ph ) - hex;
  1531. X            ph--;
  1532. X        }
  1533. X
  1534. X        *d++ = c;
  1535. X    }
  1536. X}
  1537. X    
  1538. X#ifdef STANDALONE     
  1539. Xint get_clear( p )
  1540. Xchar *p;
  1541. X{
  1542. X    int n;
  1543. X    
  1544. X    n = fread( p, 1, clear_siz, stdin );
  1545. X    
  1546. X    if (n <= 0)
  1547. X        return(0);
  1548. X    
  1549. X    
  1550. X    return(1);
  1551. X}
  1552. X
  1553. Xint get_enc( p )
  1554. Xchar *p;
  1555. X{
  1556. X    int n;
  1557. X
  1558. X    n = fread( p, 1, enc_siz, stdin );
  1559. X    
  1560. X    if (n != enc_siz)
  1561. X        return(0);
  1562. X    
  1563. X    return(1);
  1564. X}
  1565. X
  1566. Xint put_clear( p )
  1567. Xchar *p;
  1568. X{
  1569. X    int n;
  1570. X    
  1571. X    n = fwrite( p, 1, clear_siz, stdout );
  1572. X    
  1573. X    if (n != clear_siz)
  1574. X        return(0);
  1575. X
  1576. X    return(1);
  1577. X}
  1578. X
  1579. Xint put_enc( p )
  1580. Xchar *p;
  1581. X{
  1582. X    int n;
  1583. X
  1584. X    n = fwrite( p, 1, enc_siz, stdout );
  1585. X    
  1586. X    if (n != enc_siz)
  1587. X        return(0);
  1588. X    
  1589. X    return(1);
  1590. X}
  1591. X
  1592. X
  1593. Xmain( argc, argv )
  1594. Xchar **argv;
  1595. X{
  1596. X    char buf[ STRLEN*2 ];
  1597. X    NUMBER n,e;
  1598. X    FILE *keys;
  1599. X    int (*inp)() = 0;
  1600. X    int (*out)() = 0;
  1601. X    
  1602. X    if ( ! (prog=strrchr( argv[0], '/' )) )
  1603. X        prog=argv[0];
  1604. X    
  1605. X    
  1606. X    if ( ! strcmp( prog, DECODE ) ) {
  1607. X        inp = get_enc;
  1608. X        out = put_clear;
  1609. X    }
  1610. X    if ( ! strcmp( prog, ENCODE ) ) {
  1611. X        inp = get_clear;
  1612. X        out = put_enc;
  1613. X    }
  1614. X    
  1615. X    if (! inp) {
  1616. X        fprintf(stderr,"%s: don't know who i am (%s or %s)\n",prog,ENCODE,DECODE);
  1617. X        exit(1);
  1618. X    }
  1619. X    
  1620. X    if (argc != 2) {
  1621. X        fprintf(stderr,"usage: %s keyfile\n",prog);
  1622. X        exit(1);
  1623. X    }
  1624. X    if ( !( keys= fopen(argv[1],"r")) ) {
  1625. X        perror(argv[1]);
  1626. X        exit(1);
  1627. X    }
  1628. X    
  1629. X    num_fget( &n, keys ); getc(keys);
  1630. X    num_fget( &e, keys );
  1631. X    if (a_cmp(&n,&e) <= 0 || e.n_len == 0 || getc(keys) != EOF) {
  1632. X        fprintf(stderr,"%s: corrupt keyfile\n",prog);
  1633. X        fprintf(stderr,"keyfile format:\n");
  1634. X        fprintf(stderr,"\t<n in hex>\n");
  1635. X        fprintf(stderr,"\t<delimiter> (1 char)\n");
  1636. X        fprintf(stderr,"\t<e/d in hex>\n");
  1637. X        fprintf(stderr,"white spaces are ignored\n");
  1638. X        exit(1);
  1639. X    }
  1640. X    
  1641. X    enc_siz = ( n_bitlen( &n ) + 7 ) / 8;
  1642. X    clear_siz = enc_siz -1;
  1643. X    
  1644. X    m_init( &n, NUM0P );
  1645. X    
  1646. X    while ( (*inp)( buf ) ) {
  1647. X        do_crypt( buf, buf, enc_siz, &e );
  1648. X        if (! (*out)( buf ) ) {
  1649. X            perror("output");
  1650. X            exit(1);
  1651. X        }
  1652. X    }
  1653. X    
  1654. X    exit(0);
  1655. X}
  1656. X
  1657. X#else STANDALONE
  1658. X
  1659. Xdo_rsa(keyfile,buffer,buflen,maxlen )
  1660. Xint buflen;
  1661. Xchar *keyfile,*buffer;
  1662. X{
  1663. X    NUMBER n,e;
  1664. X    FILE *keys;
  1665. X    
  1666. X    if ( !( keys= fopen(keyfile,"r")) ) {
  1667. X/*        perror(keyfile);    /* quiet, no errors */
  1668. X        return(-1);
  1669. X    }
  1670. X    
  1671. X    num_fget( &n, keys ); getc(keys);
  1672. X    num_fget( &e, keys );
  1673. X    if (a_cmp(&n,&e) <= 0 || e.n_len == 0 || getc(keys) != EOF) {
  1674. X            /*     
  1675. X        fprintf(stderr,"%s: corrupt keyfile\n",prog);
  1676. X        fprintf(stderr,"keyfile format:\n");
  1677. X        fprintf(stderr,"\t<n in hex>\n");
  1678. X        fprintf(stderr,"\t<delimiter> (1 char)\n");
  1679. X        fprintf(stderr,"\t<e/d in hex>\n");
  1680. X        fprintf(stderr,"white spaces are ignored\n");
  1681. X             */
  1682. X        return(-11);
  1683. X    }
  1684. X    
  1685. X    enc_siz = ( n_bitlen( &n ) + 7 ) / 8;
  1686. X    clear_siz = enc_siz -1;
  1687. X    
  1688. X    m_init( &n, NUM0P );
  1689. X    
  1690. X        if(buflen > enc_siz) {
  1691. X        /*
  1692. X          fprintf(stderr,"Public Key must be larger than data!\n");
  1693. X         */
  1694. X          return(-1);
  1695. X        } 
  1696. X        if(maxlen < enc_siz) {
  1697. X        /* 
  1698. X          fprintf(stderr,"Public key is too big for buffer.\n");
  1699. X         */
  1700. X          return(-1);
  1701. X        }
  1702. X    memset( buffer+buflen, 0, enc_siz - buflen ); /* pad out block */
  1703. X    do_crypt( buffer, buffer, enc_siz, &e );
  1704. X        return(enc_siz);
  1705. X    
  1706. X}
  1707. X
  1708. X#endif   STANDALONE
  1709. X
  1710. END_OF_FILE
  1711.   if test 4406 -ne `wc -c <'Circ/RSA/rsa.c'`; then
  1712.     echo shar: \"'Circ/RSA/rsa.c'\" unpacked with wrong size!
  1713.   fi
  1714.   # end of 'Circ/RSA/rsa.c'
  1715. fi
  1716. if test -f 'Circ/crypt.irc' -a "${1}" != "-c" ; then 
  1717.   echo shar: Will not clobber existing file \"'Circ/crypt.irc'\"
  1718. else
  1719.   echo shar: Extracting \"'Circ/crypt.irc'\" \(1324 characters\)
  1720.   sed "s/^X//" >'Circ/crypt.irc' <<'END_OF_FILE'
  1721. X# Start up the proggie
  1722. X/^exec -name crypt exec new
  1723. X
  1724. X# automatically pick out protocol messages
  1725. X#    crypt processor gets:   !send nick!CLIPPER:...etc
  1726. X#    or   !our nick!SKPJACK:...etc 
  1727. X/on ^public "* CLIPPER:*" /msg %crypt !$0!$1-
  1728. X/on ^public "* SKPJACK:*" /msg %crypt OURNICK:$N;/msg %crypt !$0!$1-
  1729. X/on ^public_other "* * CLIPPER:*" /msg %crypt !$0:$1!$2-
  1730. X/on ^public_other "* * SKPJACK:*" /msg %crypt OURNICK:$N;/msg %crypt !$0:$1!$2-
  1731. X
  1732. X/on ^msg "* CLIPPER:*" /msg %crypt !*$0*!$1-
  1733. X/on ^msg "* SKPJACK:*" /msg %crypt OURNICK:$N;/msg %crypt !*$0*!$1-
  1734. X
  1735. X# messages comming back from crypt, to server or screen?
  1736. X/on ^exec "crypt TCHANNL: *" /msg $C $2-
  1737. X/on ^exec "crypt TSCREEN: *" /echo $2-
  1738. X/on ^exec "crypt TNICKNM: *" /msg $2 $3-
  1739. X
  1740. X# our irc commands:
  1741. X#    /key nick  or /key nick filename
  1742. X#    /die
  1743. X#    /e message to be encrypted
  1744. X#    /p message to be plaintext
  1745. X#    /crypt   (turn on automatic encryption)
  1746. X#    /plain   (turn off automatic encryption)
  1747. X#    /emsg nick text  send an encrypted message
  1748. X/alias key /echo K->*$0* Sending Key;/^msg %crypt SENDKEY: $0-
  1749. X/alias die /^msg %crypt QUITDIE:;/query 
  1750. X/alias e /echo E> $0-;/^msg %crypt CRYPTME:$0-
  1751. X/alias p /msg $C $0-
  1752. X/alias crypt /query %crypt
  1753. X/alias plain /query
  1754. X/alias emsg /echo E->*$0* $1-;/^msg %crypt !$0!CRYPTME:$1-
  1755. X
  1756. X/echo *** Encrypted Irc Protocol loaded. 
  1757. END_OF_FILE
  1758.   if test 1324 -ne `wc -c <'Circ/crypt.irc'`; then
  1759.     echo shar: \"'Circ/crypt.irc'\" unpacked with wrong size!
  1760.   fi
  1761.   # end of 'Circ/crypt.irc'
  1762. fi
  1763. if test -f 'Circ/d3des/d3des.h' -a "${1}" != "-c" ; then 
  1764.   echo shar: Will not clobber existing file \"'Circ/d3des/d3des.h'\"
  1765. else
  1766.   echo shar: Extracting \"'Circ/d3des/d3des.h'\" \(4546 characters\)
  1767.   sed "s/^X//" >'Circ/d3des/d3des.h' <<'END_OF_FILE'
  1768. X/* d3des.h -
  1769. X *
  1770. X *    Headers and defines for d3des.c
  1771. X *    Graven Imagery, 1992.
  1772. X *
  1773. X * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
  1774. X *    (GEnie : OUTER; CIS : [71755,204])
  1775. X */
  1776. X
  1777. X#define D2_DES        /* include double-length support */
  1778. X#define D3_DES        /* include triple-length support */
  1779. X
  1780. X#ifdef D3_DES
  1781. X#ifndef D2_DES
  1782. X#define D2_DES        /* D2_DES is needed for D3_DES */
  1783. X#endif
  1784. X#endif
  1785. X
  1786. X#define EN0    0    /* MODE == encrypt */
  1787. X#define DE1    1    /* MODE == decrypt */
  1788. X
  1789. X/* A useful alias on 68000-ish machines, but NOT USED HERE. */
  1790. X
  1791. Xtypedef union {
  1792. X    unsigned long blok[2];
  1793. X    unsigned short word[4];
  1794. X    unsigned char byte[8];
  1795. X    } M68K;
  1796. X
  1797. Xextern void deskey(/* unsigned char *, short */);
  1798. X/*              hexkey[8]     MODE
  1799. X * Sets the internal key register according to the hexadecimal
  1800. X * key contained in the 8 bytes of hexkey, according to the DES,
  1801. X * for encryption or decryption according to MODE.
  1802. X */
  1803. X
  1804. Xextern void usekey(/* unsigned long * */);
  1805. X/*            cookedkey[32]
  1806. X * Loads the internal key register with the data in cookedkey.
  1807. X */
  1808. X
  1809. Xextern void cpkey(/* unsigned long * */);
  1810. X/*           cookedkey[32]
  1811. X * Copies the contents of the internal key register into the storage
  1812. X * located at &cookedkey[0].
  1813. X */
  1814. X
  1815. Xextern void des(/* unsigned char *, unsigned char * */);
  1816. X/*            from[8]          to[8]
  1817. X * Encrypts/Decrypts (according to the key currently loaded in the
  1818. X * internal key register) one block of eight bytes at address 'from'
  1819. X * into the block at address 'to'.  They can be the same.
  1820. X */
  1821. X
  1822. X#ifdef D2_DES
  1823. X
  1824. X#define desDkey(a,b)    des2key((a),(b))
  1825. Xextern void des2key(/* unsigned char *, short */);
  1826. X/*              hexkey[16]     MODE
  1827. X * Sets the internal key registerS according to the hexadecimal
  1828. X * keyS contained in the 16 bytes of hexkey, according to the DES,
  1829. X * for DOUBLE encryption or decryption according to MODE.
  1830. X * NOTE: this clobbers all three key registers!
  1831. X */
  1832. X
  1833. Xextern void Ddes(/* unsigned char *, unsigned char * */);
  1834. X/*            from[8]          to[8]
  1835. X * Encrypts/Decrypts (according to the keyS currently loaded in the
  1836. X * internal key registerS) one block of eight bytes at address 'from'
  1837. X * into the block at address 'to'.  They can be the same.
  1838. X */
  1839. X
  1840. Xextern void D2des(/* unsigned char *, unsigned char * */);
  1841. X/*            from[16]          to[16]
  1842. X * Encrypts/Decrypts (according to the keyS currently loaded in the
  1843. X * internal key registerS) one block of SIXTEEN bytes at address 'from'
  1844. X * into the block at address 'to'.  They can be the same.
  1845. X */
  1846. X
  1847. Xextern void makekey(/* char *, unsigned char * */);
  1848. X/*        *password,    single-length key[8]
  1849. X * With a double-length default key, this routine hashes a NULL-terminated
  1850. X * string into an eight-byte random-looking key, suitable for use with the
  1851. X * deskey() routine.
  1852. X */
  1853. X
  1854. X#define makeDkey(a,b)    make2key((a),(b))
  1855. Xextern void make2key(/* char *, unsigned char * */);
  1856. X/*        *password,    double-length key[16]
  1857. X * With a double-length default key, this routine hashes a NULL-terminated
  1858. X * string into a sixteen-byte random-looking key, suitable for use with the
  1859. X * des2key() routine.
  1860. X */
  1861. X
  1862. X#ifndef D3_DES    /* D2_DES only */
  1863. X
  1864. X#define useDkey(a)    use2key((a))
  1865. X#define cpDkey(a)    cp2key((a))
  1866. X
  1867. Xextern void use2key(/* unsigned long * */);
  1868. X/*            cookedkey[64]
  1869. X * Loads the internal key registerS with the data in cookedkey.
  1870. X * NOTE: this clobbers all three key registers!
  1871. X */
  1872. X
  1873. Xextern void cp2key(/* unsigned long * */);
  1874. X/*           cookedkey[64]
  1875. X * Copies the contents of the internal key registerS into the storage
  1876. X * located at &cookedkey[0].
  1877. X */
  1878. X
  1879. X#else    /* D3_DES too */
  1880. X
  1881. X#define useDkey(a)    use3key((a))
  1882. X#define cpDkey(a)    cp3key((a))
  1883. X
  1884. Xextern void des3key(/* unsigned char *, short */);
  1885. X/*              hexkey[24]     MODE
  1886. X * Sets the internal key registerS according to the hexadecimal
  1887. X * keyS contained in the 24 bytes of hexkey, according to the DES,
  1888. X * for DOUBLE encryption or decryption according to MODE.
  1889. X */
  1890. X
  1891. Xextern void use3key(/* unsigned long * */);
  1892. X/*            cookedkey[96]
  1893. X * Loads the 3 internal key registerS with the data in cookedkey.
  1894. X */
  1895. X
  1896. Xextern void cp3key(/* unsigned long * */);
  1897. X/*           cookedkey[96]
  1898. X * Copies the contents of the 3 internal key registerS into the storage
  1899. X * located at &cookedkey[0].
  1900. X */
  1901. X
  1902. Xextern void make3key(/* char *, unsigned char * */);
  1903. X/*        *password,    triple-length key[24]
  1904. X * With a triple-length default key, this routine hashes a NULL-terminated
  1905. X * string into a twenty-four-byte random-looking key, suitable for use with
  1906. X * the des3key() routine.
  1907. X */
  1908. X
  1909. X#endif    /* D3_DES */
  1910. X#endif    /* D2_DES */
  1911. X
  1912. X/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
  1913. X ********************************************************************/
  1914. END_OF_FILE
  1915.   if test 4546 -ne `wc -c <'Circ/d3des/d3des.h'`; then
  1916.     echo shar: \"'Circ/d3des/d3des.h'\" unpacked with wrong size!
  1917.   fi
  1918.   # end of 'Circ/d3des/d3des.h'
  1919. fi
  1920. if test -f 'Circ/new.c' -a "${1}" != "-c" ; then 
  1921.   echo shar: Will not clobber existing file \"'Circ/new.c'\"
  1922. else
  1923.   echo shar: Extracting \"'Circ/new.c'\" \(11955 characters\)
  1924.   sed "s/^X//" >'Circ/new.c' <<'END_OF_FILE'
  1925. X
  1926. X#include <stdio.h>
  1927. X#include <unistd.h>   /* R_OK */
  1928. X#include <sys/dir.h>  /* MAXFNAMLEN */
  1929. X
  1930. Xchar *en_crypt(),*de_crypt(); /* external, in crypt.c */
  1931. X
  1932. X/* defines for encoding and decoding */
  1933. X#define KEYLEN  24+1          /* size of keys */ 
  1934. X#define MAXKEYS 30            /* number of keys we keep track of */
  1935. X#define HUGE 1024             /* big size for buffers */
  1936. X#define SECKEY  "secret"      /* secret key file,  should be a variable */
  1937. X#define LINELEN 65            /* must be less than 90,  line wrap */
  1938. X                              /* why? irc message length limits */
  1939. X
  1940. X/* keys database */
  1941. Xchar keys[MAXKEYS][KEYLEN];            /* the actual keys */
  1942. Xunsigned int  sers[MAXKEYS];           /* serial numbers  */
  1943. X
  1944. X/* globals for irc interface */
  1945. Xint nickvalid = 0;             /* tells if 'nick' has valid data */
  1946. Xchar *nick,ournick[50];        /* dest nick and our nick         */
  1947. X
  1948. X/* strings sent to ircII script */
  1949. X#define S_TOSCREEN   "TSCREEN:"
  1950. X#define S_TONICK     "TNICKNM:"
  1951. X#define S_TOCHAN     "TCHANNL:"
  1952. X/* output routines */
  1953. X#define TO_SCREEN(str)    (printf("%s %s\n",S_TOSCREEN,(str)))
  1954. X#define TO_SCRKEY(str)    (printf("%s K<%s> %s\n",S_TOSCREEN,\
  1955. X  (nickvalid)?nick:"???",(str)))
  1956. X#define TO_SCRENC(str)    (printf("%s E<%s> %s\n",S_TOSCREEN,\
  1957. X  (nickvalid)?nick:"???",(str)))
  1958. X#define TO_REMOTE(str)    ((nickvalid)?\
  1959. X  printf("%s %s %s\n",S_TONICK,nick,(str)):\
  1960. X  printf("%s %s\n",S_TOCHAN,(str)))
  1961. X
  1962. X
  1963. X/* find_path()
  1964. X * return path to file if can find it.
  1965. X * look in current dir first, then in $KEYDIR then in
  1966. X * ./pubkeys directory.
  1967. X * if not found.. return null
  1968. X */
  1969. Xchar *find_path(name)
  1970. Xchar *name;
  1971. X{
  1972. X  char *path;
  1973. X  static char fname[MAXNAMLEN];
  1974. X
  1975. X  if(access(name,R_OK)==0) return(name);
  1976. X  if(path=(char *)getenv("KEYDIR")) {
  1977. X    sprintf(fname,"%s/%s",path,name);
  1978. X    if(access(fname,R_OK)==0) return(fname);
  1979. X  }
  1980. X  sprintf(fname,"pubkeys/%s",name);
  1981. X  if(access(fname,R_OK)==0) return(fname);
  1982. X  return(0);
  1983. X}
  1984. X
  1985. X/* casecmp(a,b)
  1986. X     a,b - null terminated strings.
  1987. X       does a non-case sensitive compare
  1988. X */
  1989. X#define To_lower(a)    (isupper(a)?tolower(a):(a))
  1990. X
  1991. Xcasecmp(a,b)
  1992. Xchar *a,*b;
  1993. X{
  1994. X  while(*a && *b) 
  1995. X    if(To_lower(*a) != To_lower(*b)) 
  1996. X      return (*b-*a);   /* doesnt really matter if they are diff cases here*/
  1997. X    else {
  1998. X      a++,b++;
  1999. X    }
  2000. X  return(0);
  2001. X}
  2002. X
  2003. X/* asctobin(str,len)
  2004. X     str - ascii string (null terminated)
  2005. X     len - int *,   RETURN length of binary block
  2006. X     returns:  char * to binary block data in static storage.
  2007. X       coding:
  2008. X         high nybble - 'a'=0 to 'p'=15
  2009. X         low nybble  - 'A'=0 to 'P'=15
  2010. X      NULL returned for bad encoding. 
  2011. X */
  2012. Xchar *asctobin(str,len)
  2013. Xchar *str;
  2014. Xint *len;
  2015. X{
  2016. X  static char buf[HUGE];
  2017. X  char a,b;
  2018. X  int i;
  2019. X
  2020. X  for(i=0;;) {
  2021. X    a= *str++;
  2022. X    while(a==' '||a=='\n') a= *str++;
  2023. X    b= *str++;
  2024. X    if(a=='\0' || b=='\0') {
  2025. X      *len=i;
  2026. X      return(buf);
  2027. X    }
  2028. X    if (a<'a'||a>'p' || b<'A'||b>'P') 
  2029. X      return(0);
  2030. X    buf[i++] = ((a-'a')<<4)|(b-'A');
  2031. X  }
  2032. X}
  2033. X
  2034. X/* bintoasc(str,len)
  2035. X      str - a pointer to a binary block
  2036. X      len - length of binary block in bytes
  2037. X      return - char * to a string that is ascii, null-terminated
  2038. X        coding -
  2039. X           high nybble  'a'=0 to 'p'=15
  2040. X           low nybble   'A'=0 to 'P'=15
  2041. X */
  2042. Xchar *bintoasc(str,len)
  2043. Xint len;
  2044. Xchar *str;
  2045. X{
  2046. X  static char buf[HUGE];
  2047. X  int i;
  2048. X  
  2049. X  for(i=0;len-- >0;str++) {
  2050. X    buf[i++]=((*str&0xf0)>>4) + 'a';
  2051. X    buf[i++]=(*str&0xf) + 'A'; 
  2052. X    if((rand()&0x03) == 0) buf[i++]=' ';  /* wow, now it has spaces! */
  2053. X  }
  2054. X  buf[i]='\0';
  2055. X  return(buf);
  2056. X}
  2057. X
  2058. X/* encode(str)
  2059. X     str - an ascii null-terminated string 
  2060. X     encoding:
  2061. X       CLIPPER:xxxx:yyyyyyyyyyyyy
  2062. X          xxxx - serial number of key used
  2063. X          yyyyy- ascii coded, encrypted text message
  2064. X     Note: only prints LINELEN characters per message. does 
  2065. X           line wrap.
  2066. X     return - nothing, prints results to remote
  2067. X */
  2068. Xencode(str)
  2069. Xchar *str;
  2070. X{
  2071. X  int l,ser,a,i;
  2072. X  char buf[HUGE];
  2073. X  char tmp[LINELEN+5]; 
  2074. X  char *p;
  2075. X
  2076. X  set_key(keys[0]);          /* use our key and our serial number */
  2077. X  a=strlen(str);
  2078. X  while (a>LINELEN) {         /* do line wrap */
  2079. X    for(i=LINELEN;i>0;i--)
  2080. X      if(isspace(str[i])) break;
  2081. X    if(i==0) 
  2082. X      i=LINELEN;             /* couldnt break at a space */
  2083. X    else
  2084. X      i++;                   /* put spaces on the same line */
  2085. X    strncpy(tmp,str,i);     
  2086. X    tmp[i]='\0';
  2087. X    p=en_crypt(tmp,i+2,&l);
  2088. X    sprintf(buf,"CLIPPER:%d:%s",sers[0],bintoasc(p,l));
  2089. X    TO_REMOTE(buf);
  2090. X    a-=i;                    /* skip over what we just outputed */
  2091. X    str+=i;
  2092. X  } 
  2093. X  p=en_crypt(str ,a+1,&l);   /* add 1 so we get the NULL too */
  2094. X  sprintf(buf,"CLIPPER:%d:%s",sers[0],bintoasc(p,l));
  2095. X  TO_REMOTE(buf);
  2096. X}
  2097. X
  2098. X/*  decode(str)
  2099. X      str - ascii string, null terminated
  2100. X       coding:  see encode()
  2101. X       error codes are returned as human readable strings.
  2102. X
  2103. X        CLIPPER:xxxx:yyyyyy
  2104. X            x - ascii serial number
  2105. X            y - ascii encoded binary data, crypted
  2106. X        SKPJACK:xxxx:yyyy:zzzz
  2107. X            x - nick name of destination
  2108. X            y - serial number of key being received
  2109. X            z - ascii encoded binary data,  encrypted with rsa
  2110. X                in 'nick's public key ,  contains the key
  2111. X                needed to read messages from nick
  2112. X       returned - nothing,  results output to screen
  2113. X */
  2114. Xdecode(str)
  2115. Xchar *str;
  2116. X{
  2117. X  char *p;      /* lots of chars */
  2118. X  char buf[HUGE];
  2119. X  int i,ser,l,a,itsakey=0,len;
  2120. X  
  2121. X  if(strncmp(str,"SKPJACK:",8)==0) 
  2122. X    itsakey=1;                          /* someones sending a key */
  2123. X  else if(strncmp(str,"CLIPPER:",8))   
  2124. X      return(0);                    /* not encoded */
  2125. X  for(i=8;str[i]!=':'&&str[i]!='\0';i++);  /* jump past ser # */
  2126. X  if(str[i]!=':') {
  2127. X    TO_SCRENC("*Badly Formed*");
  2128. X    return(0);
  2129. X  }
  2130. X  str[i++]='\0';
  2131. X  ser=atoi(str+8);                          /* this is ser # */
  2132. X
  2133. X  if(itsakey && casecmp(str+8,ournick)==0) {      /* new key sent to us */
  2134. X    ser=atoi(str+i);
  2135. X    for(;str[i]!=':'&&str[i]!='\0';i++) ;
  2136. X    if(str[i++]!=':') {
  2137. X      TO_SCRKEY("*Newkey: badly formed*");
  2138. X      return(0);
  2139. X    }
  2140. X    p=asctobin(str+i,&len);
  2141. X    if(!p)  {
  2142. X      TO_SCRKEY("*new key: bad coding*");
  2143. X      return(0);
  2144. X    }
  2145. X    memcpy(buf,p,len);         /* copy binary data */
  2146. X    p=find_path(SECKEY);
  2147. X    if (!p)  {
  2148. X      TO_SCRKEY("*Newkey: 'secret' not found!*");
  2149. X      return(0);
  2150. X    }
  2151. X    if(do_rsa(p,buf,len,HUGE)<0)  {
  2152. X      TO_SCRKEY("*new key: couldnt decrypt (rsa)*");
  2153. X      return(0);
  2154. X    }
  2155. X    for(i=0;i<MAXKEYS;i++) 
  2156. X      if(sers[i]==0 || sers[i]==ser) break;
  2157. X    if(i==MAXKEYS) {
  2158. X      TO_SCRKEY("*new key: out of table entries*");
  2159. X      return(0);
  2160. X    }
  2161. X    if(sers[i]==ser) {
  2162. X                    /* *never* receive a key we already have */
  2163. X                    /* this could be a trick                 */
  2164. X      TO_SCRKEY("*new key: already have it!*");
  2165. X      return(0);
  2166. X    }
  2167. X    sers[i]= ser;
  2168. X    memcpy(keys[i],buf,KEYLEN);
  2169. X    TO_SCRKEY("*New Key installed*");
  2170. X    return(0);
  2171. X  }
  2172. X  if (itsakey) {
  2173. X    sprintf(buf,"*Saw key for %s*",str+8);
  2174. X    TO_SCRKEY(buf);
  2175. X    return(0);
  2176. X  }
  2177. X
  2178. X  /* else its a message , try to decode */  
  2179. X
  2180. X  a=key(ser);                               /* find the key */
  2181. X  if(a==-1) {
  2182. X    TO_SCRENC("*Dont Have the Key*");
  2183. X    return(0);
  2184. X  }
  2185. X  set_key(keys[a]);
  2186. X  p=asctobin(str+i,&len);                   /* decrypt it */
  2187. X  if(!p) { 
  2188. X    TO_SCRENC("*Bad Encoding*");
  2189. X    return(0);
  2190. X  }
  2191. X  TO_SCRENC(de_crypt(p,len,&l));
  2192. X  return(0);
  2193. X}
  2194. X
  2195. X/*  key(ser)
  2196. X      ser = serial number 
  2197. X      returned - index to the key with serial number ser, else -1 
  2198. X */
  2199. Xint key(ser)
  2200. Xint ser;
  2201. X{
  2202. X  int i;
  2203. X
  2204. X  for(i=0;i<MAXKEYS;i++)
  2205. X    if(ser == sers[i]) return(i);
  2206. X  return(-1);
  2207. X}
  2208. X
  2209. X/* sendkey(line)
  2210. X     line - char *,  everything after  /key on the command line
  2211. X       parsed to 'nick' and the optional 'filename'
  2212. X       filename is set to nick if it doesnt exist.
  2213. X     returned - nothing,  outputs to remote (errors to screen)
  2214. X    encodes our key and serial number with nick's public
  2215. X    key and sends it over the current channel for him
  2216. X    to receive 
  2217. X */
  2218. Xsendkey(line)     /* handle  /key nick [filename]   */
  2219. Xchar *line;
  2220. X{
  2221. X  char *file,*p;
  2222. X  char buf[1024];
  2223. X  int len;
  2224. X
  2225. X  while(*line==' ') line++;
  2226. X  nick=line;
  2227. X  while(*line!=' '&&*line!='\0'&&*line!='\n') line++; 
  2228. X  if(*line=='\n') *line='\0';
  2229. X  if(*line=='\0') 
  2230. X    file=nick;
  2231. X  else {
  2232. X    *line++='\0';
  2233. X    file=line;
  2234. X    while(*line!=' '&&*line!='\0'&&*line!='\n') line++; 
  2235. X    *line='\0';
  2236. X  }
  2237. X  if(*nick=='\0') {
  2238. X    TO_SCREEN("*ERROR*  nick missing,  /key nick [file]");
  2239. X    return;
  2240. X  }
  2241. X
  2242. X  memcpy(buf,keys[0],KEYLEN);
  2243. X  p=find_path(file);
  2244. X  if(!p) {
  2245. X    sprintf(buf,"*Error* public key file '%s' not found",file);
  2246. X    TO_SCREEN(buf);
  2247. X    return(0);
  2248. X  }
  2249. X  len=do_rsa(p,buf,KEYLEN,1024);
  2250. X  if(len<0)  {
  2251. X    sprintf(buf,"*ERROR* public key file corrupt for %s",file);
  2252. X    TO_SCREEN(buf);
  2253. X    return(0);                 /* couldnt send it, RSA failed */
  2254. X  }
  2255. X  p=bintoasc(buf,len);
  2256. X  sprintf(buf,"SKPJACK:%s:%d:%s",
  2257. X          nick,sers[0],p);
  2258. X  nickvalid=1;                 /* send it to their nick */
  2259. X  TO_REMOTE(buf);
  2260. X}
  2261. X
  2262. X/* everything above this line (excluding some #include's and #defines)
  2263. X   is for encoding and decoding messages.
  2264. X */
  2265. Xmain(argc, argv)
  2266. X  int argc;
  2267. X  char **argv;
  2268. X{
  2269. X  int i;
  2270. X
  2271. X  /* pick random  key -> K                */
  2272. X  /* encrypt  crypt(K,K) -> serial number */
  2273. X  /* pick random  L                       */
  2274. X  /* encrypt  crypt(L,K) -> our DES key   */
  2275. X
  2276. X  srand(time(0));
  2277. X  for(i=0;i<KEYLEN;i++)
  2278. X    keys[0][i]= (char)((rand()&0xff00)>>8);
  2279. X  set_key(keys[0]);
  2280. X  en_crypt(keys[0],KEYLEN,&i);
  2281. X  sers[0] = (int) *((int *)keys[0]);  /* pick serial number */
  2282. X  /* if(sers[0]<0) sers[0]=-sers[0];     /* problem with negative ser #'s */
  2283. X  for(i=0;i<KEYLEN;i++)
  2284. X    keys[0][i]= (char)((rand()&0xff00)>>8);
  2285. X  en_crypt(keys[0],KEYLEN,&i);
  2286. X
  2287. X  strcpy(ournick,"*invalid*");      /* dont know yet */
  2288. X
  2289. X  do_it();
  2290. X}
  2291. X
  2292. X/* gets messages from ircII, sends em back to ircII
  2293. X   messages can be from either user, or remote users
  2294. X   and to local screen or to remote users.
  2295. X   to distinguish, client stuff passes it to use with
  2296. X   special headers:
  2297. X        optionally preceeded by:
  2298. X          !nick!       nickname of sending party for
  2299. X                       CLIPPER: and SKIPJACK: 
  2300. X                       nickname of destination for key SENDKEY: 
  2301. X                       CRYPTME:
  2302. X        to us from remote users
  2303. X          CLIPPER:     encrypted message
  2304. X          SKPJACK:     key exchange
  2305. X        to us from local user
  2306. X          CRYPTME:     to be encrypted 
  2307. X          SENDKEY:     send key to another user
  2308. X          QUITDIE:     shut down.. die, etc.
  2309. X          OURNICK:     tell us what our current nick is
  2310. X        to ircII
  2311. X          TSCREEN:     to users screen
  2312. X          TCHANNL:     to current channel 
  2313. X          TNICKNM:     to specified (following) nickname
  2314. X */
  2315. X
  2316. X#define NUMTOK 6 
  2317. Xchar *tok[NUMTOK] = { 
  2318. X     "CLIPPER:","SKPJACK:","CRYPTME:","SENDKEY:","QUITDIE:","OURNICK:", 
  2319. X};
  2320. X
  2321. Xdo_it()         /* main loop here */
  2322. X{
  2323. X  char buf[1024],*str;
  2324. X  char temp[1024];
  2325. X  int i;
  2326. X  while(1) {
  2327. X    if(gets(buf)==NULL)    /* input line from irc */
  2328. X      return;
  2329. X    str=buf;
  2330. X    nickvalid=0;
  2331. X    if(*str == '!') {
  2332. X      nick= ++str;
  2333. X      while(*str!='!' && *str!='\0') str++;
  2334. X      if (*str!='\0') 
  2335. X        *str++='\0';
  2336. X      nickvalid=1;
  2337. X    } else nick="!dunno!";
  2338. X    for(i=0;i<NUMTOK;i++)
  2339. X      if(strncmp(str,tok[i],8)==0) break;
  2340. X    switch(i) {
  2341. X      case  0:      /* encrypted message */
  2342. X      case  1:      /* new key sent to us */
  2343. X           decode(str);
  2344. X           break; 
  2345. X      case  2:      /* message to be encrypted */
  2346. X           encode(str+8);
  2347. X           break;
  2348. X      case  3:      /* send a key to a user */
  2349. X           sendkey(str+8);
  2350. X           break;
  2351. X      case  4:      /* get out of dodge, and quick */
  2352. X           return;
  2353. X      case  5:      /* update ournick */
  2354. X           strcpy(ournick,str+8);
  2355. X           break;
  2356. X
  2357. X      case NUMTOK:
  2358. X      default:      /* no prefix, encrypt it  */
  2359. X          encode(str);
  2360. X          break;
  2361. X    }
  2362. X    fflush(stdout);
  2363. X  }
  2364. X} 
  2365. X
  2366. END_OF_FILE
  2367.   if test 11955 -ne `wc -c <'Circ/new.c'`; then
  2368.     echo shar: \"'Circ/new.c'\" unpacked with wrong size!
  2369.   fi
  2370.   # end of 'Circ/new.c'
  2371. fi
  2372. echo shar: End of archive 2 \(of 3\).
  2373. cp /dev/null ark2isdone
  2374. MISSING=""
  2375. for I in 1 2 3 ; do
  2376.     if test ! -f ark${I}isdone ; then
  2377.     MISSING="${MISSING} ${I}"
  2378.     fi
  2379. done
  2380. if test "${MISSING}" = "" ; then
  2381.     echo You have unpacked all 3 archives.
  2382.     rm -f ark[1-9]isdone
  2383. else
  2384.     echo You still must unpack the following archives:
  2385.     echo "        " ${MISSING}
  2386. fi
  2387. exit 0
  2388. exit 0 # Just in case...
  2389.