Jenkins JSF PRNG

60 views
Skip to first unread message

David Szafranski

unread,
Dec 13, 2024, 3:19:14 PM12/13/24
to xblite
I came across this pseudo random number generator, Jenkins JSF, or Jenkins small fast prng, and attempted to translate the C to XBLite. But I have not had any success in getting it to work. I have my attempt attached. 

Maybe someone else can figure out what is needed to make this work. 
typedef uint32_t u4; typedef struct ranctx { u4 a; u4 b; u4 c; u4 d; } ranctx; #define rot32(x,k) (((x)<<(k))|((x)>>(32-(k)))) u4 ranval( ranctx *x ) { u4 e = x->a - rot32(x->b, 27); x->a = x->b ^ rot32(x->c, 17); x->b = x->c + x->d; x->c = x->d + e; x->d = e + x->a; return x->d; } void raninit( ranctx *x, u4 seed ) { u4 i; x->a = 0xf1ea5eed, x->b = x->c = x->d = seed; for (i=0; i<20; ++i) { (void)ranval(x); } }

The C code for the 32-bit variant is also included in my program file. If we can get this figured out, there is also a 64-bit variant as well. Although, after looking at the code for the 64-bit prng, it uses a integer type of uint64_t which is an unsigned 8 byte type. Our GIANT type is signed 8 bytes, so it may be a problem doing the 64-bit one.

thanks
D.

Here is the 64-bit C for JSF:

typedef uint64_t u8; typedef struct ranctx { u8 a; u8 b; u8 c; u8 d; } ranctx; #define rot64(x,k) (((x)<<(k))|((x)>>(64-(k)))) u8 ranval( ranctx *x ) { u8 e = x->a - rot64(x->b, 7); x->a = x->b ^ rot64(x->c, 13); x->b = x->c + rot64(x->d, 37); x->c = x->d + e; x->d = e + x->a; return x->d; } void raninit( ranctx *x, u8 seed ) { u8 i; x->a = 0xf1ea5eed, x->b = x->c = x->d = seed; for (i=0; i<20; ++i) { (void)ranval(x); } }
Jenkins_JSK_PRNG.x

Garquint

unread,
Dec 13, 2024, 6:39:37 PM12/13/24
to xblite
Maybe using an XLONG instead of a ULONG may
Work. Also in the xlibs folder in xblite there is u64.x
file for the 64 bit version.


Garquint 

David Szafranski

unread,
Dec 13, 2024, 6:41:35 PM12/13/24
to xblite
Thanks, I completely forgot about the u64 library. Exactly what is needed to do this. 

gentsky

unread,
Dec 14, 2024, 11:19:56 AM12/14/24
to xblite
Hi D.

Since you are passing ranctx to a function and then updating the components within the function don't you need to pass by reference?

Alan

gentsky

unread,
Dec 14, 2024, 6:52:42 PM12/14/24
to xblite
Hi D.

Looking more carefully, I see you are passing by reference - sorry I was rushing

When I ran it, I got no output at all. You need to insert "CONSOLE" after the VERSION and then you do get output.

It then runs OK but finishes without ever getting to the  a$ = INLINE$ ("Press Enter to quit >")

The problem seems to be with the FOR / NEXT PRINT loop within raninit() as if you comment this out it runs to a proper conclusion

If you comment out the ranval (@x) line it again completes OK but prints the same values each time.

This seems to narrow it down to the repeated calls to ranval(@x)

That's all I have time for at the moment but this may help you pin the problem down. I will investigate more tomorrow if you haven't cracked it by then

David Szafranski

unread,
Dec 14, 2024, 9:09:00 PM12/14/24
to xblite
I found that after the second call of ranval(), the value of e  goes negative, leading to an exception. 
This leads me to believe that there is an issue with the rot32() function. Not sure how to proceed
since this it what the C code shows.

D. 

gentsky

unread,
Dec 15, 2024, 3:42:46 AM12/15/24
to xblite
Hi D.

Since e is defined as u4 it can't really be negative even if bit 31 is set. I would try writing ranval() in ASM  with e as a register variable. I suspect Xblite is checking for an exception when it shouldn't.

Reply all
Reply to author
Forward
0 new messages