From 106fd12423491625b78326a2d2055d7e1d43464f Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 25 Apr 2013 17:59:42 +1000 Subject: [PATCH 1/2] rt: pull upstream ISAAC code for consistency between 32/64 bit platforms The "unsigned 4 byte" `ub4`s are actually 8 bytes on 64-bit platforms which mean that some bits > 2**32 were retained in calculations, these would then "reappear" after a shift and so the stream of random numbers would differ on 32 bit vs 64 bit platforms. --- src/rt/isaac/randport.cpp | 41 ++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/rt/isaac/randport.cpp b/src/rt/isaac/randport.cpp index 5b40506f8565f..a2928a9b5d08e 100644 --- a/src/rt/isaac/randport.cpp +++ b/src/rt/isaac/randport.cpp @@ -6,6 +6,7 @@ rand.c: By Bob Jenkins. My random number generator, ISAAC. Public Domain 970719: use context, not global variables, for internal state 980324: make a portable version 010626: Note this is public domain + 100725: Mask on use of >32 bits, not on assignment: from Paul Eggert ------------------------------------------------------------------------------ */ #ifndef STANDARD @@ -27,22 +28,22 @@ rand.c: By Bob Jenkins. My random number generator, ISAAC. Public Domain void isaac(randctx *ctx) { - register ub4 a,b,x,y,*m,*mm,*m2,*r,*mend; + ub4 a,b,x,y,*m,*mm,*m2,*r,*mend; mm=ctx->randmem; r=ctx->randrsl; - a = ctx->randa; b = (ctx->randb + (++ctx->randc)) & 0xffffffff; + a = ctx->randa; b = ctx->randb + (++ctx->randc); for (m = mm, mend = m2 = m+(RANDSIZ/2); m>6 , a, b, mm, m, m2, r, x); + rngstep( (a & 0xffffffff) >>6 , a, b, mm, m, m2, r, x); rngstep( a<<2 , a, b, mm, m, m2, r, x); - rngstep( a>>16, a, b, mm, m, m2, r, x); + rngstep( (a & 0xffffffff) >>16, a, b, mm, m, m2, r, x); } for (m2 = mm; m2>6 , a, b, mm, m, m2, r, x); + rngstep( (a & 0xffffffff) >>6 , a, b, mm, m, m2, r, x); rngstep( a<<2 , a, b, mm, m, m2, r, x); - rngstep( a>>16, a, b, mm, m, m2, r, x); + rngstep( (a & 0xffffffff) >>16, a, b, mm, m, m2, r, x); } ctx->randb = b; ctx->randa = a; } @@ -50,14 +51,14 @@ void isaac(randctx *ctx) #define mix(a,b,c,d,e,f,g,h) \ { \ - a^=b<<11; d+=a; b+=c; \ - b^=c>>2; e+=b; c+=d; \ - c^=d<<8; f+=c; d+=e; \ - d^=e>>16; g+=d; e+=f; \ - e^=f<<10; h+=e; f+=g; \ - f^=g>>4; a+=f; g+=h; \ - g^=h<<8; b+=g; h+=a; \ - h^=a>>9; c+=h; a+=b; \ + a^=b<<11; d+=a; b+=c; \ + b^=(c&0xffffffff)>>2; e+=b; c+=d; \ + c^=d<<8; f+=c; d+=e; \ + d^=(e&0xffffffff)>>16; g+=d; e+=f; \ + e^=f<<10; h+=e; f+=g; \ + f^=(g&0xffffffff)>>4; a+=f; g+=h; \ + g^=h<<8; b+=g; h+=a; \ + h^=(a&0xffffffff)>>9; c+=h; a+=b; \ } /* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */ @@ -81,8 +82,10 @@ void randinit(randctx *ctx, word flag) /* initialize using the contents of r[] as the seed */ for (i=0; i Date: Fri, 26 Apr 2013 22:13:24 +1000 Subject: [PATCH 2/2] rt: use the [u]int[nn]_t types in the RNG. This means that `ub4`s are always 4 bytes, rather than being 8 bytes on x64. (Suggested but not implemented by upstream: "Porting it to a 64-bit machine [...] may just need an adjustment of the definition of ub4") --- src/rt/isaac/standard.h | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/rt/isaac/standard.h b/src/rt/isaac/standard.h index cb6cc15b8f686..c196a37474b9d 100644 --- a/src/rt/isaac/standard.h +++ b/src/rt/isaac/standard.h @@ -13,27 +13,32 @@ Standard definitions and types, Bob Jenkins # include # define STDDEF # endif -typedef unsigned long long ub8; +# ifndef STDINT +# include +# define STDINT +# endif + +typedef uint64_t ub8; #define UB8MAXVAL 0xffffffffffffffffLL #define UB8BITS 64 -typedef signed long long sb8; +typedef int64_t sb8; #define SB8MAXVAL 0x7fffffffffffffffLL -typedef unsigned long int ub4; /* unsigned 4-byte quantities */ +typedef uint32_t ub4; /* unsigned 4-byte quantities */ #define UB4MAXVAL 0xffffffff -typedef signed long int sb4; +typedef int32_t sb4; #define UB4BITS 32 #define SB4MAXVAL 0x7fffffff -typedef unsigned short int ub2; +typedef uint16_t ub2; #define UB2MAXVAL 0xffff #define UB2BITS 16 -typedef signed short int sb2; +typedef int16_t sb2; #define SB2MAXVAL 0x7fff -typedef unsigned char ub1; +typedef uint8_t ub1; #define UB1MAXVAL 0xff #define UB1BITS 8 -typedef signed char sb1; /* signed 1-byte quantities */ +typedef int8_t sb1; /* signed 1-byte quantities */ #define SB1MAXVAL 0x7f -typedef int word; /* fastest type available */ +typedef int word; /* fastest type available */ #define bis(target,mask) ((target) |= (mask)) #define bic(target,mask) ((target) &= ~(mask))