Main
 
Programs
Writings
Algorithms
About
Links
Contact
 
Using ARC4 as a random number generator
   The heart of the ARC4 algorithm is acualy a strong random number generator in which the key is the seed value.  For encryption, this key-seeded stream of random numbers is XORed with the plaintext to produce the encrypted text.
   One can make a strong random number generator with this system by modifying the XOR part of the encryption process and storing just using the XOR value as the random number.  The guts would look something like this :

type
    SeedType = record
      State : array[ 0..255 ] of byte;
      x     : byte;
      y     : byte;
    end;

...

function GetRandom : byte;
begin
     Inc( Seed.x );
     Inc( Seed.y , Seed.State[ Seed.x ] );

     SwapByte( Seed.State[ Seed.x ] , Seed.State[ Seed.y ] );

     GetRandom := Seed.State[ Seed.State[ Seed.x ] + Seed.State[ Seed.y ] ];
end;

   The trick is getting the whole thing started (i.e. seeding the generator).  The best way to do this is feeding in 256 "real-world" random bytes (2048-bits).  These may come from things such as delay time between keystrokes or mouse movement.  Then, the standard init may look something like this :

procedure InitRandom( const RandomStream : array of byte );
var
   Index1  : byte;
   Index2  : byte;
begin
     { Zero varables }
     Seed.x := 0;
     Seed.y := 0;

     { Initial 256 byte matrix with each element set to it's index }
     for Index1 := 0 to 255 do
       Seed.State[ Index1 ] := Index1;

     { Modify matrix }
     Index2 := 0;
     for Index1 := 0 to 255 do
     with Seed do
     begin
          Inc( Index2 , ( RandomStream[ Index1 ] + State[ Index1 ] ) );
          SwapByte( State[ Index1 ] , State[ Index2 ] );
     end;
end;

   If the predictions on the RC4 algorithm are correct, this should create a generator with a period greated than 10**100.  The seed would could be saved directly to disk after each use so the stream can be restarted.  To stop traceing of the generators last stream, the generator could be reseeded with a random stream before being saved, like this :

procedure Reseed;
var
   RandomStream : array[ 0..255 ] of byte;
   Index        : byte;
begin
     for Index := 0 to 255 do
       RandomStream[ Index ] := GetRandom;

     InitRandom( RandomStream );
end;

   Sence the 'RandomStream' acts like the key does for normal RC4 operations, there's no way to the new stream back to 'RandomStream', which means there's no way to trace the new seed back to the old seed.  This is nessary in generators used for creating public/private keys sets.


Copyright ©2001-2005, Punkroy. Bla, bla, bla...
=:(