Кости
Все пять игр здесь держатся на одних и тех же двух костях. Эта страница показывает, откуда берутся их числа, почему их никто не может выбрать — мы в первую очередь — и как ты проверишь это сам.
Зачем нужна эта страница
31–45 % всех жалоб в отзывах на крупные приложения для нард касаются костей — больше, чем любой другой темы.
Это подозрение — не мнение меньшинства. Оно стоит в отзывах на каждом языке, на котором говорит этот сайт: кости подкручены, сопернику выпадает ровно то, что ему нужно, после покупки следующую партию проигрываешь. Каждый, кто играл онлайн, думал эту фразу — и чаще всего не находилось никого, кто отнёсся бы к ней всерьёз.
Обычный ответ — сертификат: аудитор подтверждает, что генератор случайных чисел в порядке. Это значит «верь аудитору» — ровно там, где ты никому верить не хочешь. Поэтому здесь нет печати, а есть расчёт, который ты можешь повторить сам, для каждой законченной партии.
Почему ни один бросок не выбирается задним числом
Каждая партия фиксирует свои броски до того, как они выпадут. В начале сервер публикует контрольную сумму, а в конце — число, из которого вычислены все броски; если одно не сходится с другим, это доказуемо.
-
Перед партией: запечатанный конверт
Сервер берёт стартовое значение из 32 случайных байтов и публикует только его отпечаток — контрольную сумму, из которой стартовое значение не восстановить. С этой минуты оно закреплено; подменить его никто не может так, чтобы отпечаток сошёлся.
-
Оба игрока добавляют своё
Каждый из вас вносит собственный идентификатор, и он входит в каждый бросок. Именно этот шаг опускают обещания «у нас есть контрольная сумма» — а без него всё остальное было бы театром: сервер, который выбирает и ваши значения, может перебирать стартовые значения, пока броски ему не понравятся, и лишь тогда опубликовать отпечаток.
-
Якорь извне
К этому добавляется число из drand — публичного источника случайности, который совместно производят несколько независимых операторов. Названный раунд — тот, которого в момент запечатывания ещё не существовало. Так закрывается последняя брешь: даже если бы сервер и оба игрока были в сговоре, выбрать броски заранее они не смогли бы.
-
Партия идёт
Каждый бросок вычисляется из этих частей по порядковому номеру броска. Ничто не решается в тот миг, когда ты нажимаешь на стакан, — всё было определено до начала партии.
-
После партии: конверт вскрывают
Сервер публикует стартовое значение. Теперь проверяется и то и другое: сходится ли оно с прежним отпечатком и получаются ли из него ровно те броски, что выпали? Если хоть одно не сходится — это уже не подозрение, а доказательство, и притом такое, которое каждый может провести, не спрашивая нас.
1 Отпечаток 2·3 Привязано к 5 Начальное значение
Расчёт, выложенный открыто
Вот он целиком. Второй, тайной части нет — здесь всё, что нужно броску.
Каждый бросок — это HMAC-SHA256(начальное значение, привязка ‖ номер). Байты от 252 и выше отбрасываются, чтобы все шесть граней оставались равновероятными; остальное — остаток от деления на шесть плюс единица.
Стартовое значение — ключ, привязка — сообщение: номер матча, номер партии, идентификаторы обоих игроков и якорь, причём перед каждой частью стоит её длина. Длины — не украшение. Без них идентификаторы «ab» и «c» дали бы то же сообщение, что «a» и «bc», и игрок мог бы отобразить две разные пары на один и тот же поток костей.
Почему четыре значения из 256 выбрасываются
256 не делится на шесть. Если просто взять остаток, грани от 1 до 4 выпадают в 43 случаях из 256, а 5 и 6 — лишь в 42; это перевес около двух с половиной процентов, легко доказуемый на ста тысячах бросков. Именно это и был бы тот скандал, который эта страница призвана предотвратить. Поэтому четыре старших значения байта отбрасываются и берётся новое, и все шесть граней остаются равновероятными.
используются, поровну на шесть граней отбрасываются, берётся новый байт
Три способа проверить это самому
Всё, что нужно для проверки, открыто — и ни один из трёх путей не идёт через нас.
-
Пересчитано в твоём браузере
У каждой законченной партии есть своя страница под «Проверить кости»: отпечаток, привязка, стартовое значение и все броски. Твоё устройство пересчитывает там всё криптофункцией твоего же браузера — и вывод исходит от твоей машины, а не от нашей.
-
nard.gg — проверка костей
Этот файл пересчитывает кости партии из опубликованных значений. В нём нет ничего нашего, кроме самого расчёта: ничего не подгружается, никуда не соединяется, ничего не считается.
Скачать программу проверки — один файл, без сети, без нас. Сохрани и запускай против любой опубликованной записи когда угодно.
-
Вручную или своим инструментом
Формула выше — это полная спецификация, а HMAC-SHA256 есть в любом языке программирования. Кто хочет, напишет проверяющую программу в двадцать строк и не потребует от нас ничего, кроме опубликованных чисел. Именно за этим они там и стоят.
Чего мы не обещаем
С момента запечатывания сервер знает броски текущей партии наперёд. Убрать это можно было бы, только если бы обе стороны фиксировали значение перед каждым отдельным броском и раскрывали его после, — а это лишний обмен на каждом ходу и приглашение просто отказаться раскрывать. Мы так не делаем. И пишем об этом здесь, а не умалчиваем.
Зато верно другое: для каждой партии берётся собственное стартовое значение, независимое от всех прочих — из одного ничего не следует о следующем. И доказательство лежит открыто для каждой законченной партии, не по запросу, а само собой.
Тридцать шесть бросков
А почему всё равно кажется, будто кости против тебя? Потому что случайность в малых количествах выглядит неровно. Две кости падают тридцатью шестью способами, и тот, кому нужен определённый, часто ждёт его долго. Обе таблицы здесь это показывают: первая — сколько бросков вообще достают до данной дистанции, вторая — насколько неровно выглядит настоящая случайность в малых числах.
Две кости выпадают тридцатью шестью равновероятными способами. Выбери расстояние — и таблица покажет, какие из бросков проводят шашку так далеко по свободному пути, без заслонов посередине.
Ничего не выбрано — таблица показывает все тридцать шесть бросков.
21 разных бросков, 6 из них дубли. Считают всё равно в тридцать шестых: каждый дубль выпадает один раз, любой другой бросок — дважды.
Бросьте сами
Эта таблица бросает в твоём браузере, его собственной случайностью. После тридцати шести бросков половина клеток остаётся пустой — это не сбой, так выглядит случайность.
Всего бросков 0
Дубль
Если на обеих костях одно и то же число, оно играется четыре раза, а не два. Дубль выпадает в шести бросках из тридцати шести — то есть в каждом шестом ходе.
Поэтому дубль уводит дальше любого другого броска: 6–6 переносит на двадцать четыре пункта.
Первый бросок
В начале каждый бросает одну кость; начинает тот, у кого больше, и играет ровно эти два числа. При равенстве бросают заново. Поэтому первый ход партии никогда не бывает дублем — остаётся 30 бросков из тридцати шести.