Cryptography-Digest Digest #815, Volume #8       Wed, 30 Dec 98 09:13:07 EST

Contents:
  WEAK4-EX -- Another Poorman's 56-bit Data Encryption Algorithm (long) (Mok-Kong Shen)
  New Book "The Unknowable" ([EMAIL PROTECTED])

----------------------------------------------------------------------------

From: Mok-Kong Shen <[EMAIL PROTECTED]>
Subject: WEAK4-EX -- Another Poorman's 56-bit Data Encryption Algorithm (long)
Date: Wed, 30 Dec 1998 13:49:07 +0100

Recently I have designed two 56-bit algorithms, WEAK2-EX and WEAK3-EX,
with which the user can arbitrarily scale up the processing time and
the algorithm initialization time respectively such that the expected
average time for brute forcing can be rendered beyond any practically
infeasible bounds. (The number of rounds in these algorithms can be
suitably chosen such that brute forcing would be the only viable means
of analysis.) Thus, in exchange for some tolerable higher time
expenditure, the user can manage to obtain adequate security despite
the severe limitation posed by the forthcoming 56-bit key length
restriction.

The present algorithm, WEAK4-EX, is based on the same paradox-sounding
paradigm 'security through inefficiency' as its two predecessors but
extends the 'inefficiency' into an additional 'dimension', namely the
volume of the ciphertext. It has in total three user choosable scaling
factors of processing time. The first is the same as one of the two
employed in WEAK2-EX and controls the time rate of pseudo-random
number generation of the PRNG used. The second scaling factor
determines the number of pseudo-random bits thus obtained that are to
be XORed with each single bit of the plaintext. (In WEAK4-EX the
plaintext is treated as a bit stream.) The third scaling factor
determines (approximately) by how much the ciphertext is to be
expanded through filling it with pseudo-random bits at positions that
are determined by the PRNG.

Let input() designate the function delivering the next bit from the
plaintext and scf2 and scf3 be the second and third scaling factor
mentioned above. Then the encryption with WEAK4-EX can be conceptually
(not 'strictly speaking', see below) described by the following very
simple probabilistic automaton, where the function pbit(m) denotes the
result of XORing of m*32 pseudo-random bits obtained from the PRNG,
i.e. their parity:

      do

        with probability 1/scf2:
           output( input() XOR pbit(scf3) );

        with probability 1 - 1/scf2:
           output( pbit(1) );

      od;

In the implementation we use our PRNG (not a TRNG) to determine the
transition of the automaton. Thus the actual process is not random
but only a 'simulation' and is in fact deterministic, being governed
by the seed of the PRNG. For otherwise the receiver of the message
would have a hard task to do the decryption. Thus WEAK4-EX is a
pseudo-randomized encryption. It is not a (true) randomized
encryption such as the time-honoured but apparently now disfavoured
homophone cipher, where the decision of the choice of the homophones
can be made e.g. through casting of dices. (I suggested recently
though that homophones could once again be interesting in the light
of the 56-bit restriction.)

Through the (simulated) probabilistic nature of the algorithm the
analyst has the essential difficulty to identify which bits of the
ciphertext are information-bearing, i.e. encrypted plaintext bits,
and which are the filling nonsense bits. Since the information-bearing
bits are themselves obtained through XORing the plaintext bit with a
large number (some multiples of 32) of pseudo-random bits, brute
forcing would be the only viable method of attack if the factors scf2
and scf3 are adequately chosen. The price that the user has to pay
through the scaling factor scf3 is that the ciphertext is about scf3
times as large as the plaintext and hence incurs correspondingly
higher transmission expenditure. However, if the plaintext is fairly
short, which is very often likely to be the case in a poorman's
environment, such expansion of the ciphertext, if not carried to the
extreme, may well be sensible. In other cases, one can simply set
scf3=1 and exclusively employ the other two scaling factors to achieve
a sufficient level of security.

An implementation in Fortran 90 is attached below. A binary
executable file for PC can be downloaded via my main Web page.

I am indebted to TPS for discussions leading to the present work.

Constructive critiques, comments and suggestions for improvements
are sincerely solicited.

M. K. Shen

=============
NOTE: The program codes of WEAK2-EX and WEAK3-EX have been revised
(with an error reported by CWL and CK corrected). In the zip-file
for download, all three encryption programs and their binaries are
included.



