For the complete documentation index, see llms.txt. This page is also available as Markdown.

Provably Fair Mechanism

Merkle Tree with On-chain Merkle Root Commitment

This section explains the provably fair mechanism behind Crypta. The system ensures that every price movement is fair, transparent and cryptographically verifiable.

Crypta generates synthetic price movements from randomness that no single party controls. Each movement is produced by combining two independent sources:

  • Internal secret: Generated inside a secure enclave and cryptographically committed on-chain (Merkle Root) before any price movement is released.

  • External Public Salt: The latest Solana block hash for each ticks — which did not exist when the Merkle Root commitment was made.

Because the internal half is locked in first and the external half is beyond anyone's control, changing every second, neither Crypta nor any other party can steer the outcome and every tick can be independently verified.

Epochs

Randomness is organised into epochs. An epoch is a fixed-length window with a fixed set of assets..

Parameter
Value

Epoch Duration

3,600 seconds (1 hour)

Tick Interval

1,000 ms (1 tick per second)

Assets per Epoch

Variable

At the start of every epoch the enclave generates all randomness for the entire epoch for all assets in advance, commits to it publicly on-chain, and only then begins releasing each assets random hash one tick at a time.qa

Merkle Tree

At the start of each epoch, the enclave generates a random 256 bit secret to derive 3,600 hashes for each asset. Each asset's values are derived from an independent key, so one asset's entropy reveals nothing about another's and nothing carries over between epochs.

Pre-computing the entropy is only half the guarantee. Crypta must also prove it did not change any value afterwards. To do this, the enclave builds a Merkle Tree.

Every secret hash is hashed once to form a leaf:

L(i)=SHA256(Easset,t)L_{(i)} = SHA256(E_{asset,t})

These leaves are then used to construct the Merkle Tree, with each node built bottom-up:

Nparent=SHA256(Nleft∣∣Nright)N_{parent} = SHA256(N_{left}||N_{right})

The single 32-byte value at the top of the tree is the Merkle Root - which get committed on-chain before the start of the epoch. Changing any one of the secret hashes changes the Merkle Root completely.

Merkle Root Commitment

Before the first tick is released, the enclave publishes:

  • The epoch ID (UUID)

  • The Merkle Root

  • The total ticks

  • The number of assets

This commitment is published on-chain to Solana so the commitment is timestamped by the blockchain and cannot be backdated.

This ordering is the heart of the guarantee: (1) the commitment is public before any randomness is revealed, and (2) before the external salt exists.

Solana Block Hash Salt

Crypta incorporates the latest Solana block hash to each new tick as the external and unpredictable salt.

This salt introduces independent entropy beyond the control of any party - including the Crypta team. It is combined with the pre-committed secret hash to generate price movements, ensuring that outcomes cannot be predicted or manipulated.

Solana produces a new block every ~400 ms meaning each new tick receives its own independent hash.

At tick t, the latest available Solana block hash (BHt​)is used as that tick's salt.

Provably Fair Entropy

The two hashes are combined with a keyed hash. The committed secret becomes the key; the public block hash becomes the message:

PFEasset,t=HMAC−SHA256(key=Easset,t, msg=BHt)PFE_{asset,t} = HMAC-SHA256(key=E_{asset,t}, \: msg=BH_t)
Party
What they control
Why they cannot manipulate

Crypta

The secret hash (Easset,t)

Committed to the Merkle root before BHt existed

Solana Validators

The public block hash (BHt)

Do not know E, so cannot predict the output

Everyone else

Neither

Can verify everything after each tick

A single bit changed anywhere in either input produces a completely unrelated 32-byte result.

Price Movement Generation

Each tick's 32-byte PFE output is converted into the random variables consumed by Crypta's price model.

Two separate portions of the PFE are used:

  1. Bytes 0:8 generate the normally distributed noise variable.

  2. Bytes 8:16 generate the Bernoulli jump indicator.

1

Extract Uniform Random values

  • The first 8 bytes of the PFE hash are read as big-endian unsigned 64-bit integer and normalised:

Ut=uint64(PFE[0:8])264−1U_t = \frac {uint64(PFE[0:8])} {2^{64}-1}
Ut=min⁡(1−ϵ,max⁡(ϵ,Ut))\boxed{ U_t= \min \left( 1-\epsilon, \max(\epsilon,U_t) \right) }
  • The result is clamped to (ε, 1 - ε) with ε=10-10, so its never exactly 0 or 1.

  • Eight bytes give roughly 1.8 × 10 19 distinct values — far more resolution than any price model requires.

2

Inverse Normal CDF

The uniform value is mapped to a standard normal distribution using the inverse normal CDF, computed via Acklam's rational approximation:

Zt=Φ−1(Ut)Z_t = \Phi^{-1}(U_t)

Zt is the noise term consumed by Crypta's price model.

3

Jump Indicator (Bernoulli Variable)

The next 8 bytes from the PFE hash determine whether each tick has an additional price jump based on a probability of triggering.

threshold=uint64⁡(p×264)\text{threshold} = \operatorname{uint64}(p \times 2^{64})
Bt={1if uint64⁡(PFE[8:16])<threshold0otherwiseB_t = \begin{cases} 1 & \text{if } \operatorname{uint64}(\mathrm{PFE}[8{:}16]) < \text{threshold} \\ 0 & \text{otherwise} \end{cases}
4

Price Movement (ABM)

The random variables are then applied to the synthetic asset's price based on the Arithmetic Brownian Motion (ABM) formula below. One movement per second.

Pt+1=Pt+μΔt⏟drift+σΔt Zt⏟noise−μΔtpBt⏟Bernoulli jumpP_{t+1} = P_t + \underbrace{\mu \Delta t}_{\text{drift}} + \underbrace{\sigma \sqrt{\Delta t}\, Z_t}_{\text{noise}} - \underbrace{\frac{\mu \Delta t}{p} B_t}_{\text{Bernoulli jump}}

Where:

  • Pt​ = current price

  • Pt+1​ = next tick's price

  • μ = drift parameter

  • σ = standard deviation

  • Zt​ = standard-normal noise

  • p = probability of a jump

  • Bt​ = Bernoulli jump indicator

  • Δt=1 second

Verifying Fairness

After each hash is used, it is immediately revealed to the public, along with the Merkle Proof allowing anyone to verify the results and that the hash is part of the original committed Merkle Root. This provides a constant stream of tamper-proof, time-released randomness.

Last updated