Re: [RFC] enhanced version of net_random()

From: Richard B. Johnson
Date: Fri Aug 20 2004 - 14:24:52 EST


On Fri, 20 Aug 2004, Andreas Dilger wrote:

> On Aug 20, 2004 13:59 -0400, Jean-Luc Cooke wrote:
> > Is there a reason why get_random_bytes() is unsuitable?
> >
> > Keeping the number of PRNGs in the kernel to a minimum should a goal we can
> > all share.
>
> For some uses a decent PRNG is enough, and the overhead of get_random_bytes()
> is much too high. We've needed something like this for a long time (something
> that gives decenly uniform numbers) and hacks to use useconds/cycles/etc do
> not cut it. I for one welcome a simple in-kernel interface to
> e.g. get_urandom_bytes() (or net_random() as this is maybe inappropriately
> called) that is only pseudo-random but fast and efficient.
>
> Cheers, Andreas
> --
> Andreas Dilger

The attached code will certainly work on Intel machines. It is
in the public domain, having been modified by myself to produce
a very long sequence...

I wouldn't suggest converting it to 'C' because the rotation
takes many CPU instructions when one tries to do the test, shift,
and OR in 'C',

Cheers,
Dick Johnson
Penguin : Linux version 2.4.26 on an i686 machine (5570.56 BogoMips).
Note 96.31% of all statistics are fiction.


#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#
# File rnd.S Created 04-FEB-1999 Richard B. Johnson
#
# Simple random number generator. Based upon Alan R. Miller's
# algorithm. Professor of Metallurgy, University of New Mexico
# Institute of Mining and Technology, circa 1980. Published
# In the 8080/Z-80 Assembly Language manual he wrote.
#
# unsigned size_t rnd((size_t *) seed);
#
# The seed can be initialized with time(&seed); on each boot.
#

MAGIC = 0x72b6078b
INTPTR = 0x08
DIVISR = 0x0c
.section .text
.global rnd
.type rnd,@function
.align 0x04
rnd: pushl %ebx
movl INTPTR(%esp), %ebx
movl (%ebx), %eax
rorl $3, %eax
addl $MAGIC, %eax
movl %eax, (%ebx)
popl %ebx
ret

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#
# This returns a random number between 0 and one less than the
# input divisor, i.e. n mod rand(x).
#
# size_t modrnd((size_t *) seed, size_t divisor);
#
.type modrnd,@function
.global modrnd
.align 0x04

modrnd: pushl %ebx
movl INTPTR(%esp), %ebx
movl (%ebx), %eax
rorl $3, %eax
addl $MAGIC, %eax
movl %eax, (%ebx)
xorl %edx, %edx
divl DIVISR(%esp)
movl %edx, %eax
popl %ebx
ret
.end
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-