==================================================================
c The design of WEAK4-EX is explained in the text of the article
c introducing the present program code:
c
c    http://www.stud.uni-muenchen.de/~mok-kong.shen/#paper16
c
c See also:
c
c    http://www.stud.uni-muenchen.de/~mok-kong.shen/#paper13
c
c    http://www.stud.uni-muenchen.de/~mok-kong.shen/#paper15
c
c
c Notes:
c
c   1. This program has been designed to be fairly simple in programming
c      logic. It should be independently implementable from scratch in
c      2 to 5 hours with average programming experience.
c
c   2. Pseudo-random generation in WEAK4-EX is the same as that of
c      the standard PRNG in WEAK3-EX. See
c      http://www.stud.uni-muenchen.de/~mok-kong.shen/#paper13
c
c   3. The implementation is scalable. The arbitrarily chosen maximum
c      value settings (Fortran parameter statements) may be trivially
c      changed, if needed. Also the file record length may be changed
c      if a couple of Fortran format statements are correspondingly
c      modified. The parameter statement for mgnseed, however, cannot
c      be modified.
c
c   4. This is a pure stream encoding scheme. The user is reminded of
c      the critical importance of good key management.
c
c   5. For the buffer length etc. the brackets in input prompts
c      indicate the valid ranges. The user should choose values
c      suitable for his applications. It is advisable not to always use
c      the same set of such input values but to vary the configuration
c      of the system over time. For processing time scaling factors see
c      the text of the article introducing this program.
c
c   6. The implementation is for 32 bit processors. A check should be
c      be made in case communication partners use 32 bit processors
c      of different architechture.
c
c   7. The user is strongly advised (not to blindly trust the integrity
c      of codes written by third persons and therefore) to read and
c      critically examine our code before using it.
c
c Program written (copyright) by M. K. Shen on 30th December 1998.
c Tested on PC with INTEL Pentium II using the NAG FTN90 compiler.
c
c
c This program may be freely copied (but only in its entirety), 
c distributed and used for any civil (i.e. personal, academic or
c commercial) purposes conforming to the law, subject to the single 
c condition that in no case the author is to be held responsible for 
c any eventual damages in connection with its use. Any other usage is 
c herewith explicitly disallowed.
c
c
c Critiques, comments and suggestions for improvements are sincerely
c solicited. Author's addresses:
c Postal:  M. K. Shen, Postfach 340238, D-80099 Muenchen, Germany
c e-mail:  [EMAIL PROTECTED]  (subject to change)
c
c
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c
       program weak4ex
c
       implicit integer(a-z)
c
       parameter(maxint=2147483647)
c
c Number of words, number of bytes and number of hexadecimal digits
c in a record (of file type 1)
       parameter(nword=20,nbyte=nword*4,nhex=nword*8)
c
c Dimension of array randb
c randbdim must be divisible by 3.
       parameter(randbdim=900)
c
       parameter(mgnseed=2)
c
c
       common /rbblk/randb(randbdim),rbi
       integer gseeds(mgnseed)
c
       integer aa(nbyte),bb(nword),cc(nword)
       character *12 filein,fileout
       character *(nbyte) rec
       character *(nhex) rec1
       character *14 key
       character kc
       real t0,t1
       real sprng,rscf3
c
c
       print *, "WEAK4-EX --- ",
     1          "Another Poorman's 56-bit Data Encryption Algorithm "
       print *,'Version   : 30th December 1998'
       print *,'Copyright : Mok-Kong Shen, Munich, Germany'
       print *,' '
c
       print *,'give mode (1 = encryption, 2 = decryption)'
       read *,mode
       call rgcheck('mode ',mode,1,2)
c
c Plaintext file has
c    type 1 if 80 ASCII characters per record
c    type 2 if 80 hexadecimal digits ([0,9],[A,F]) per record and
c           there are even number of records
c Ciphertext file always has type 2
c Thus information in one record of file type 1 corresponds to two
c records of file type 2. It is an error if the record number of file
c type 2 is odd.
c Note that, if the input file is not generated by a program but, as
c is normally the case, prepared with a text editor, then the last
c line must be terminated by pressing the return key (but nothing else
c following that, including further pressing of the return key).
c Otherwise, the procesing will be in error.
c Note that file type 1 is restricted generally to contain printable
c characters only (because of possible difficulties caused by some
c non-printable byte values) while file type 2 can contain any binary
c information.
c Thus both types of files can, for example, be directly transported
c via e-mail without requiring additional transformations.
c The file type of plaintext file in encryption and decryption
c should be the same.
c Validity of content of input file is not checked.
c
       print *,'give input file name'
       read *,filein
       if (mode .eq. 1) then
         print *,'give input file type [1, 2] ',
     1           '(1 = ASCII, 2 = hexadecimals)'
         read *,ftype
         call rgcheck('ftype ',ftype,1,2)
       end if
       print *,'give output file name'
       read *,fileout
       if (mode .eq. 2) then
         print *,'give output file type [1, 2] ',
     1           '(1 = ASCII, 2 = hexadecimals)'
         read *,ftype
         call rgcheck('ftype ',ftype,1,2)
       end if
