Непредсказуемые кубики: что было не так и что мы изменили
Мы обнаружили, что кубики в онлайн-партиях в принципе можно было вычислить ещё до броска: их зерно строилось из данных, которые видит каждый игрок. Признаков, что кто-то этим воспользовался, мы не нашли. С 1 октября зерно каждого броска берётся из секрета, известного только серверу, и прежний прогноз теперь угадывает лишь один бросок из 36 — чистая случайность.

Простыми словами
Вот что мы нашли. Всё случайное в онлайн-партии — два кубика, вытянутая карточка Шанса, кубик Джекпота — берётся из генератора случайных чисел, а генератору нужна отправная точка — зерно. Наше зерно строилось из двух вещей, которые видит каждый игрок: id игры, который виден в адресной строке, и номера хода, который игра возвращает после каждого действия. Сам генератор — обычный опубликованный код. Сложите это вместе, и тот, кто знал, как это сделать, мог вычислить бросок ещё до того, как бросить кубики, — а в принципе даже выбрать, какой из нескольких следующих бросков ему достанется.
Мы проверили это на настоящих партиях, а не в теории. Из последних 2,000 бросков до исправления 1,985 — 99.3% — оказались ровно такими, какими их предсказывала эта открытая информация.
Кто-нибудь этим воспользовался?
Потом мы искали тех, кто этим пользовался, и не нашли никого. Прямее всего знание броска окупается в ставке на Джекпот. За семь дней до исправления из 2,354 ставок в Джекпоте выиграли 31.4% — против 31.1%, которые предсказывает одна лишь случайность, — и ни один игрок не выделялся своими результатами.
Частые вопросы
Честные ли кубики в opolyx?
Да. По 247,968 броскам со 2 по 6 октября 2026 года каждая грань каждого кубика выпадала с частотой от 16.54% до 16.77% — у идеального кубика это 16.67%, — а дубль выпадал в 16.67% бросков.
Можно ли предсказать кубики в opolyx?
Нет — с 1 октября 2026 года уже нельзя. Зерно каждого броска берётся из секрета, который существует только на сервере, а прежний прогноз теперь совпадает лишь в 2.76% бросков — это те 2.78%, которые дало бы угадывание двух кубиков вслепую.
Воспользовался ли кто-нибудь старой уязвимостью кубиков?
Мы не нашли признаков этого. За семь дней до исправления из 2,354 ставок в Джекпоте выиграли 31.4% — против 31.1%, которые предсказывает одна лишь случайность, — и ни один игрок не выделялся своими результатами.
Где определяется результат броска?
На игровом сервере, в тот момент, когда вы бросаете кубики, — генератором случайных чисел, чьё зерно берётся из секрета, которого нет больше ни у кого. Результат записывается в журнал партии; повторы и статистика читают журнал, а не бросают кубики заново.
Для тех, кому интересны детали
Зерном была метка вида <id игры>:<номер хода>, захешированная FNV-1a и переданная в mulberry32. Так было задумано — это позволяло воспроизвести любую партию по её собственному журналу, — но для воспроизводимости зерну вовсе не нужно было быть открытым. Каждый результат записывается в событие, которое его породило, а повторы партий и статистика читают эти события, вместо того чтобы бросать кубики заново.
// before: anyone who knew the game id and the move number could do this
rng = mulberry32(fnv1a(`${gameId}:${seq}`))
// after: the same label, signed with a key that never leaves the server
rng = mulberry32(uint32(hmacSha256(serverSecret, `${gameId}:${seq}`)))Теперь метка сначала проходит через HMAC-SHA256 с 32-байтовым секретным ключом, который существует только внутри сервера. По умолчанию ключ генерируется заново при каждом запуске сервера. Переживать перезапуск ему незачем, потому что ни один прошлый бросок никогда не пересчитывается, — а секрет, который нигде не записан, не может утечь.
Так подписывается каждый случайный розыгрыш, от которого что-то зависит в партии: кубики, карточка Шанса, кубик Джекпота и выбор того, кто ходит первым.
И кубики честны ровно настолько, насколько и должны быть. По всем броскам со 2 октября — а их 247,968 — каждая грань каждого кубика выпадала с частотой от 16.54% до 16.77% против 16.67% у идеального кубика, а дубль выпадал в 16.67% бросков:
| Грань | Первый кубик | Второй кубик |
|---|---|---|
| Грань 1 | 16.75% | 16.72% |
| Грань 2 | 16.77% | 16.65% |
| Грань 3 | 16.56% | 16.61% |
| Грань 4 | 16.54% | 16.70% |
| Грань 5 | 16.67% | 16.70% |
| Грань 6 | 16.72% | 16.62% |
Исправление проверили на тех же условиях, что и проблему. Прогноз, который раньше совпадал в 99.3% бросков, после исправления прогнали ещё раз на данных за целый день: он совпал в 1,388 случаях из 50,212, то есть в 2.76%, — это те самые 2.78%, которых можно ждать, угадывая два кубика вслепую.
