Random-Handler is a Native DOS Handler for AmigaOS to produce sequences of
random bytes, mostly used on cryptography or related applications.
The Handler has been designed to allow the use of various different types
of RNGs (Random Number Generators) by just providing a filename or other,
as well other ways to change it interactively, and even the seed values.
This handler has been developed on an A1200 with AmigaOS v3.5 and a
Blizzard 68060 board, The Random Generators has been optimized where
possible to pass the Chi-Square tests (some unsucesfull, as you'll see),
check the file benchmarks.txt to see my own results and feel free to send
me your report by running the randomtest tool in the hope to perform some
optimizations.
_______________________________________________________________________________
-------------------------------------------------------------------------------
Random-Handler Glosary:
RNG: Random Number Generator
PRNG: Pseudo Random Number Generator
CSPRNG: Cryptographically Secure Pseudo Random Number Generator
ENT: Shell tool (created by John 'Random' Walker) which applies various
tests to sequences of bytes for evaluate entropy per byte, compressibility,
arithmetic mean value, etc
_______________________________________________________________________________
-------------------------------------------------------------------------------
Random Generators Supported and/or created for this Handler:
<id> 1
<desc> Single generator using FastRand()
This is a "must" in the sense to implement what is available on our OS, but
the random data generating by this function is really a crap.. if you need
to known more about it check the amiga.lib docs. The read buffer is filled
peforming iterations of 32-bits.
<id> 2
<desc> Single generator using RangeRand()
Same as FastRand(), RangeRand() however works slower but it generates better
entropy, it does iterations of 16-bits, this can be improved/optimized but
we decided to keep it as-is for legacy reasons...
<id> 3
<desc> Mouse movements (plus XOR deviations)
This isnt a real RNG by itself but on how it has been created generates a
good entropy, more or less faster (less than more..), and the most important
thing is that the Chi-Square test is reasonable passed compared to others
RNGs, ofcouse that the mouse can't be quiet to generate something good.
How the mouse movements are detected is just reading the Custom chips
registers, which values are recorded then incrementally XORed and that
filled to the read buffer on iterations of 16-bits.
<id> 4
<desc> CIA / Custom / etc things
This works on a similar way to Mouse movements, it reads various
Amiga's hardware registers which used to generate the random data.
<id> 5
<desc> Linear Congruential Generator
Generates 2**31-2 random numbers, based on "Random Number Generators: Good
Ones Are Hard to Find", S.K. Park and K.W. Miller, Communications of the
ACM 31:10 (Oct 1988), and "Two Fast Implementations of the 'Minimal Standard'
Random Number Generator", David G. Carta, Comm. ACM 33, 1 (Jan 1990), p. 87-88
Uses L. Schrage's method to avoid overflow problems.
<id> 6
<desc> McGill Super-Duper RNG
The McGill Super-Duper Random Number Generator, incorporates the Ziggurat
method of sampling from decreasing... Created by K. Ananthanarayana, N. Paul,
G. Marsaglia, W.W. Tsang and which has been rewritted into C by E. Schneider.
<id> 7
<desc> Marsaglia's algorithm
This method implements the concatenation of following two 16-bit multiply
with carry x(n)=a*x(n-1)+carry mod 2^16 and y(n)=b*y(n-1)+carry mod 2^16
number and carry packed within the same 32 bit integer.
Algorithm recommended by Marsaglia from the diehard tests.
<id> 8
<desc> Combination of three tausworth generators.
Source: Pierre L'Ecuyer, "Maximally Equidistributed Combined Tausworthe
Generators". Mathematics of Computation, vol.65, no.213(1996), pp203--213.
<id> 9
<desc> Twisted GFSR generator
A twisted GFSR generator with an unusually long peroid. (2^800)
<id> 10
<desc> Default IBBA generator.
An implementation of Robert Jenkins' IBAA (Indirection, Barrelshift,
Accumulate, and Add) generator. Very fast and it seems excellent.
The read buffer is filled with iterations of 32-bits, such integers are
obtained from a private pool of 1024 bytes
<id> 11
<desc> Own IBBA Generator
Optimized IBAA Generator which shifts 128-bits per iteration, this is done
by using a two-side pool which makes it work faster.
<id> 12
<desc> Mersenne Twister
A newer twisted GFSR generator with an incredibly long period of 2^19937.
The read buffer is filled on iterations of 64-bits using a private pool
(such pool can contain a maximun of 624 ULONGs)
<id> 13
<desc> CSPRNG from Amiga's ExecBase
A funny method of Cryptographicaly Secure random data generation, very good
but slow.. It reads the System's Exec base on chunks of ULONG, which are
used later as keys to generate the cryptographically random numbers.
(This is a BETA RNG and should be revised and optimized..)
If you like to see some other algorithm implemented on the handler just
request it and we will study it.
_______________________________________________________________________________
-------------------------------------------------------------------------------
Usage:
Normal usage from programs is just using the normal dos.library functions,
Open() -> Read() -> Close(), remember this is a system-friendly DOS Handler,
hence you can even use "type random: >ram:entropy" without problems at all!
Hence to use the handler from AmigaDOS command line tools just follow the
instructions from the first packet description ( ACTION_FIND#? / Open() ).
The supported DOS Packets by the handler are the follow:
ACTION_FINDINPUT
ACTION_FINDUPDATE
ACTION_FINDOUTPUT
These packets implements the Open() function, from the filename to be
openend you can chose what RNG to use and even the Seed value which internally
will be used to the whole generators...
To Select the RNG type, use "rX" where X is the id number assigned as above
mentioned.
To the Seed value, use "sXYZ" where XYZ is a decimal value for the new Seed to
be used internally by the RNGS, that value should be from 1 to 4294967296.
To Enable Cryptographically Secure Random Numbers put "c" AT THE END of the
filename, ie: RANDOM:r4c, that will crypt the data generated by RNG #4, If
what you want is to just generate a quick and safe sequence, ie: for
digital-fingerprint usage, just use RANDOM:c<key>, where <key> is the
secret key to use to generate such sequence.
NOTE that if you use "c" or "c<key>" that MUST be at the end of the filename
or it will not work properly!...
examples:
Open( "RANDOM:r3", MODE_NEWFILE)
Will open the random stream type 3 (Mouse movements)
Open( "ranDOm:r2s245786633", MODE_NEWFILE)
Will open the random stream 2, and use 245786633 as the
initial seed value.
Open( "RANDOM:r2s245786633c", MODE_NEWFILE)
Same as above but the random data is crypted.
Open("random:", MODE_NEWFILE)
Will use the default RNG and Seed (the initial seed value
used by default comes from the E-Clock)
Open( "Random:cNoMeJodas", MODE_NEWFILE )
Will generate a Cryptographically Secure Sequence using as
secret key "NoMeJodas"
ACTION_READ
This packet implements the Read() function, not much to say, it is
obvious how it works (see the example at below if so)
ACTION_WRITE
This packet implements the Write() function, note that you can't
write to the ramdom stream, obviously. It is implemented as a way to
propagate more unpredictable results...
When you have open a random stream, if you want to reinitialize the seeder,
you may think on doing Close() -> Open("random:rXsXYZ",0), you can do that to
give a known(!) new seed value,
however is faster (and will be less predictable) just using:
Write(fh, mydata, mydatalen);
The CRC CheckSum of 'mydata' will be used to reinitialize the internal seeder.
ACTION_SEEK
ACTION_SET_FILE_SIZE
These two packets, like ACTION_WRITE, are just wrappers to other
behaviors which aren't the default.
Using Seek() on a open random stream is used to change interactively the RNG
type, without the need to re-opened a new file.
ie: Seek( fh, 4, 0); will change the fh's RNG type to 4 (note that even if
you try to use a wrong type it will fall back to the default one)
NOTE: the value returned by Seek() is the seed currently in use!, therefore
if what you want is to obtain such value only, just use Seek(fh,-1,0);
ACTION_LOCATE_OBJECT
ACTION_FREE_LOCK
These packets are but aren't here... ;-)
ACTION_INFO
ACTION_DISK_INFO
These two packets are implemented as fun mainly... The number of
blocks are the number of times a RNG worked, and the BytesPerBlock the
average random bytes which have been generated since the random: device was
mounted. (therefore, if you like to know how many random data have been
generated just use (NumBlocks * BytesPerBlock) :o)
ACTION_END
ACTION_DIE
These packets implements Close() and UnMount ... nothing more to say.
_______________________________________________________________________________
-------------------------------------------------------------------------------
Code Examples:
1) Normal Usage to obtain random data
int main( void )
{
BPTR fh;
if((fh = Open( "RANDOM:r3", MODE_NEWFILE)))
{
APTR buffer;
ULONG buflen;
buflen = 1024;
if((buffer = AllocMem( buflen+1, MEMF_ANY )))
{
if(Read( fh, buffer, buflen ) == buflen)
{
while(buflen-- > 0)
Printf("%02lx", *((UBYTE *)buffer)++);
}
FreeMem( buffer, 1025 );
}
Close( fh );
}
PrintFault( IoErr(), "something failed");
return(EXIT_SUCCESS);
}
2) Cryptographically Secure Sequence for digital-fingerprint
int main(int argc, char * argv[] )
{
BPTR fh;
UBYTE file[34], dfg[16];
if( argc != 2 )
{
Printf("Usage: %s <key>\a\n",(long) argv[0] );
return(EXIT_FAILURE);
}
snprintf( file, sizeof(file)-1, "RANDOM:c%s", argv[1] );
if((fh = Open( file, MODE_NEWFILE)))
{
if(Read( fh, dfg, sizeof(dfg)) == sizeof(dfg))
{
int x;
Printf("Your digital-fingerprint for key \"%s\""
" is:\n",(long) &file[8] );
for( x = 0 ; x < sizeof(dfg) ; x++ )
Printf("%02lX",(long) dfg[x] );
PutStr("\n");
}
Close( fh );
}
PrintFault( IoErr(), "something failed");
return(EXIT_SUCCESS);
}
_______________________________________________________________________________
-------------------------------------------------------------------------------
Installation:
Cd into the "Handler" folder as found into the archive and copy the "RAMDOM"
mount-list file to SYS:Devs/DOSDrivers or to SYS:Storage/DOSDrivers, and the
random-handler file to L:, when finished use "Mount RANDOM:" to actvate it.
_______________________________________________________________________________
-------------------------------------------------------------------------------
Usefull Links:
http://random.mat.sbg.ac.at/~charly/server/node3.html
http://www.derkeiler.com/Newsgroups/sci.crypt/2004-09/0880.html
http://www.mathcom.com/corpdir/techinfo.mdir/scifaq/q210.html
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
http://senderek.de/security/secret-key.protection.html
http://www.iro.umontreal.ca/~simardr/indexe.html
http://citeseer.ist.psu.edu/context/35616/0
http://www.csis.hku.hk/~diehard/
http://www.fourmilab.ch/random/
http://csrc.nist.gov/rng/
http://amiga.sourceforge.net/ .. :-)
_______________________________________________________________________________
-------------------------------------------------------------------------------
History:
Arround the year 2003, when Ive started coding on C, one of my
various first projects was to create a file handle which generates random
data to be used on my OpenSSH port, since ixemul.library lacks a
/dev/random unit, then looking the net for examples and docs on how to
create Handlers ive found a good example (on the fish disks, IIRC),
Empty-handler created by Oliver Wagner, that handler does nothing apart
creating a zeroed file, but let me understand how works internatelly the
File Handlers for AmigaOS, well, with that example as base of my work Ive
started imagining how to generate proper entropy data... First thing Ive
tested was just using the lame FastRand() function, but his data sucks too
much therefore with some help from the E-Clock values as to the seeds it
was a bit better.. but however it was still a shit (4.2 bits per byte, or
so). Then I decided to change how to generate the random data, but hey...
why a handler should manage only a type of data? indeed here I chossed
that handler will be able to manage not a single entropy generator,
depending the filename given it will decide what to use, ie random:r1
random:r2 etc, certain cases will require a faster random data generator
only and not the better entropy which generated slowy, hence thats the way
to do it. well, happily ;) ive continued implementing a new RNG, now
testing how RangeRand() does his work... it worked more slowy than
FastRand() (well, the function names says all ;-), but indeed was much
better, 7.8 bits per byte of entropy!, wow, almost prefect!... At this
step the 0.1 version of the handler was ready, working fine..and stable :-)
However, although it worked well, I wasn't satisfied... and looking the
net Ive found some PD-RNGs (Public Domain Random Number Generators) which
Ive integrated into the handler as well, they was fex a LCG (Linear
congruential generator) By Ray Gardner (based on "Random Number Generators:
Good Ones Are Hard to Find", and "Two Fast Implementations of the 'Minimal
Standard' Random Number Generator"), Or The McGill Super-Duper Random
Number Generator (Incorporating the Ziggurat method of sampling from
decreasing or symmetric unimodal density functions), both methods worked on
a similar way for entropy (about 7.8 bits per byte as well) but lots faster
than RangeRand()! ... Unfortunatelly on the 2004, due some issue I can't
remember right now - and due others projects comming - Ive stoped further
improving of the handler and finally wasn't publically released, and these
days (yeah, two years later!) just remembered this handler after an idea of
creating a new handler comes to my mind, and to be again familiar with
Handlers I decided to rewrite almost from scrach this random-handler, and
in addition optimizing it all as possible... and well... here is
the result, hope you like it! :-)
btw, I give a BIG thanks to the people mentioned here, this Handler was
possible thanks to your previous work!...
_______________________________________________________________________________
-------------------------------------------------------------------------------
Licence:
Random-Handler, Copyright (c)2006 Diego Casorran
All rights reserved.
Random-Handler is FREEWARE, do what you want with it, but there is
no warranty of any kind, use it at your own risk.
if you would like to pay/donate anything for it I'll appreciate it,
but instead you can go to http://amiga.sf.net/ and click on the
Google Adverts, that will be fine for me as well, thanks :-)
|