c Range check of gnseed, gseeds, gbufflen, gwichs is
c taken care of by the subprogram initsprng
       print *,'give 56-bit key in 14 hexadecimal digigts',
     1         ' (0-9 or A-F in upper case)'
       read *,key
       do i=1,14
         kc=key(i:i)
         if (.not. ((lge(kc,'0') .and. lle(kc,'9')) .or.
     1              (lge(kc,'A') .and. lle(kc,'F')))) then
           print *,'Error : key digit ',kc,
     1             ' is out of ranges [0-9] and [A-F]'
           stop
         end if
       end do
       read(key,260) gseeds(1),gseeds(2)
       gnseed=2
       print *,'give buffer length of standard PRNG [1, 2000]'
       read *,gbufflen
       print *,'give first processing time scaling factor ',
     1         '[2, 2147483646]'
       print *,'(this determines the number of times to perform ',
     1         'addition mod 1'
       print *,' operations in the standard PRNG. larger value leads ',
     1         'to correspondingly'
       print *,' longer processing time)'
c gwichs determines the number of times to perform addition mod 1
c operations (device of Wichmann and Hill).
       read *,gwichs
       print *,'give second processing time scaling factor ',
     1         '[2, 2147483646]'
       print *,'(this determines the number of multiples of 32 ',
     1         'pseudo-random bits to be'
       print *,' XORed with an information bit. larger value leads to ',
     1         'correspondingly'
       print *,' longer processing time)'
       read *,scf2
       call rgcheck('scf2 ',scf2,2,maxint-1)
       print *,'give third processing time scaling factor ',
     1         '[1, 5000]'
       print *,'(this determines the (approximate) ratio of volume of ',
     1         'ciphertext to'
       print *,' plaintext, based on plaintext type = 2. (doubled for ',
     1         'plaintext type = 1)'
       print *,' larger value leads to',
     1         ' correspondingly longer processing time)'
       read *,scf3
       call rgcheck('scf3 ',scf3,1,5000)
       rscf3=1.0/scf3
c
c Subprogram clock@ is specific to NAG FTN 90 compiler
c Substitution with another name may be needed for other compilers
       call clock@(t0)
c
c
c Initialization of PRNG
       call initsprng(gseeds,mgnseed,gnseed,gbufflen,gwichs)
c Open files
       open(10,file=filein)
       open(20,file=fileout)
c Initialize index to array randb for call of cmprnword
       rbi=randbdim
c Number of records processed
       recn=0
c
 210   format(a)
 220   format(80z2.2)
 230   format(20z8.8)
 260   format(2z7.7)
c
c
c Set number of records written, clear first word for output and
c initialize pointers to cc
       wrecn=0
       cc(1)=0
       cwi=1
       cbi=31
       goto (300,400) mode
c
c
c Encryption
c
c
c Input 1 or 2 plain text record depending on ftype
 300     if (ftype .eq. 1) then
c Read 1 record of ASCII characters
           read(10,210,err=810,end=310) rec
           recn=recn+1
c Convert to integers
           do i=1,nbyte
             aa(i)=iachar(rec(i:i))
           end do
c Convert to hexadecimal digits
           write(rec1,220) aa
         else
c Read 2 records of hexadecimal digits
           read(10,210,err=810,end=310) rec1(1:nbyte)
           read(10,210,err=810,end=820) rec1(nbyte+1:nhex)
           recn=recn+2
         end if
c
c Convert to binary words
         read(rec1,230) bb
c Initialize pointers to word and bit of bb to be processed
         bwi=1
         bbi=31
c
c With probability of 1/scf3 will a bit from plaintext get processed,
c otherwise some pseudo-random bit is output.
         do
           if (sprng() .lt. rscf3) then
