• XSS.stack #1 – первый литературный журнал от юзеров форума

Шизо-RNG

USA_Straday

Prosraft
Premium
Регистрация
26.05.2024
Сообщения
118
Реакции
92
Гарант сделки
6
В текущей ситуации с форумом хочу снять напряжение с себя и некоторых участников,
предлагаю взглянуть на супер прорывную инновационную технологию генерации
случайных чисел (шутка😁)

В попытках сделать хотя-бы как то похожим не секурность был добавлен _mm_pause и ксор на время исполнения.
Суть концепции в том что мы делаем из кучи потоков inc одной и той же переменной, что по сути
является ситуацией когда инструкции могут смешаться и вместо +8 может произойти +(1-8),
т.е. часть inc потеряется и мы получим то что сложно предугадать.

По сути это ГСЧ на состояниях гонки потоков..)

Что бы сломать такой гсч надо знать как сильно было нагружено каждое ядро процессора,
как kernel распределил потоки которые создала программа и тд и тп..

C++:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdint.h>
#include <stdio.h>
#include <intrin.h>

#define THREADS_PER_BIT 8
#define CNT_PER_THREAD 1000000
#define YIELD_EVERY 0x4000

typedef struct
{
    volatile LONG val;
    char          pad[60];
} align64_t;

static align64_t g_cnt[THREADS_PER_BIT];
static volatile ULONGLONG g_dur[THREADS_PER_BIT];

#pragma optimize("", off)
static DWORD WINAPI Worker(LPVOID pId)
{
    const int id = (int)(INT_PTR)pId;

    LARGE_INTEGER t0, t1;
    QueryPerformanceCounter(&t0);

    for (int i = 0; i < CNT_PER_THREAD; ++i)
    {
        ++g_cnt[id].val;

        if ((i & (YIELD_EVERY - 1)) == 0)//пробуем сделать не таким предсказуемым
            _mm_pause();
    }

    QueryPerformanceCounter(&t1);
    g_dur[id] = (ULONGLONG)(t1.QuadPart - t0.QuadPart);
    return 0;
}
#pragma optimize("", on)

static int get_random_bit(void)
{
    for (int i = 0; i < THREADS_PER_BIT; ++i)
        g_cnt[i].val = g_dur[i] = 0;

    HANDLE th[THREADS_PER_BIT];
    for (int i = 0; i < THREADS_PER_BIT; ++i)
        th[i] = CreateThread(NULL, 0, Worker, (LPVOID)(INT_PTR)i, 0, NULL);

    WaitForMultipleObjects(THREADS_PER_BIT, th, TRUE, INFINITE);

    for (int i = 0; i < THREADS_PER_BIT; ++i)
        CloseHandle(th[i]);

    uint64_t mix = 0;
    for (int i = 0; i < THREADS_PER_BIT; ++i)
        mix ^= (uint64_t)g_cnt[i].val ^ g_dur[i]; //смешиваем все результаты
        //дополнительня ксоря с задержкой которая понадобилась на выполнение

    return (int)(mix & 1);//возвращаем бит, не стал делать байты что бы гсч вышел максимально близким к csprng
    //т.е. на каждый байт 8 итераций по N потоков
}

static uint8_t get_random_byte(void)
{
    uint8_t b = 0;
    for (int bit = 0; bit < 8; ++bit) {
        b |= get_random_bit() << bit;
    }
    return b;
}

int main(void)
{
    printf("SHIZORNG OUTPUT:\n");
    for (;;)
    {
        uint8_t byte = get_random_byte();
        printf("%02X ", byte);
        fflush(stdout);
        Sleep(10);
    }
    return 0;
}
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх