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.