c Encrypt the information bit with the parity of scf2*32 pseudo-random
c bits from array randb
             u=ieor(ibits(bb(bwi),bbi,1),pbit(scf2))
             infb=1
           else
c Get the parity of 32 pseudo-random bits from array randb
             u=pbit(1)
             infb=0
           end if
           if (u .ne. 0) cc(cwi)=ibset(cc(cwi),cbi)
           cbi=cbi-1
           if (cbi .lt. 0) then
             if (cwi .eq. nword) then
c Convert to hexadecimal digits in rec1
               write(rec1,230) cc
c Write out 2 cipher text records in hexadecimal format from rec1
               write(20,210) rec1(1:nbyte)
               write(20,210) rec1(nbyte+1:nhex)
               wrecn=wrecn+2
               cwi=1
             else
               cwi=cwi+1
             end if
             cc(cwi)=0
             cbi=31
           end if
           if (infb .ne. 0) then
             bbi=bbi-1
             if (bbi .lt. 0) then
               if (bwi .eq. nword) goto 300
               bwi=bwi+1
               bbi=31
             end if
           end if
         end do
c
 310   if (.not. (cwi .eq. 1 .and. cbi .eq. 31)) then
c Filling the rest of array cc with bits consisting of the parity of
c groups of 32 pseudo-random bits from array randb and output cc
         do j=cbi,0,-1
           u=pbit(1)
           if (u .ne. 0) cc(cwi)=ibset(cc(cwi),j)
         end do
         do i=cwi+1,nword
           cc(i)=0
           do j=31,0,-1
             u=pbit(1)
             if (u .ne. 0) cc(i)=ibset(cc(i),j)
           end do
         end do
c Convert to hexadecimal digits in rec1
         write(rec1,230) cc
c Write out 2 cipher text records in hexadecimal format from rec1
         write(20,210) rec1(1:nbyte)
         write(20,210) rec1(nbyte+1:nhex)
         wrecn=wrecn+2
       end if
c
       print *,recn,' records processed and ',wrecn,' records ',
     1         'written to ',fileout
       goto 900
c
c
c Decryption
c
c
c Input 2 cipher text records in hexadecimal format into rec1 
 400   read(10,210,err=810,end=410) rec1(1:nbyte)
       read(10,210,err=810,end=820) rec1(nbyte+1:nhex)
       recn=recn+2
c
c Convert to binary word
       read(rec1,230) bb
c Initialize pointers to word and bit of bb to be processed
       bwi=1
       bbi=31
c
c See comments for encryption at the corresponding location
       do
         if (sprng() .lt. rscf3) then
c Decrypt the information bit with the parity of scf2*32 pseudo-random
c bits from array randb
           u=ieor(ibits(bb(bwi),bbi,1),pbit(scf2))
           if (u .ne. 0) cc(cwi)=ibset(cc(cwi),cbi)
           cbi=cbi-1
           if (cbi .lt. 0) then
             if (cwi .eq. nword) then
c Convert to hexadecimal digits in rec1
               write(rec1,230) cc
c
c Write out 1 or 2 plain text record depending on ftype
               if (ftype .eq. 1) then
C Convert to integers
                 read(rec1,220) aa
C Convert to ASCII characters
                 do i=1,nbyte
                   rec(i:i)=achar(aa(i))
                 end do
C Write out 1 record of ASCII characters
                 write(20,210) rec
                 wrecn=wrecn+1
               else
c Write out 2 records of hexadecimal digits
                 write(20,210) rec1(1:nbyte)
                 write(20,210) rec1(nbyte+1:nhex)
                 wrecn=wrecn+2
               end if
c
               cwi=1
             else
               cwi=cwi+1
             end if
             cc(cwi)=0
             cbi=31
           end if
         else
