So, I had a perfectly working PRNG in Java like this:
public class WLPRNG {
long seed;
public WLPRNG(long seed) { this.seed = seed; }
public int nextInt() {
long result = seed + 0x123defca;
result = Long.rotateLeft(result, 19);
result += 0xbead6789;
result *= 0x1234567c;
int temp = (int)result;
result ^= 0x5ecdab73;
result = Long.rotateLeft(result, 48);
if (temp % 4 == 0) result *= 0x87650027;
result += 13;
seed = result;
return (int)result;
}
public byte nextByte() {
return (byte)nextInt();
}
}
And I thought I’d test out the Assembler version like this:
; random number generator to be used in crypto transmission
; of sensitive data over the internet
; WLGfx 2017-Nov-19
section .text
global main
extern printf
srand: mov [seed],rax ; set random seed
ret
arand: mov rax,[seed] ; get seed
mov rbx,qword 0x023defca321acfed
add rax,rbx ; add 64 bit value
rol rax,19 ; rotate bits
mov rbx,qword 0xbead6789
add rax,rbx ; another add
imul rax,qword 0x1234567c ; a multiple this time
mov rbx,rax ; copy into rbx
xor rax,qword 0x5ecdab73 ; flip some bits
rol rax,48 ; rotate bits again
mov rcx,rax ; copy to rcx
and rax,0x3 ; mask and test with 0
jnz .notz ; 25% chance of other ops
mov rax,rbx
add rcx,rax
mov rbx,qword 0x87650027
imul rax,rbx
jmp .cont
.notz mov rax,rcx ; back into rax
.cont mov [seed],rax ; store into seed
and rax,0xff ; return byte value only
ret
main: mov rax,9 ; set seed
call srand
mov dword[lc],10 ; set loop counter
.loop call arand ; get random byte
push rbp ; stack frame
mov rsi,rax ; random number
mov rdi,pf_msg ; format string
xor rax,rax ; 0
call printf ; call printf
pop rbp ; stack frame
sub dword[lc],1 ; dec loop counter
jnz .loop
ret
section .data
seed dq 0,0,0,0 ; random seed value 64 bit
lc dd 10 ; loop counter
pf_msg db "Number: 0x%02x",10,0
Using the build script:
#!/bin/bash
nasm -f elf64 random.asm
gcc -o random random.o
Gives a sample output of:
~/dev/asm/tests $ ./buildrand.sh
~/dev/asm/tests $ ./random
Number: 0xe0
Number: 0x5b
Number: 0xca
Number: 0x7c
Number: 0xfc
Number: 0x2d
Number: 0x79
Number: 0xa5
Number: 0x62
Number: 0x7f
All I need to do now is to be able to link directly to C and C++ code. I’m currently reading up on threading in assembler, but it looks like the standard pthreads are just the same really.
There’s lot’s of potential for using assembler.