KAPITAN

Доказуемая честность (provably fair)

Обновлено:

Provably fair — способ доказать, что результат раунда определён до ставки и не подменён. Kapitan заранее публикует SHA-256-отпечаток секретного сида, смешивает этот сид с вашим и раскрывает его, когда раунды сыграны. Любой может пересчитать результат и сверить его с записанным.

Как это устроено

  1. Отпечаток до ставки. Сервер выбирает случайный секретный сид на следующие 100 раундов и сразу публикует его SHA-256-хеш. Подменить сид позже нельзя: изменился бы хеш.
  2. Ваш сид. Во всех играх, кроме Краша, в расчёт входит сид, который выбираете вы, поэтому сервер не может подобрать результат под вас. В Краше раунд общий для всех, и сид у него публичный — crash.
  3. Раскрытие. Когда раунды сида сыграны (или сервер перезапущен), секретный сид публикуется. По нему любой пересчитывает каждый из этих раундов. Пока на сиде идёт игра в Мины, он остаётся закрытым до её конца.

Формула результата

Для каждого раунда считается HMAC-SHA256 с ключом «секретный сид» от строки ваш_сид:номер_раунда. Номер раунда — сквозной счётчик всех игр и игроков. Первые 4 байта результата, делённые на 232, дают число r от 0 до 1.

  • Краш: множитель = (1 − преимущество) / (1 − r), округлённый вниз до сотых, не меньше 1.00x и не больше 1000x. Преимущество — 10%, если в раунде не записано другое.
  • Дайс: число = ⌊r × 100⌋ + 1, от 1 до 100.
  • Плинко: для ряда i берётся байт 4 + i: чётный — шар уходит влево, нечётный — вправо. Лунка — число отскоков вправо, множитель — из таблицы выбранного поля.
  • Лимбо: результат = (1 − преимущество казино) / (1 − r), округлённый вниз до двух знаков, не меньше 1.00x и не больше 1000x: формула Краша с вашим сидом. Преимущество записывается в каждом раунде (сейчас 10%).
  • Мины: клетки пронумерованы от 0 до 24 по строкам сверху слева. Мина k (с нуля) берёт rk из HMAC строки ваш_сид:номер_раунда:k и выбирает клетку ⌊rk × оставшиеся клетки⌋ среди ещё не занятых, по порядку.

Проверьте сами

Этот код для Node.js 18+ проверяет отпечаток и пересчитывает результат. Подставьте раскрытый сид, свой сид и номер раунда — их показывает панель «Доказуемая честность» в разделе «Что мы проверили».

const crypto = require('crypto');

// Раскрытый секретный сид и его опубликованный отпечаток
const serverSeed = '...';
const fingerprint = '...';
// Ваш сид (для Краша — "crash") и номер раунда
const clientSeed = 'crash';
const roundNumber = 123456;

// Отпечаток совпадает с опубликованным до раунда?
console.log(crypto.createHash('sha256').update(serverSeed).digest('hex') === fingerprint);

const hmac = crypto.createHmac('sha256', serverSeed).update(`${clientSeed}:${roundNumber}`).digest();
const r = hmac.readUInt32BE(0) / 2 ** 32;

// Краш
const edge = 0.1;
console.log(Math.min(Math.max(Math.floor(((1 - edge) / (1 - r)) * 100) / 100, 1), 1000));
// Дайс
console.log(Math.floor(r * 100) + 1);
// Плинко: 0 — влево, 1 — вправо; лунка — число единиц
const rows = 16;
console.log([...hmac.subarray(4, 4 + rows)].map(b => b % 2));
// Лимбо: результат считается как точка краша, с преимуществом казино, записанным в раунде
const limboEdge = 0.1;
console.log(Math.min(Math.max(Math.floor(((1 - limboEdge) / (1 - r)) * 100) / 100, 1), 1000));
// Мины: клетки 0–24 по строкам сверху слева; мина k — из HMAC с ":k" в конце
const mines = 3; // Сколько мин было на поле
const left = [...Array(25).keys()];
const board = [];
for (let k = 0; k < mines; k++) {
  const rk = crypto.createHmac('sha256', serverSeed).update(`${clientSeed}:${roundNumber}:${k}`).digest().readUInt32BE(0) / 2 ** 32;
  board.push(left.splice(Math.floor(rk * left.length), 1)[0]);
}
console.log(board.sort((a, b) => a - b));

Проверка в один клик

Под каждой игрой есть панель «Доказуемая честность». Нажмите на свой недавний результат или введите номер раунда: панель сверит раскрытый сид с опубликованным отпечатком прямо в браузере и покажет, совпадает ли пересчёт с записанным результатом. Для полностью независимой проверки используйте код выше.

Играть в Краш · Дайс · Плинко · Мины · Лимбо

Частые вопросы

Почему секретный сид раскрывается не сразу?

Пока сид действует, по нему можно было бы просчитать следующие раунды. Поэтому он раскрывается только после того, как сыграны все его 100 раундов или сервер перезапущен, и не раньше, чем закончится игра в Мины на этом сиде: он выдал бы, где лежат мины.

Может ли казино подобрать сид под мою ставку?

Нет. Отпечаток сида публикуется до ставки, а изменить сид, не изменив отпечаток, невозможно. Во всех играх, кроме Краша, в расчёт к тому же входит ваш сид, который вы меняете когда угодно.

Чем номер раунда отличается от ID раунда?

Номер раунда — сквозной счётчик всех игр и игроков, он входит в формулу. ID — номер записи вашей ставки, по нему раунд находят в панели. Панель показывает оба.