c Discard 32 bits (1 word) from array randb
c (we don't need to compute the parity)
           if (rbi .eq. randbdim) then
             call randblock
             rbi=1
           else
             rbi=rbi+1
           end if
         end if
         bbi=bbi-1
         if (bbi .lt. 0) then
           if (bwi .eq. nword) goto 400
           bwi=bwi+1
           bbi=31
         end if
       end do
c
 410   print *,recn,' records processed and ',wrecn,' records ',
     1         'written to ',fileout
       goto 900
c
c
 810   print *,'error in reading ',filein
       goto 900
 820   print *,'error: ',filein,' does not have even number of records'
c
c
 900   call clock@(t1)
       print *,'processing time = ',t1-t0,' sec'
       end
c
c
cccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccc
c
c This is adapted from WEAK3-EX with uprng replaced by sprng and
c change of parameters.
c
c Filling the array randb with pseudo-random bits.
c
       subroutine randblock
       implicit integer(a-z)
       parameter(randbdim=900)
       parameter(cc=2**24,ms3=255,ms2=ms3*256,ms1=ms2*256)
       common /rbblk/randb(randbdim),rbi
       real sprng
       k=0
c randbdim is divisible by 3
       do i=1,randbdim/3
c Obtain 24 bits from each call to uprng. 4 calls are needed to
c get 3 words of 32 bits.
c There are 24 bits in the mantissa part of a real number of 32 bit
c processors. Hence it is not sensible to obtain more than 24 bits
c from a pseudo-random number delivered by sprng.
         h1=sprng()*cc
         h2=sprng()*cc
         h3=sprng()*cc
         h4=sprng()*cc
         randb(k+1)=ior(ishft(h1,8),ishft(h2,-16))
         randb(k+2)=ior(ishft(h2,16),ishft(h3,-8))
         randb(k+3)=ior(ishft(h3,24),h4)
         k=k+3
       end do
       end
cccccccccccccccccccccccccccccc
c
c Obtaining the parity (i.e. XOR of all bits) of scf*32 bits from the
c array randb
c The global varialbe rbi is to be initialized to randbdim before
c first call of this function.
c
       integer function pbit(scf)
       implicit integer(a-z)
       parameter(randbdim=900)
       common /rbblk/randb(randbdim),rbi
       s=-1
       do i=1,scf
         if (rbi .eq. randbdim) then
           call randblock
           rbi=1
         else
           rbi=rbi+1
         end if
         u=randb(rbi)
         do j=0,31
           if (btest(u,j)) s=-s
         end do
       end do
       if (s .lt. 0) then
         pbit=0
       else
         pbit=1
       end if
       end
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c The following set of subprograms are taken from the implementation
c of WEAK3-EX.
c  
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c Check whether k is in [k1, k2].
c
       subroutine rgcheck(string,k,k1,k2)
       character (*) string
       if (k .lt. k1 .or. k .gt. k2) then
         print *,'Error : ',string,k,' is out of range [',k1,',',k2,']'
         stop
       end if
       end
cccccccccccccccccccccccccccccc
c
c Copying of seeds and initialization of pointers and filling of the
c shuffling buffer of the output of the multiple seed PRNG parkms.
c After this is called, the standard PRNG sprung can be used.
c Copying is done to render the set of Fortran subprograms independent
c of the main program, thus facilitating their employment by main
c programs written in other languages than Fortran.
c This subprogram is not directly called by the user.
c
       subroutine initsprng(gseeds,mgnseed,gnseed,gbufflen,gwichs)
       implicit integer(a-z)
       parameter(maxint=2147483647)
       parameter(mbufflen=2000)
       integer gseeds(mgnseed)
       common /msp/seeds(3),sqi
       common /bds/buffer,bufflen,buffi,wichs
       real buffer(0:mbufflen-1)
       real parkecuyer
c Exactly 2 elements required in gseeds
       call rgcheck('gnseed ',gnseed,2,2)
       bufflen=gbufflen
       call rgcheck('gbufflen ',bufflen,1,mbufflen)
       wichs=gwichs
c We require that wichs be at least 2
       call rgcheck('gwichs ',wichs,2,maxint-1)
c Check that each element in gseeds is 28 bits
       do i=1,gnseed
         call rgcheck('gseeds ',gseeds(i),1,2**28-1)
       end do
c In parkecuyer the PRNG of Park and Miller needs 1 seed while that
c of L'Ecuyer needs 2 seeds. These are arbitrarily obtained from
c gseeds as follows:
       seeds(1)=gseeds(1)
       seeds(2)=gseeds(1)
       seeds(3)=gseeds(2)
c Initialization of pointer used in parkecuyer             
       sqi=0
c Initialization of pointer of buffer used in sprng
       buffi=0
c Filling of buffer
       do i=0,bufflen-1
         buffer(i)=parkecuyer()
       end do
       end
cccccccccccccccccccccccccccccc
c
c Standard PRNG.
c This corresponds to sprng of WEAK3-EX
c
c Algorithm of Bays and Durham is used to shuffle the output of parkms.
c Method of Wichmann and Hill is used to combine wichs successive
c numbers output from the shuffling buffer to form the output of sprng.
c Returns a pseudo-random number in [0,1).
c Requires initialization by initsprng.
c
       real function sprng()
       implicit integer(a-z)
       parameter(mbufflen=2000)
       common /bds/buffer,bufflen,buffi,wichs
       real buffer(0:mbufflen-1)
       real parkecuyer,rr,rr2
c Obtain one number from the shuffling buffer
c Algorithm of Bays and Durham
       rr=buffer(buffi)
       buffer(buffi)=parkecuyer()
       buffi=rr*bufflen
c Obtain further numbers from the shuffling buffer and combine
       do i=2,wichs
c Algorithm of Bays and Durham
         rr2=buffer(buffi)
         buffer(buffi)=parkecuyer()
         buffi=rr2*bufflen
c Addition of rr and rr2 mod 1 (device of Wichmann and Hill)
         rr=rr+rr2
         if (rr .ge. 1.0) rr=rr-1.0
       end do
c Avoid rounding to 1.0.
       if (rr .ge. 0.999999) rr=0.999999
       sprng=rr
       end
cccccccccccccccccccccccccccccc
c
c If sqi=0 the PRNG of Park and Miller is called (seed(1))
c If sqi=1 the PRNG of L'Ecuyer is called (seed(2) and seed(3))
c sqi ensures that the two PENGs are called alternatingly.
c
c This is not directly called by the user.
c
c Returns a pseudo-random number in [0,1)
c The global variable sqi is to be initialized to 0 before first
c call of this function.
c All seeds must be in [1, 2^31-2].
c
       real function parkecuyer()
       implicit integer(a-z)
       parameter(mbufflen=2000)
       common /msp/seeds(3),sqi
       real random
c
       if (sqi .eq. 0) then
         sqi=1
c Use PRNG of Park and Miller
         seed=seeds(1)
c
c Algorithm of Park and Miller
         hi=seed/127773
         lo=mod(seed,127773)
         test=16807*lo-2836*hi
         if (test .gt. 0) then
           seed=test
         else
           seed=test+2147483647
         end if
         random=real(seed)/2147483647
c Avoid rounding to 1.0.
         if (random .ge. 0.999999) random=0.999999
c
c Store back new seed value
         seeds(1)=seed
       else
         sqi=0
c Use PRNG of L'Ecuyer
         s1=seeds(2)
         s2=seeds(3)
c
c Algorithm of L'Ecuyer
         a1=53668
         a2=52774
         b1=40014
         b2=40692
         c1=12211
         c2=3791
         m1=2147483563
         m2=2147483399
         q1=s1/a1
         s1=b1*(s1-a1*q1)-c1*q1
         if (s1 .lt. 0) s1=s1+m1
         q2=s2/a2
         s2=b2*(s2-a2*q2)-c2*q2
         if (s2 .lt. 0) s2=s2+m2
         z=s1-s2
         if (z .lt. 1) z=z+2147483562
         random=z*4.656613e-10
c Avoid rounding to 1.0.
         if (random .ge. 0.999999) random=0.999999
c
c Store back new seed value
         seeds(2)=s1
         seeds(3)=s2
       end if
c
c Return random to caller.
       parkecuyer=random
       end

------------------------------

From: [EMAIL PROTECTED]
Subject: New Book "The Unknowable"
Date: Wed, 30 Dec 1998 12:42:21 GMT

Hi folks, this is to let everyone know that I've
just finished a new book, "The Unknowable".
It's a prequel/sequel to my book on "The Limits
of Mathematics".  "The Unknowable" is available
in html and in postscript at these two URL's:
http://www.umcs.maine.edu/~chaitin/unknowable
http://www.cs.auckland.ac.nz/CDMTCS/chaitin/unknowable
Best wishes for 1999,
GJC

============= Posted via Deja News, The Discussion Network ============
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    

------------------------------


** FOR YOUR REFERENCE **

The service address, to which questions about the list itself and requests
to be added to or deleted from it should be directed, is:

    Internet: [EMAIL PROTECTED]

You can send mail to the entire list (and sci.crypt) via:

    Internet: [EMAIL PROTECTED]

End of Cryptography-Digest Digest
******************************

Reply via email to