Я какое-то время назад занимался идеей реализации генератора псевдослучайных чисел для задач молекулярной динамики, с хорошим распределением ошибки, чтобы не давал водяных знаков. Искал алгоритмы, которые можно использовать на GPU и допускающие параллельный расчет с нескольких позиций.
Нашел методы MWC64 и MWC128 (Multiply With Carry) основанные на умножении по модулю простых чисел Ризеля. Сейчас в контексте распределенных вычислений мы рассматриваем методы хеширования для быстрого поиска тензоров в распределенных вычислениях и в частности хэши пригодные для параллельного вычисления и проверки на GPU. Для этого мы выбираем хеш функции на модульной арифметике и простых числах.
Методы пост-квантовой криптографии требуют, чтобы хеш функция строилась с использованием модульной арифметики и NTT-Friendly модулей - это простые числа Прота (Proth primes): $q=A2^s+1$. Функция сжатия данных может быть основана на использовании MDS матриц перестановок, которые можно считать с использованием аналога быстрыго фурье преобразования на кольце полиномов (NTT). Использование нескольких простых чисел позволяет реализовать Redundancy RNS непозиционную систему исчисления, основанную на теореме об остатках (CRT). Т.е. нас ко всему прочему интересует расчет нескольких хешей в виде вектора по взаимно простым числам.
Algorithm 1. MWC reduction
*Require*: $p=K\cdot 2^{s}-1$, где $K\lt 2^{w}$, $\beta=2^{s}$
*Require*: input $x=x_1\beta + x_0 \lt p2^{s}$
*Ensure*: output $r \equiv x\beta^{-1} \bmod p$
- $r ← x_1 + x_0\cdot K$
- $r ← r - p \text{ if } r\geqslant p$
Метод основан на операции сдвига на $\beta$ на пол- слова и тождестве: $$ r\beta^{-1}\pmod{p} \equiv (r \bmod \beta)\cdot\lfloor (p+1)/\beta \rfloor + \lfloor r/\beta \rfloor, \text{ где } \beta=2^{w/2} \leqslant 2^s~. $$ $$ (r\bmod \beta) + \lfloor r/\beta \rfloor\cdot \beta \equiv r $$ $$ \beta\cdot a \equiv 1 \pmod{a\beta -1} $$
Algorithm 2. NTT-Friendly reduction
*Require*: $p=K\cdot 2^{s}+1$, где $K\lt 2^{w}$, $\beta=2^{s}$
*Require*: input $x=x_1\beta + x_0 \lt p2^{s}$
*Ensure*: output $r \equiv x\beta^{-1} \bmod p$
- $r ← x_1 - x_0\cdot K$
- $r ← r + p \text{ if } r\lt 0$
Алгоритм основан на тождестве $$ r\beta^{-1}\pmod{p} \equiv \lfloor r/\beta \rfloor - (r \bmod \beta)\cdot\lfloor (p-1)/\beta \rfloor, \text{ где } \beta=2^w \leqslant 2^s~. $$ $$ \beta\cdot a \equiv -1 \pmod{a\beta +1} $$
// Функция MWC хэша без знака uint32_t mwc32_hash(uint32_t h, uint16_t d, uint32_t q, uint32_t a){ h = h + d; h = (uint16_t)h*a + (h>>16); return h; }
// Функция MWC хэша со знаком NTT-friendly int32_t mwc32s_hash(int32_t h, int16_t d, int32_t q, int32_t a){ h = h + d; h = (h>>16) - (uint16_t)h*a; return h; }
// Множество простых чисел Прота 128 шт: 0x7ffe0001, 0x7ff80001, 0x7fea0001, 0x7fe90001, 0x7fd70001, 0x7fd20001, 0x7fcb0001, 0x7fbd0001, 0x7fb90001, 0x7fb40001, 0x7fad0001, 0x7f7b0001, 0x7f4e0001, 0x7f440001, 0x7f420001, 0x7f3c0001, 0x7f330001, 0x7f210001, 0x7f180001, 0x7f000001, 0x7efc0001, 0x7ee20001, 0x7ecf0001, 0x7eba0001, 0x7eb50001, 0x7eb40001, 0x7ea90001, 0x7e780001, 0x7e640001, 0x7e550001, 0x7e520001, 0x7e4b0001, 0x7e370001, 0x7e360001, 0x7e250001, 0x7e100001, 0x7e0f0001, 0x7e040001, 0x7e000001, 0x7dfd0001, 0x7df20001, 0x7de90001, 0x7de60001, 0x7de30001, 0x7dbf0001, 0x7dbe0001, 0x7db90001, 0x7db20001, 0x7d9e0001, 0x7d980001, 0x7d970001, 0x7d8e0001, 0x7d6b0001, 0x7d560001, 0x7d4c0001, 0x7d3a0001, 0x7d290001, 0x7d200001, 0x7d1f0001, 0x7d190001, 0x7d160001, 0x7d110001, 0x7d0d0001, 0x7d010001, 0x7cfc0001, 0x7cf30001, 0x7cea0001, 0x7ce00001, 0x7cda0001, 0x7cd80001, 0x7cd50001, 0x7cd40001, 0x7ccb0001, 0x7cb10001, 0x7cae0001, 0x7c9c0001, 0x7c980001, 0x7c800001, 0x7c5c0001, 0x7c480001, 0x7c450001, 0x7c3b0001, 0x7c390001, 0x7c1d0001, 0x7c1a0001, 0x7c0e0001, 0x7c030001, 0x7c020001, 0x7bff0001, 0x7bf30001, 0x7bd90001, 0x7bd50001, 0x7bd00001, 0x7bcd0001, 0x7bc10001, 0x7bb40001, 0x7baf0001, 0x7b9f0001, 0x7b8b0001, 0x7b850001, 0x7b700001, 0x7b6c0001, 0x7b640001, 0x7b5a0001, 0x7b3c0001, 0x7b3a0001, 0x7b340001, 0x7b310001, 0x7b270001, 0x7b250001, 0x7b070001, 0x7af40001, 0x7ada0001, 0x7a8c0001, 0x7a880001, 0x7a860001, 0x7a7d0001, 0x7a770001, 0x7a650001, 0x7a550001, 0x7a4f0001, 0x7a470001, 0x7a460001, 0x7a380001, 0x7a310001, 0x7a2b0001, 0x7a220001, 0x7a100001,