> For the complete documentation index, see [llms.txt](https://docs.cardz.game/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cardz.game/how-it-works/rng-and-verifiable-fairness.md).

# RNG and Verifiable Fairness

This page covers the RNG calculation for pack opening, followed by a practical verification guide for Upgrade and Enhancement.

**Checking an Upgrade?** Jump to [Upgrade and Enhancement: step-by-step verification](#upgrade-and-enhancement-step-by-step-verification). On JACKZ.AI choose **Success / fail: Card Upgrade, Enhancement**.

## Pack opening: RNG calculation

### 1. Introduction

The Cardz.game settlement engine utilizes a deterministic random number generation (RNG) algorithm based on the SHA-256 cryptographic hash function. This ensures that the outcome of any probabilistic event (Pack Opening) is derived solely from pre-committed inputs, rendering the result immutable and verifiable.

This document defines the mathematical operations used to transform raw entropy into asset selection.

### 2. Input Parameters

The generator requires three distinct inputs (seeds) to maximize entropy and ensure user participation.

| **Parameter**    | **Type**      | **Bit Length** | **Description**                                                                                 |
| ---------------- | ------------- | -------------- | ----------------------------------------------------------------------------------------------- |
| Server Seed (Ss) | String (Hex)  | 256-bit        | Cryptographically secure random bytes generated by the platform.                                |
| Client Seed (Sc) | String        | Variable       | User-provided entropy. Defaults to a browser-generated 32-char string, but can be user-defined. |
| Nonce (N)        | Integer (u64) | 64-bit         | A sequential monotonic counter associated with the seed pair. Increments (N+1) per execution.   |

### 3. Hashing Procedure

The raw entropy is generated via concatenation and hashing.

#### 3.1. Concatenation

The inputs are concatenated as a strict UTF-8 string:

Plaintext

{% code collapsedlinecount="10" %}

```
Raw = ServerSeed + ClientSeed + Nonce
```

{% endcode %}

#### 3.2. Digest Generation

The concatenated string is processed through the SHA-256 algorithm to produce a hexadecimal digest (H):

Plaintext

{% code collapsedlinecount="10" %}

```
H = SHA256(Raw)
```

{% endcode %}

This results in a 64-character hexadecimal string representing 256 bits of entropy.

> *Example H:* `b56a4208e9104033...`

### 4. Outcome Determination (Normalization)

To convert the hexadecimal hash (H) into a usable Game Result, we utilize a Uniform Float Conversion method. This maps the hash to a floating-point number between 0 and 1.

#### 4.1. Slicing & Integer Conversion

We take the first 8 characters (32 bits) of the generated hash (H). This substring is converted from base-16 (hex) to base-10 (decimal).

Plaintext

{% code collapsedlinecount="10" %}

```
I = HexToDecimal(H.substring(0, 8))
```

{% endcode %}

* Theoretical Range of I: `0` to `4,294,967,295` (16^8 - 1)

#### 4.2. Float Normalization

The integer `I` is divided by the maximum possible 32-bit value to produce a normalized float (U).

Plaintext

{% code collapsedlinecount="10" %}

```
U = I / 4,294,967,296
```

{% endcode %}

This yields a uniformly distributed float where `0 <= U < 1`.

### 5. Asset Selection (CDF Mapping)

The float `U` is compared against the Cumulative Distribution Function (CDF) of the pack's drop table.

Example Drop Table:

* Asset A (Common): 50% (0.50)
* Asset B (Rare): 30% (0.30)
* Asset C (SSR): 20% (0.20)

Mapping Logic:

The system iterates through the cumulative weights. If `U` is less than the cumulative threshold, that asset is selected.

1. Threshold 1: `0.50` (Asset A) -> Is `U < 0.50`?
2. Threshold 2: `0.80` (0.50 + 0.30) -> Is `U < 0.80`?
3. Threshold 3: `1.00` (0.80 + 0.20) -> Is `U < 1.00`?

*Note: For 5-card packs, this process is repeated 5 times. The Nonce is usually incremented to generate 5 distinct numbers from a single seed.*

### 6. Reference Implementation (TypeScript)

The following code snippet replicates the production logic for verification purposes.

TypeScript

{% code collapsedlinecount="10" %}

```
import { createHash } from 'crypto';

/**
 * Generates a normalized float from seeds.
 * @param serverSeed - The unhashed server seed.
 * @param clientSeed - The user's client seed.
 * @param nonce - The current transaction count.
 * @returns A float between 0 and 1.
 */
function generateResult(serverSeed: string, clientSeed: string, nonce: number): number {
  // 1. Construct the Raw String
  const rawString = `${serverSeed}${clientSeed}${nonce}`;

  // 2. Generate SHA-256 Hash (Hex Output)
  const hash = createHash('sha256').update(rawString).digest('hex');

  // 3. Slice first 8 characters (32 bits)
  const hexSlice = hash.substring(0, 8);

  // 4. Convert to Decimal Integer
  const decimalValue = parseInt(hexSlice, 16);

  // 5. Normalize to Float [0, 1)
  // Divisor is 16^8 (4,294,967,296)
  const result = decimalValue / 4294967296;

  return result;
}

// Example Usage
const outcome = generateResult("a1b2c3d4...", "user-seed-123", 1);
console.log(`RNG Result: ${outcome}`); // e.g., 0.4812...
```

{% endcode %}

### 7. Edge Case Handling

#### 7.1. Precision Constraints

The system operates using standard IEEE 754 double-precision floating-point arithmetic. The divisor `2^32` ensures that the resolution of the outcome is sufficient for drop rates as low as `0.000000023%`.

#### 7.2. Modulo Bias Prevention

We strictly avoid using modulo (`%`) operations on the raw hash to determine outcomes, as modulo can introduce slight statistical biases when the keyspace is not perfectly divisible by the number of outcomes. The Float Normalization method (`I / 2^32`) is statistically neutral and unbiased.

## Upgrade and Enhancement: step-by-step verification

Upgrade uses HMAC-SHA256. Use the Upgrade instructions below when checking an Upgrade or Enhancement; the pack-opening concatenation formula above applies to a different workflow.

Check your CARDZ.GAME Upgrade or Enhancement result yourself, using the record in your account and the verifier at JACKZ.AI. This guide shows every field to copy and what a successful check means. No coding is needed.

**This guide covers Upgrade and Enhancement only.** On JACKZ.AI, always choose **Success / fail: Card Upgrade, Enhancement**.

### Why the result can be checked

RNG means random number generator. For an Upgrade, it produces a number called the **Roll**. The result is successful when that number falls inside the round's **Winning range**.

The fairness check connects three things:

1. **Before the round: save the fingerprint.** CARDZ.GAME shows a Server seed hash. This is a digital fingerprint of a hidden Server seed. Save the full hash before the round you want to check.
2. **After the seed is revealed: check the fingerprint.** The verifier hashes the revealed Server seed. It must reproduce the hash you saved. Changing the seed would produce a different fingerprint with overwhelming probability.
3. **Recalculate: compare the result.** The Server seed, Client seed and Nonce feed the same published formula. The same inputs give the same Roll. Compare that Roll with the recorded Roll and the round's Winning range.

Together, these checks let you detect a changed seed or a result that does not follow the supplied inputs and rule. Saving the hash **before** the round is what connects the later calculation to the earlier commitment.

### Why save the hash before an Upgrade, and what if I did not?

A hash is the Server seed's digital fingerprint. Saving it lets you check that the seed revealed later matches the commitment made before your Upgrade. You keep an original reference that you can compare yourself.

Before the Upgrade, save hash H. After the seed is revealed, obtain Server seed S. Calculate SHA-256(S) and compare it with H. A match lets you check that the revealed seed fulfils that recorded pre-round commitment.

A hash does not prove timing by itself. A seed and hash obtained afterwards can be checked for consistency. Confirming that the hash was published before the Upgrade still requires a pre-round record.

Even without saving the hash yourself, you can use the revealed Server seed and that round's data to recalculate the Roll and check success or failure against its Winning range.

Another pre-round hash record with a verifiable source and timing can also be used to check the seed commitment. A screenshot is one way to keep a record. What matters is that the record existed before the Upgrade and corresponds to the seed used for that round.

Without any verifiable pre-round record, you can still check whether the result calculation matches, but cannot retrospectively establish the commitment's timing. Not saving a record does not itself show that the platform changed the seed.

**Have a completed Upgrade already?** Start at Step 3. You can recalculate it now. A hash copied only after the round cannot, by itself, prove when that hash was first published.

**Keep two tabs open:** your [CARDZ.GAME Upgrade page](https://app.cardz.game/asia/upgrade) and [JACKZ.AI in English](https://jackz.ai/en/).

### Step 1 Open Upgrade and find the controls

Open [app.cardz.game/asia/upgrade](https://app.cardz.game/asia/upgrade) and sign in to your CARDZ.GAME account. Look at the small icons beside the **Upgrader** heading.

![The Upgrade page and its controls](https://39136273-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLfdpdXWAx9AmtkTQh6G2%2Fuploads%2FH27dNoPQ4CXfMjHDZoWw%2F01-upgrader-controls.jpg?alt=media)

**Clock icon = Upgrade history. Shield icon = Fairness.** Hover over an icon on a computer to see its name. The speaker controls sound; the question mark opens the gameplay instructions.

![Close view of the history and fairness icons](https://39136273-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLfdpdXWAx9AmtkTQh6G2%2Fuploads%2FhmwCLmgRL41ozLMXxOXL%2F01-toolbar.jpg?alt=media)

### Step 2 Save the hash before a future round

Click the **shield icon / Fairness**. Beside **Server seed hash**, click **Copy**. Paste the full value into a note and save a screenshot. Also note your **Client seed**.

![The Fairness panel with Server seed hash and Client seed](https://39136273-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLfdpdXWAx9AmtkTQh6G2%2Fuploads%2FmlPOd60ahK4KEhrnXBBv%2F02-fairness.jpg?alt=media)

The hash and the Server seed are different values. The hash is visible first; the Server seed is revealed later. If you change or rotate seeds, save the new current hash before the next round. Verification itself does not require a new Upgrade.

### Step 3 Open one completed Upgrade

Close Fairness. Click the **clock icon / Upgrade history**. Find the round you want to check, then click its row to open **Upgrade details**. A failed Upgrade can be verified too.

Scroll to **Provable Fairness**. On a smaller screen, expand that section if it is closed. Keep all copied values from this one round together.

![Upgrade details showing the winning range and fairness values](https://39136273-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLfdpdXWAx9AmtkTQh6G2%2Fuploads%2Fme6gRQl5dj8tKPiaymEm%2F04-verify-link.jpg?alt=media)

Use the **Copy** buttons for **Server seed (hash)**, **Server seed**, **Client seed** and **Nonce**. Select and copy **Winning range** and **Result roll** if they have no Copy button. Note whether this round says **Success** or **Failed**.

**If Server seed is hidden:** finish any pending round using those seeds. Use **Rotate to verify** if offered in the details, or **Fairness → Rotate**, then reopen the old round. Read any confirmation before continuing. Rotation changes the seeds for future rounds; it does not rerun this Upgrade. A round still using the old seeds may delay disclosure.

Click **Verify results ↗**, or open [jackz.ai/en/](https://jackz.ai/en/) yourself. If the verifier opens in another language, choose **EN**. Keep the CARDZ.GAME record open beside it.

### Step 4 Fill in the Upgrade inputs

On JACKZ.AI, click **Start Verifying** or **Self Verify**. Open **Enter Seeds** if it is collapsed. If values are already filled in, compare them with your record before proceeding.

1. **Server Seed:** paste the revealed value labelled **Server seed** in CARDZ.GAME. Do not paste **Server seed (hash)** here.
2. **Client Seed:** paste the Client seed from the same round. Keep capitals, spaces and symbols exactly as recorded.
3. **Nonce:** paste that round's Nonce. Use the recorded number, not the number of rounds you remember playing.
4. **Draw type:** select **Success / fail: Card Upgrade, Enhancement**.
5. **Winning range or Threshold:** paste the entire Winning range, including both ends. For example: **0 – 2,611,340,114**.

![The correct Upgrade and Enhancement draw type and its input fields](https://39136273-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLfdpdXWAx9AmtkTQh6G2%2Fuploads%2FFJE3Cy5uxZRf0ASg6hL8%2F05-upgrade-inputs-corrected.jpg?alt=media)

**Winning range and Result roll are different.** The range is the success zone. The Roll is the number that landed. Put the range in this box; the Roll goes in the next step.

### Step 5 Add the values that must match

Open **Optional: compare with the platform’s record**. Complete this section to check the saved hash and compare against the recorded outcome.

![The optional comparison fields and Verify button](https://39136273-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLfdpdXWAx9AmtkTQh6G2%2Fuploads%2F4Xs32ZJ5zq40h9UeeVB6%2F06-compare-record-corrected.jpg?alt=media)

* **Server Seed Hash:** paste the full hash saved before this round. Check that it also matches **Server seed (hash)** in the round details.
* **Draw:** enter **0** for this Upgrade. Draw is a separate field from Nonce.
* **Roll:** paste **Result roll**. In the example, enter **18489831**.
* **Result:** enter **1** if CARDZ.GAME says **Success**, or **0** if it says **Failed**. Use these values, not a percentage.
* **Input card names** and **Target card name:** optional labels. They can be left blank for the RNG check.

Before clicking Verify, make one last check: every value belongs to the **same completed round**, and Draw type says **Card Upgrade, Enhancement**.

### Step 6 Click Verify and read the result

Click **Verify**. The calculation runs in your browser. For the complete example shown here, the page displays **Verified**.

![Verified result with matching hash and record checks](https://39136273-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLfdpdXWAx9AmtkTQh6G2%2Fuploads%2FOWtJueYLuWK1qwoYBkSL%2F07-verified.jpg?alt=media)

Read all three checks below the result:

* **Server Seed Hash: Hash matches:** the revealed seed produces the hash you entered.
* **Roll: Recalculated:** the verifier has calculated the Roll from the seeds and Nonce.
* **Record: Matches the record:** the comparison values agree with the calculation.

**Verified and Success mean different things.** Verified describes the check. Success describes the Upgrade outcome. A round that failed can still be correctly verified.

Click **View Proof** to inspect the calculation. Save a screenshot of the result and keep the round details with it.

#### Understand the example

The Winning range is **0 to 2,611,340,114**, including both ends. The calculated Roll is **18,489,831**, which is inside that range, so the outcome is **Success**. The matching Threshold is **2,611,340,115**, one above the range's upper end. JACKZ.AI accepts the full range, so you do not need to calculate the Threshold yourself.

### What the check proves

With the correct pre-round hash and complete record, the check confirms that the revealed seed matches that commitment, and that the recorded Roll and success or failure match the published calculation for the supplied inputs.

JACKZ.AI is an external verification tool you can open yourself. Its calculation can be repeated outside the CARDZ.GAME interface. The page's **Verified** result is a check of the data entered; it is not a certification of the entire platform.

The **Winning range** determines the success probability. This manual workflow checks the outcome against the range you enter. It does not assess how CARDZ.GAME set that probability, card values or prices. It also does not check delivery, account balances or every other round.

Keep the displayed chance and round record as well as the hash. A fair random process can produce repeated failures; a particular success rate does not promise a fixed number of successes in a small run.

#### The calculation in plain terms

The Upgrade verifier uses **HMAC-SHA256** with the Server seed text as the key and **ClientSeed:Nonce:0** as the message. It reads the first four bytes as one unsigned number: the Roll, from **0** to **4,294,967,295**.

The Upgrade succeeds when **Roll < Threshold**. Equivalently, a Winning range shown as **0 – U** includes Rolls from zero through U. A Roll equal to the Threshold fails.

The seed commitment uses a separate calculation: **SHA-256 of the Server seed text**. That output must equal the saved Server seed hash. You do not have to run either formula by hand.

**PTS and USDC:** copy the proof fields directly. Do not convert card values, balances or currencies to fill these boxes. This guide uses the supplied Asia Upgrade page; other versions can use different screens and currency rules.

### If the page does not say Verified

**Draw calculated:** the inputs were enough to calculate a result, but the comparison is not complete. Fill in the recorded Roll and Result under Optional, and include the saved hash.

**Result matches the record:** the outcome matches, but no pre-round Server Seed Hash was supplied. Add the hash you saved before the round for the commitment check.

**This draw can’t be verified yet:** the revealed Server seed is missing. Return to Step 3 and obtain the old seed after rotation.

**Incomplete data or Can’t verify:** copy the missing values again. Confirm that you selected Card Upgrade, Enhancement, and put Winning range and Result roll in their separate fields.

**Verification failed:** first check for a copying mistake, a value from another round, or a changed character. If the same correct inputs still fail, save screenshots of both pages and contact [CARDZ.GAME support](https://docs.cardz.game/about-cardz.game/contact-us).

![Deliberately incorrect Roll showing Verification failed](https://39136273-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLfdpdXWAx9AmtkTQh6G2%2Fuploads%2FGuiVygmMqQVTsb5sOrXt%2F08-mismatch-example.jpg?alt=media)

**Error demonstration:** only the entered Roll was changed from **18,489,831** to **18,489,832** for this screenshot. The underlying CARDZ.GAME record was unchanged. The verifier detected the mismatch.

#### Links

* [CARDZ.GAME Upgrade](https://app.cardz.game/asia/upgrade)
* [JACKZ.AI verifier in English](https://jackz.ai/en/)
* [JACKZ.AI published algorithm and examples](https://jackz.ai/en/docs.html#algo)
* [CARDZ.GAME support](https://docs.cardz.game/about-cardz.game/contact-us)

Screens and button names checked on 29 October 2026. Example values illustrate one completed Upgrade; use the values from your own round.
