News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Multi thread rdrand test piece

Started by hutch--, June 12, 2019, 05:17:56 AM

Previous topic - Next topic

hutch--

That is pretty much what I had in mind, rdrand for hardware that supports it, an alternative that is at least probably as good for older hardware and for hardware that supports rdrand , a combination of the two. The combination is slower but I can't see a method of reproducing a random pad made this way which is the target for a random pad.

hutch--

This the first test piece for a rdrand free pad generator. The surprising thing is it is far faster than rdrand. It uses the irand algo in the library and the ENT analysis is at least as good as the rdrand but is much faster. As this test piece is a simple single pass of one seed value, it is not secure in terms of brute forcing but with QWORD seed range, it will at least make them work for it.  :tongue:

To make it secure it needs to be multi seeded and multi passed but its fast enough to do that.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .data?
      seed dq ?
    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    USING r12,r13
    LOCAL bcnt  :QWORD
    LOCAL block :QWORD
    LOCAL pMem  :QWORD
    LOCAL bwrt  :QWORD
    LOCAL rqst  :QWORD
    LOCAL tcnt  :QWORD

    SaveRegs

    mov rax, 1024*1024*1024             ; requested pad size
    mov rqst, rax

    mov rax, rqst
    add rax, 1024*64                    ; add 64k
    mov bcnt, rax                       ; store it in bcnt
    mov block, rax                      ; store it in block

    rcall intdiv,block, 8               ; divide block by 8
    mov block, rax

    mov pMem, alloc(bcnt)               ; allocate the byte count

    call reseed                         ; get a seed for the random algo
    rcall seed_irand,rax

    conout "Creating Pad",lf

    mov tcnt, rv(GetTickCount)

    mov r12, block                      ; block is loop counter
    mov r13, pMem                       ; memory address
  @@:
    rcall irand                         ; call random algo
    mov QWORD PTR [r13], rax
    add r13, 8
    sub r12, 1
    jnz @B

    rcall GetTickCount
    sub rax, tcnt

    conout "Timing = ",str$(rax)," ms",lf
    conout "Saving File",lf

    mov bwrt, savefile("random.pad",pMem,rqst)
    mfree pMem

    conout "Bytes written to disk = ",str$(bwrt),lf,lf
    conout "Wait for ENT to complete analysis",lf

    exec "ent random.pad"

    waitkey
    RestoreRegs
    .exit

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

NOSTACKFRAME

reseed proc

    mov rax, 100        ; out of range number
    cpuid               ; set all regs to 0
    rdtsc
    pause
    bswap rax
    mov r11, rax

    mov rcx, 10         ; loop count
  @@:
    rdtsc               ; date time counter
    pause               ; spinlock pause
    bswap rax           ; reverse byte order
    rol rax, 7          ; rotate left by prime
    xor r11, rax        ; xor rax to r11
    rol r11, 5          ; rotate left by prime
    sub rcx, 1          ; decrement counter

    jnz @B
    mov rax, r11
    ret

reseed endp

STACKFRAME

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end

aw27

We can also use (presumably) true random values from random.org to seed our pseudo random number generator.
Explanation page:
https://www.random.org/clients/http/

This is the C code to access the site and retrieve values. Although it is very easy to convert to Masm I will not do it at this time:


#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <Windows.h>
#include <wininet.h>

#define COUNTVALUES 10
#define MINVAL 0
#define MAXVAL 65535

int main()
{
HINTERNET   hInternet, hConnect, hHttpRequest;
char  szData[1024] = { 0 };
int  intArray[COUNTVALUES] = { 0 };
char* next;
char* curr;
char queryStr[1024] = { 0 };
int i;

sprintf(queryStr, "/integers/?num=%d&min=%d&max=%d&col=1&base=10&format=plain&rnd=new", COUNTVALUES, MINVAL, MAXVAL);

hInternet = InternetOpen("Random.org test", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternet != NULL)
{
hConnect = InternetConnect(hInternet, "www.random.org", INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (hConnect != NULL)
{
if ((hHttpRequest = HttpOpenRequest(hConnect, "GET", queryStr, 0, 0, 0, INTERNET_FLAG_SECURE, 0)))
{
BOOL isSend = HttpSendRequest(hHttpRequest, NULL, 0, NULL, 0);
if (isSend)
{
for (;;)
{
DWORD dwByteRead;
BOOL isRead = InternetReadFile(hHttpRequest, szData, sizeof(szData) - 1, &dwByteRead);

if (isRead == FALSE || dwByteRead == 0)
break;

szData[dwByteRead] = 0;
}
}
}
InternetCloseHandle(hHttpRequest);
}
InternetCloseHandle(hConnect);
}
InternetCloseHandle(hInternet);

//printf("%s\n", szData);

printf("*** %d TRUE RANDOM integer values from RANDOM.ORG in the range %d - %d ***\n\n", COUNTVALUES, MINVAL, MAXVAL);

curr = szData;

for(i=0;i< COUNTVALUES;i++)
{
intArray[i] = atoi(curr);
printf("%d\n", intArray[i]);
next = strchr(curr, '\n');
if (next == NULL)
break;
curr = next + 1;
}
_getch();
return 0;
}




I attach an exe built with the above code.

*** 10 TRUE RANDOM integer values from RANDOM.ORG in the range 0 - 65535 ***

38712
30412
42693
39657
60054
63719
61011
3045
27759
50838