home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / pc / crypto / cracking.txt < prev    next >
Encoding:
Internet Message Format  |  2003-06-11  |  18.9 KB

  1. From: cwe@it.kth.se (Christian Wettergren)
  2. Newsgroups: mail.cypherpunks
  3. Subject: Re: Netscape SSL implementation is broken!
  4. Message-ID: <199509180525.HAA06519@piraya.electrum.kth.se>
  5. Date: 18 Sep 95 05:26:16 GMT
  6.  
  7. Hi!
  8.  
  9. Neat, I'd say. Has everyone sold their Netscape Comm stock yet? :-)
  10.  
  11. I guess we should send them the draft-ietf-security-randomness-00.txt
  12. asap.
  13.  
  14. I was also thinking about how many Credit Card numbers will pass
  15. between now and the moment Netscape has done anything about it.
  16. This piece of information does have quite a value, I'd say.
  17.  
  18. I have included a short program that tries to generate non-guessable
  19. random numbers. It was written a bit back, and my coding style isn't
  20. all that good. It might be interesting, or not.  (Btw, if you find any
  21. problems with it, I'd appreciate to know about it.)
  22.  
  23. /Christian
  24.  
  25.  
  26. ----- ZZ: README -----
  27. asadi -
  28.    "As strong as DES is" (hopefully)
  29.  
  30. Written by: Christian Wettergren
  31.             cwe@nada.kth.se
  32.             February 1993
  33.  
  34. Introduction
  35. ------------
  36.  
  37. This utility generates a "random" hexstring, which can be used as input
  38. to xauth, for example. It uses a private secret and some other input
  39. to generate the hexstring. In this way a long-term secret can be used
  40. to generate a short-term secret. Since the short-term secret might be
  41. compromised (different xauth cookies might be tried repeatedly, since 
  42. o warning is emitted from the Xserver) it is not safe to use the
  43. same secret on repeated occasions.
  44.  
  45. This utility does not even need a private long-term secret, since it
  46. may use the ticket generated within the Kerberos authentication system.
  47. In this way the long-term secret is as guarded as your private password
  48. or the Kerberos master-password.
  49.  
  50. If you don't use the Kerberos system, you have to regenerate the long-term
  51. secret sometimes (in the same way as you change your password). This
  52. utility tries to help you with that step too. A decent pseudo-random
  53. generator is included, and a routine that helps you generate the secret
  54. might be run.
  55.  
  56. The short-term secret wont reveal anything about the long-term secret,
  57. since the long-term secret is altered and then encrypted with DES. The
  58. result is the short-term secret. 
  59.  
  60.  
  61. Search space
  62. ------------
  63.  
  64. The algorithm used to generate the long-term secret tries to enlarge the
  65. search-space as much as possible. so that an exhaustive attack becomes
  66. difficult.
  67.  
  68. The factors involved are:
  69.  
  70.      1/ A good random generator
  71.      2/ time-of-day
  72.      3/ user entered text
  73.      4/ user dependant elapsed time
  74.      5/ pid of process
  75.      6/ hostid of computer
  76.      7/ not using consecutive values from
  77.         random generator (initial throw-away &
  78.         intermediate throw-away.)
  79.  
  80. The most important of all is of course the random generator. The included 
  81. generator is a minimum standard.
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.     Probable usage: 
  90.       echo add $DISPLAY MIT-MAGIC-COOKIE-1 `asadi` | xauth 
  91.  
  92.     DISCLAIMER: No guarantees are made about this
  93.     program, explicit or implicit. It is distributed
  94.     AS IS. etc... :-)
  95.  
  96.   opensafely() -
  97.   open file, try not to reveal when it was
  98.   written.
  99.  
  100.   Unfortunately, this is not possible!
  101.   No matter how this is done, at least the
  102.   ctime reveals when it was written.
  103.  
  104.   If I don't remember incorrectly, there are
  105.   bugs in the filesystem under SunOS, so that
  106.   the ctime-field is updated too often. Maybe 
  107.   this might distort this field sometimes.
  108.  
  109.   Another approach might be to chmod the file
  110.   whenever it is used. In this way it's ctime
  111.   field is updated and hence overwritten.
  112.   It does not reveal anything extra either, 
  113.   since the approximate time when the cookie is
  114.   generated is probably shown in ~/.Xauthority
  115.   anyway.
  116.  
  117.  
  118. /* gensecret() -
  119.  
  120.    generate a good secret "random" file.
  121.  
  122.    This routine tries to enlarge the search-space
  123.    for a potential cracker. The involved factors
  124.    are:
  125.  
  126.      1/ A good random generator (see accompanying file.)
  127.      2/ time-of-day
  128.      3/ user entered text
  129.      4/ user dependant elapsed time
  130.      5/ pid of process
  131.      6/ hostid of computer
  132.      7/ not using consecutive values from
  133.         random generator (initial throw-away &
  134.         intermediate throw-away.)
  135.  
  136.    This approach hopefully deters an attack, or at least
  137.    makes it considerably harder for the attacker.
  138.  
  139.    Does anyone see any weakness in the above approach? It
  140.    is not based on any cryptological analysis, so no
  141.    guarantees are made of it's appropriateness.
  142. */
  143.  
  144.   fprintf(stderr, "asadi - generate a good random hexstring based on\n");
  145.   fprintf(stderr, "        a private secret as a seed. (This secret can\n");
  146.   fprintf(stderr, "        be the Kerberos ticket-file.) Could be used\n");
  147.   fprintf(stderr, "        for getting a good xauth-cookie, for example.\n\n");
  148.   fprintf(stderr, "Usage: asadi [-r] [-l n] [-v] [filename]\n");
  149.   fprintf(stderr, "       -r   -- generate a secret file (default: ~/.secret\n");
  150.   fprintf(stderr, "       -l n -- how many 8-byte blocks to output (default: 16)\n");
  151.   fprintf(stderr, "       -v   -- verbose, not very interesting.\n");
  152.   fprintf(stderr, "       filename -- name of secret file (default: Kerberos\n");
  153.   fprintf(stderr, "                   ticket file, or ~/.secret)\n");
  154.  
  155.  
  156. ---- ZZ: asadi.c ----
  157.  
  158. /*****************************************
  159.     asadi v1.1 -
  160.       "As strong as DES is" (hopefully)
  161.  
  162.     This utility generates a "random" 
  163.     hexstring, which can be used as input
  164.     to xauth, for example. Either a Kerberos
  165.     ticketfile or a secret file is used as
  166.     seed to the random generator. Other input
  167.     is probably hostid, process id and time,
  168.     depending on the implementation of the 
  169.     DES-library.
  170.  
  171.     The random generator used is the DES-
  172.     algorithm. This method is guaranteed 
  173.     not to reveal anything about the used 
  174.     seed. To crack the cookie you have to 
  175.     crack DES. (There is also a normal good 
  176.     pseudo-random generator included, to
  177.     facilitate the generation of secrets.)
  178.  
  179.  
  180.     Written by: Christian Wettergren
  181.                 cwe@nada.kth.se
  182.                 February 1993
  183.  
  184.     Usage:
  185.       asadi [keyfilename] [-v] [-l num] [-r]
  186.  
  187.     The number of 8-byte blocks to 
  188.     generate can be controlled with the 
  189.     -l-switch. There is also a verbose-
  190.     switch.
  191.  
  192.     If one does not use Kerberos, a secret file
  193.     can be used as a key instead. The contents 
  194.     of this file will not be revealed by this 
  195.     program, but you should of course NOT USE 
  196.     your password anyway!
  197.  
  198.     To help generate this secret file is a
  199.     decent (according to it's author, not me) random-
  200.     generator included in this program. Use
  201.     the r-switch for this. It deposits the secret
  202.     in the file ~/.secret (with the appropriate
  203.     chmod). This file is also used if there is
  204.     no Kerberos.
  205.  
  206.     Probable usage: 
  207.       echo add $DISPLAY MIT-MAGIC-COOKIE-1 `asadi` | xauth 
  208.  
  209.     DISCLAIMER: No guarantees are made about this
  210.     program, explicit or implicit. It is distributed
  211.     AS IS. etc... :-)
  212. *****************************************/
  213.  
  214.  
  215. /* Settings of this program */
  216.  
  217. #define USEKRB /* switches the use of Kerberos on/off */
  218. #define DEFAULTKEYLEN  8 /* multiples of 16 nibbles */
  219. #define SECRETFILE ".secret"
  220.  
  221.  
  222. #include <stdio.h>
  223. #include <errno.h>
  224. #include <sys/types.h>
  225. #include <sys/time.h>
  226. #include <sys/stat.h>
  227. #include <utime.h>
  228. #include <fcntl.h>
  229. #include <des.h>
  230. #ifdef USEKRB
  231. #include <krb.h>
  232. #endif
  233.  
  234. /* some unprototyped routines */
  235. extern char *getpass();
  236. extern void goodsrand(unsigned long);
  237. extern unsigned long goodrand(void);
  238. extern char *getenv(char *);
  239. extern void *malloc(int);
  240.  
  241.  
  242. /* Globals */
  243. char *keyfile = NULL;
  244. int vflag = 0;
  245. int keylen = DEFAULTKEYLEN;
  246.  
  247. int major = 1; /* version of program */
  248. int minor = 0;
  249.  
  250. /* calculate a secret key from the file. */
  251.  
  252. /* Algorithm: read 8 bytes, add them byte-wise to the
  253.    cblock, continue until eof.
  254.  
  255.    Hence there is no actual reason to use files
  256.    larger than eight bytes, but the above approach is
  257.    used since the ticket-files are larger. (In this 
  258.    way I don't have to care about file's structure 
  259.    too much, either.)
  260. */
  261. void calcsecretkey(char *file, des_cblock *key) {
  262.  
  263.   des_cblock tmp;
  264.   int i;
  265.   int fd;
  266.  
  267.   if (vflag)
  268.     fprintf(stderr, "file: %s\n", keyfile);
  269.  
  270.   if ((fd = open(file, O_RDONLY)) == -1) {
  271.     fprintf(stderr, 
  272.         "Could not open '%s', no cookie generated! (errno=%d)\n", 
  273.         file, errno);
  274.     exit(1);
  275.   }
  276.  
  277.   while (read(fd, &tmp, sizeof(des_cblock)) == sizeof(des_cblock)) {
  278.     for(i = 0; i < sizeof(des_cblock); i++)
  279.       *((unsigned char *)key + i)
  280.     = *((unsigned char *)key + i) + *((unsigned char *)tmp + i);
  281.     DES_ZERO_CBLOCK(tmp);  /* fixes eof-condition */
  282.   }
  283.  
  284.   /* close the file */
  285.   if (close(fd) == -1) {
  286.     fprintf(stderr, "Could not close file! (errno=%d)\n", errno);
  287.     exit(1);
  288.   }
  289. }
  290.  
  291.  
  292. void printcblock(FILE *fd, des_cblock *blk) {
  293.  
  294.   int i;
  295.   for(i=0; i < sizeof(des_cblock); i++) {
  296.     fprintf(fd, "%02x", 
  297.        (unsigned int)(*((unsigned char *)blk + i) & 255));
  298.   }
  299. }
  300.  
  301. /* 
  302.   opensafely() -
  303.   open file, try not to reveal when it was
  304.   written.
  305.  
  306.   Unfortunately, this is not possible!
  307.   No matter how this is done, at least the
  308.   ctime reveals when it was written.
  309.  
  310.   If I don't remember incorrectly, there are
  311.   bugs in the filesystem under SunOS, so that
  312.   the ctime-field is updated too often. Maybe 
  313.   this might distort this field sometimes.
  314.  
  315.   Another approach might be to chmod the file
  316.   whenever it is used. In this way it's ctime
  317.   field is updated and hence overwritten.
  318.   It does not reveal anything extra either, 
  319.   since the approximate time when the cookie is
  320.   generated is probably shown in ~/.Xauthority
  321.   anyway.
  322. */
  323. int opensafely(char *file) {
  324.  
  325.   int fd;
  326.  
  327.   /* delete old file, if any */
  328.   if (unlink(file) == -1) {
  329.     if (errno != ENOENT) {
  330.       fprintf(stderr, "Error: could not unlink '%s'. (errno=%d)\n", 
  331.           file, errno);
  332.       exit(1);
  333.     }
  334.   }
  335.  
  336.   /* open it again */
  337.   if ((fd = open(file, O_WRONLY|O_CREAT, S_IRUSR)) == -1) {
  338.     fprintf(stderr, "Error: could not create '%s'. (errno=%d)\n", 
  339.         file, errno);
  340.     exit(1);
  341.   }
  342.   return(fd);
  343. }
  344.  
  345. /* gensecret() -
  346.    generate a good secret "random" file.
  347.  
  348.    This routine tries to enlarge the search-space
  349.    for a potential cracker. The involved factors
  350.    are:
  351.  
  352.      1/ A good random generator (see accompanying file.)
  353.      2/ time-of-day
  354.      3/ user entered text
  355.      4/ user dependant elapsed time
  356.      5/ pid of process
  357.      6/ hostid of computer
  358.      7/ not using consecutive values from
  359.         random generator (initial throw-away &
  360.         intermediate throw-away.)
  361.  
  362.    This approach hopefully deters an attack, or at least
  363.    makes it considerably harder for the attacker.
  364.  
  365.    Does anyone see any weakness in the above approach? It
  366.    is not based on any cryptological analysis, so no
  367.    guarantees are made of it's appropriateness.
  368. */
  369. void gensecret(char *file) {
  370.  
  371.   int i,j;
  372.   struct timeval t, s;
  373.   unsigned long d, u, v;
  374.   int fd;
  375.   unsigned long x;
  376.   char *c;
  377.   char n[100];
  378.   int ta, b;
  379.   struct utimbuf tm;
  380.  
  381.   /* Get time before enter */
  382.   gettimeofday(&s, (struct timezone *)0);
  383.   
  384.   /* heading */
  385.   printf("\nGenerating a Secret!\n");
  386.  
  387.   /* get user's response */
  388.   printf("\nCAUTION! Don't use your password below!\n");
  389.   printf("You don't have to remember this data, so\n");
  390.   printf("just type something in.\n\n");
  391.   c = getpass("Enter something:");
  392.  
  393.   /* get time after enter */
  394.   gettimeofday(&t, (struct timezone *)0);
  395.   d = t.tv_usec - s.tv_usec;
  396.  
  397.   /* make something of input */
  398.   for(j=0; j < strlen(c) / sizeof(unsigned long); j++) {
  399.  
  400.     /* collect sizeof(long) bytes of input */
  401.     for(v=0, i=0; i < sizeof(unsigned long); i++) 
  402.       v = (v << 8) + c[i+j*sizeof(unsigned long)];
  403.  
  404.     /* xor them together */
  405.     u ^= v;
  406.   }
  407.  
  408.   /* get throw-away factors */
  409.   printf("\nEnter a throw-away factor: ");
  410.   gets(n);
  411.   ta = atoi(n);
  412.   printf("\nEnter a step factor: ");
  413.   gets(n);
  414.   b = atoi(n);
  415.  
  416.   /* verbose */
  417.   if (vflag) {
  418.     fprintf(stderr, "text: %s\n", c);
  419.     fprintf(stderr, "garbled text: %ld\n", u);
  420.     fprintf(stderr, "elapsed: %ld\n", d);
  421.     fprintf(stderr, "time: %ld %ld\n", t.tv_sec, t.tv_usec);
  422.     fprintf(stderr, "pid: %d\n", getpid());
  423.     fprintf(stderr, "hostid: %d\n", gethostid());
  424.     fprintf(stderr, "throw-away factor: %d\n", ta);
  425.     fprintf(stderr, "step factor: %d\n", b);
  426.     fprintf(stderr, "generated seed: %ld\n", t.tv_usec ^ t.tv_sec ^ d ^ getpid() ^ gethostid() ^ u);
  427.   }
  428.  
  429.   /* init random generator */
  430.   goodsrand(t.tv_usec ^ t.tv_sec ^ d ^ getpid() ^ gethostid() ^ u);
  431.   
  432.   /* open the file safely */
  433.   fd = opensafely(keyfile);
  434.  
  435.   /* throw-away ta numbers */
  436.   for(i=0; i < ta; i++)
  437.     (void)goodrand();
  438.  
  439.   /* 
  440.      this actually writes sizeof(long) 
  441.      times too much data, but it does not
  442.      matter. 
  443.   */
  444.   for (i=0; i<sizeof(des_cblock); i++) {
  445.  
  446.     x = goodrand();
  447.     if (write(fd, &x, sizeof(unsigned long)) != sizeof(unsigned long)) {
  448.       fprintf(stderr, 
  449.           "Error: could not write '%s'. (errno=%d)\n", 
  450.           keyfile, errno);
  451.       exit(1);
  452.     }
  453.  
  454.     /* throw-away (step) b numbers */
  455.     for(j=0; j < b; j++)
  456.       (void)goodrand();
  457.   }
  458.  
  459.   /* close the file */
  460.   if (close(fd) == -1) {
  461.     fprintf(stderr, 
  462.         "Error: could not close '%s'. (errno=%d)\n", 
  463.         SECRETFILE, errno);
  464.     exit(1);
  465.   }
  466.   
  467.   /* 
  468.      reset times on file.
  469.      (ctime still shows the creation-time though) 
  470.   */
  471.   tm.actime = 0;
  472.   tm.modtime = 0;
  473.   if (utime(keyfile, &tm) == -1) {
  474.     fprintf(stderr, "warning: could not reset times on file '%s'.\n", keyfile);
  475.     fprintf(stderr, "You should /bin/touch it manually at a later time!\n");
  476.   }
  477.  
  478.   fprintf(stderr, "Secret written to '%s'.\n", keyfile);
  479. }
  480.  
  481. void hidedate(char *file) {
  482.  
  483.   if (chmod(file, 0) == -1) {
  484.     fprintf(stderr, "warning: could not chmod '%s'. (errno=%d)\n");
  485.   }
  486.   if (chmod(file, S_IRUSR) == -1) {
  487.     fprintf(stderr, "warning: could not chmod '%s'. (errno=%d)\n");
  488.   }
  489. }
  490.  
  491. void usage(void) {
  492.  
  493.   fprintf(stderr, "asadi v%d.%d\n", major, minor);
  494.   fprintf(stderr, "        generate a good random hexstring based on\n");
  495.   fprintf(stderr, "        a private secret as a seed. (This secret can\n");
  496.   fprintf(stderr, "        be the Kerberos ticket-file.) Could be used\n");
  497.   fprintf(stderr, "        for getting a good xauth-cookie, for example.\n\n");
  498.   fprintf(stderr, "Usage: asadi [-r] [-l n] [-v] [filename]\n");
  499.   fprintf(stderr, "       -r   -- generate a secret file (default: ~/.secret\n");
  500.   fprintf(stderr, "       -l n -- how many 8-byte blocks to output (default: 16)\n");
  501.   fprintf(stderr, "       -v   -- verbose, not very interesting.\n");
  502.   fprintf(stderr, "       filename -- name of secret file (default: Kerberos\n");
  503.   fprintf(stderr, "                   ticket file, or ~/.secret)\n");
  504. }
  505.  
  506. int main(int argc, char *argv[]) {
  507.  
  508.   int i;
  509.   int l;
  510.   int rflag = 0;
  511.   int gfn = 0;
  512.   des_cblock key;
  513.   des_cblock out;
  514.  
  515.   /* Handle options */
  516.   for (i=1; i < argc; i++) {
  517.     
  518.     if (argv[i][0] == '-') {
  519.       switch(argv[i][1]) {
  520.  
  521.       case 'v':
  522.     vflag++;
  523.     break;
  524.  
  525.       case 'l':
  526.     i++;
  527.     keylen = atoi(argv[i]);
  528.     break;
  529.  
  530.       case 'r':
  531.     rflag++;
  532.     break;
  533.  
  534.       case 'h':
  535.     usage();
  536.     return(1);
  537.     break;
  538.  
  539.       default:
  540.     fprintf(stderr, "error: Unknown option '%s'.\n", argv[i]);
  541.     usage();
  542.     return(1);
  543.       }
  544.     }
  545.     else {
  546.       keyfile = argv[i];
  547.       gfn++;
  548.     }
  549.   }
  550.  
  551. #ifdef USEKRB
  552.   if (!keyfile && !rflag) {
  553.     keyfile = tkt_string();
  554.     gfn = 0;
  555.   }
  556. #endif
  557.   if (!keyfile) {
  558.     char *h;
  559.     if ((h = getenv("HOME")) == NULL) 
  560.       h = ".";
  561.     keyfile = malloc(sizeof(char) * strlen(h) + 2 + strlen(SECRETFILE));
  562.     strcpy(keyfile, h);
  563.     strcat(keyfile, "/");
  564.     strcat(keyfile, SECRETFILE);
  565.     gfn++;
  566.   }
  567.  
  568.   /* Which mode are we in? */
  569.   if (rflag) {
  570.     gensecret(keyfile);
  571.     return(1);
  572.   }
  573.  
  574.   /* hide creation-date */
  575.   if (gfn)
  576.     hidedate(keyfile);
  577.  
  578.   /* calculate secret key from file */
  579.   calcsecretkey(keyfile, &key);
  580.  
  581.   /* show secret key, if verbose mode */
  582.   if (vflag) {
  583.     fprintf(stderr, "secret key: ");
  584.     printcblock(stderr, &key);
  585.     fprintf(stderr, "\n");
  586.   }
  587.  
  588.   /* init the DES random-generator */
  589.   des_init_random_number_generator(&key);
  590.  
  591.   /* remove traces of secret key */
  592.   DES_ZERO_CBLOCK(key);
  593.  
  594.   /* generate output */
  595.   for(l=0; l < keylen; l++) {
  596.     des_random_cblock(&out);
  597.     printcblock(stdout, &out);
  598.     DES_ZERO_CBLOCK(out);
  599.   }
  600.   printf("\n");
  601.  
  602.   return(0);
  603. }
  604.  
  605.  
  606. ----- ZZ: rand.c -----
  607. /*
  608.  * This program is public domain and was written by William S. England
  609.  * (Oct 1988).  It is based on an article by:
  610.  *
  611.  * Stephen K. Park and Keith W. Miller. RANDOM NUMBER GENERATORS:
  612.  * GOOD ONES ARE HARD TO FIND. Communications of the ACM,
  613.  * New York, NY.,October 1988 p.1192
  614.  
  615.    From: wengland@stephsf.com (Bill England)
  616.    Newsgroups: alt.sources,comp.lang.c,rec.games.programmer,comp.os.msdos.programmer
  617.    Subject: Re: random number generator (random.c)
  618.    Date: 5 Jan 92 20:12:08 GMT
  619.    Organization: Stephen Software Systems Inc., Tacoma/Seattle, +1 800 829 1684
  620.  
  621. Modifications;
  622.  
  623.    Sun Feb 10 18:20:38 PST 1991
  624.     WSE, modified for replacement of random number object file
  625.     under unix and for use with Perl.
  626.  
  627.  The following is a portable c program for generating random numbers.
  628.  The modulus and multipilier have been extensively tested and should
  629.  not be changed except by someone who is a professional Lehmer generator
  630.  writer.  THIS GENERATOR REPRESENTS THE MINIMUM STANDARD AGAINST WHICH
  631.  OTHER GENERATORS SHOULD BE JUDGED. ("Quote from the referanced article's
  632.  authors. WSE" )
  633. */
  634.  
  635. #include <stdio.h> 
  636.  
  637. #define    m  (unsigned long)2147483647
  638. #define    q  (unsigned long)127773
  639.  
  640. #define    a (unsigned int)16807
  641. #define    r (unsigned int)2836
  642.  
  643. /*
  644. ** F(z)    = (az)%m
  645. **    = az-m(az/m)
  646. **
  647. ** F(z)  = G(z)+mT(z)
  648. ** G(z)  = a(z%q)- r(z/q)
  649. ** T(z)  = (z/q) - (az/m)
  650. **
  651. ** F(z)  = a(z%q)- rz/q+ m((z/q) - a(z/m))
  652. **      = a(z%q)- rz/q+ m(z/q) - az
  653. */
  654.  
  655. /*
  656. **
  657. */
  658. unsigned long seed;
  659.  
  660. void goodsrand( /* unsigned long*/ initial_seed)
  661. unsigned long initial_seed;
  662. {
  663.     seed = initial_seed; 
  664. }
  665. /*
  666. **
  667. */
  668. unsigned long goodrand(/*void*/){
  669.  
  670. register
  671. int     lo, hi, test;
  672.  
  673.     hi   = seed/q;
  674.     lo   = seed%q;
  675.  
  676.     test = a*lo - r*hi;
  677.  
  678.     if (test > 0)
  679.     seed = test;
  680.     else
  681.     seed = test+ m;
  682.  
  683.     return seed;
  684. }
  685.  
  686. #ifdef TEST1
  687. /*  
  688. **   The result of running this program should be
  689. **   1043618065.  If this program does not yeild this
  690. **   value then your compiler has not implemented this
  691. **   program correctly.
  692. */
  693.  
  694. main(/*void*/)
  695. {
  696. unsigned 
  697. long    n_rand;
  698.  
  699. register int     i;
  700. int    success = 0;
  701.  
  702.     goodsrand(1);
  703.  
  704.     for( i = 1; i <= 10001; i++){
  705.         n_rand = goodrand();
  706.  
  707.         if( i> 9998)  
  708.         printf("Sequence %5i, Seed= %10i\n", i, seed ); 
  709.  
  710.     if( i == 10000) 
  711.         if( seed == 1043618065 ) 
  712.         success = 1;
  713.     }
  714.  
  715.     if (success){
  716.     printf("The random number generator works correctly.\n\n");
  717.     exit(0);
  718.     }else{
  719.     printf("The random number generator DOES NOT WORK!\n\n");
  720.     exit(1);
  721.     }
  722. }
  723. #endif
  724. /*
  725. -- 
  726.  +-  Bill England,  wengland@stephsf.COM -----------------------------------+
  727.  |   * *      H -> He +24Mev                                                |
  728.  |  * * * ... Oooo, we're having so much fun making itty bitty suns *       |
  729.  |__ * * ___________________________________________________________________| 
  730. */
  731.  
  732.  
  733. ---- ZZ: Makefile ----
  734.  
  735. #
  736. # Makefile for asadi.
  737. #
  738.  
  739. CC=gcc
  740. CFLAGS=-g
  741. LIBS=-lkrb -ldes
  742.  
  743. asadi: asadi.c rand.o
  744.     ${CC} ${CFLAGS} -o asadi asadi.c rand.o ${LIBS}
  745.  
  746. rand.o: rand.c
  747.     $(CC) -c rand.c
  748.  
  749.  
  750.