Skip to main content

True random numbers sourced from live cryptocurrency market data

Project description

coinrandom

한국어 | English

True random numbers sourced from live cryptocurrency market data.

import coinrandom

coinrandom.random()        # 0.7182818...
coinrandom.randint(1, 100) # 42
coinrandom.choice(["a", "b", "c"])

Why coinrandom?

Cryptocurrency markets trade 24/7 globally. At the tick level — individual trade prices, quantities, timestamps, and buyer/seller direction — the data is highly unpredictable. The Efficient Market Hypothesis (EMH) says no one can consistently predict short-term market movements. coinrandom uses this unpredictability as an entropy source.

Trust Model

Even with the full source code published, no one can predict the output in advance — because no one can predict the coin market.

This is an application of Kerckhoffs's principle: security depends on the unpredictability of the market, not on keeping the algorithm secret. Each value generated by Heavy/SuperHeavy comes with a RandomProof — a verifiable audit trail showing exactly which market data produced the result.

Honest limits: coinrandom provides computational security (like AES/RSA), not information-theoretic security (like Chainlink VRF). The trust model is economic, not mathematical. For cryptographic key generation, use secrets. For smart contract RNG, use Chainlink VRF.


Installation

pip install coinrandom                     # Light + Heavy
pip install "coinrandom[superheavy]"       # + SuperHeavy (numpy, scipy)

No API keys. No configuration.


Three Tiers

Tier Speed Entropy source Proof Use case
Light ~1ms Binance tick + Argon2 No High-volume generation
Heavy ~2s 3 exchanges + ETH + BTC block hash + Argon2 Yes Raffles, NFT mints, DAO votes
SuperHeavy ~30s Portfolio-optimized coins + Heavy pipeline (ETH + BTC) Yes Maximum entropy, auditable

All tiers return the same API — drop-in replacement for Python's random module.


Usage

Function Reference

Function Signature Description
random() () → float Uniform float in [0.0, 1.0)
uniform(a, b) (float, float) → float Uniform float in [a, b]
randint(a, b) (int, int) → int Uniform integer in [a, b] inclusive
choice(seq) (Sequence) → Any One random element from a sequence
choices(seq, k) (Sequence, int) → list k elements with replacement
sample(seq, k) (Sequence, int) → list k elements without replacement
shuffle(seq) (MutableSequence) → None In-place shuffle
gauss(mu, sigma) (float, float) → float Normal distribution sample
random_with_proof() () → RandomProof Heavy / SuperHeavy only — value + audit trail

All functions have async variants prefixed with a: arandom(), arandint(), arandom_with_proof(), etc.


Light (default)

import coinrandom

# Basic
coinrandom.random()                        # 0.7182818...  float in [0.0, 1.0)
coinrandom.uniform(1.5, 9.5)              # 6.234...      float in [a, b]
coinrandom.randint(1, 6)                  # 4             integer in [a, b] inclusive
coinrandom.gauss(mu=0.0, sigma=1.0)       # -0.312...     normal distribution

# Sequences
coinrandom.choice(["rock", "paper", "scissors"])   # pick one
coinrandom.choices(range(1, 7), k=5)               # roll dice 5 times (with replacement)
coinrandom.sample(range(1, 46), k=6)               # lotto numbers (no duplicates)

lst = list(range(1, 11))
coinrandom.shuffle(lst)                            # in-place shuffle

# Practical: raffle — pick 3 winners from participants
participants = ["Alice", "Bob", "Carol", "Dave", "Eve"]
winners = coinrandom.sample(participants, k=3)

# Practical: 5% probability event
if coinrandom.random() < 0.05:
    print("rare drop!")

Heavy — with proof

Each call fetches live data from 3 exchanges + ETH + BTC block hashes, then applies Argon2id. Returns a RandomProof with a full audit trail.

from coinrandom import heavy

# Simple usage — same API as Light
val = heavy.random()
n   = heavy.randint(1, 100)

# Practical: auditable raffle
participants = ["Alice", "Bob", "Carol", "Dave", "Eve"]
proof = heavy.random_with_proof()
winner = participants[int(proof.value * len(participants))]

print(winner)
print(proof.value)               # 0.3571428...
print(proof.block_hashes)        # {"ETH": "0xabc123...", "BTC": "000000000000..."}
print(proof.block_hashes["ETH"])
print(proof.block_hashes["BTC"])
print(proof.exchanges)           # [{"exchange": "binance", "symbol": "BTCUSDT", ...}, ...]
print(proof.final_hash)          # SHA-256 of the Argon2-stretched entropy
print(proof.timestamp)           # "2026-05-17T09:00:00.123456"

# NFT mint order — shuffle with proof
token_ids = list(range(1, 10001))
for _ in range(len(token_ids)):
    proof = heavy.random_with_proof()
    # use proof.value to drive each swap step, saving proofs for audit

SuperHeavy — portfolio-optimized entropy

Runs inverse Markowitz optimization to select the least-correlated coins as entropy sources before executing the Heavy pipeline.

from coinrandom import superheavy  # requires: pip install "coinrandom[superheavy]"

val   = superheavy.random()
proof = superheavy.random_with_proof()

print(proof.value)
print(proof.selected_symbols)       # coins selected by inverse portfolio optimization
print(proof.correlation_matrix)     # correlation matrix of candidates
print(proof.optimization_result)    # scipy SLSQP result
print(proof.block_hashes)           # {"ETH": "...", "BTC": "..."}
print(proof.final_hash)

Saving proof as JSON

RandomProof and SuperProof are plain dataclasses — serialize with the standard library:

import dataclasses, json

proof = heavy.random_with_proof()

with open("proof.json", "w") as f:
    json.dump(dataclasses.asdict(proof), f, indent=2)

Async API

All functions have async variants prefixed with a.

import asyncio
import coinrandom
from coinrandom import heavy, superheavy  # superheavy requires [superheavy] extra

async def main():
    # Light
    val = await coinrandom.arandom()
    n   = await coinrandom.arandint(1, 100)
    c   = await coinrandom.achoice(["a", "b", "c"])
    lst = [1, 2, 3]
    await coinrandom.ashuffle(lst)

    # Heavy
    val   = await heavy.arandom()
    proof = await heavy.arandom_with_proof()
    print(proof.block_hashes)

    # SuperHeavy
    val   = await superheavy.arandom()
    proof = await superheavy.arandom_with_proof()
    print(proof.selected_symbols)

asyncio.run(main())

Async methods offload blocking I/O to a thread pool via asyncio.run_in_executor — no new dependencies.


Design Principles

  1. No API keys — works out of the box with pip install
  2. Uniform API — every tier exposes the same functions as random
  3. No Mersenne Twister — custom HashDRBG (SHA-512 counter-based) seeded from coin market data and OS hardware entropy
  4. Open-source safe — Kerckhoffs's principle: publishing the algorithm doesn't compromise security
  5. Intentionally heavy — Heavy/SuperHeavy: each call runs the full entropy pipeline. "Slow = costly to manipulate."

Internals

coinrandom/
├── __init__.py          # Light tier as default API
├── core.py              # fetch_binance_entropy, mix_entropy
├── proof.py             # RandomProof, SuperProof dataclasses
├── light/               # HashDRBG + Argon2 (t=1, m=8MB) reseed cache
├── heavy/               # 3 exchanges parallel + ETH block hash + Argon2 (t=4, m=64MB)
└── superheavy/          # Inverse portfolio optimization → Heavy pipeline

HashDRBG

Custom SHA-512 counter-based DRBG. No import random anywhere in the codebase.

# Simplified
state = argon2(mix_entropy(coin_data, os.urandom(32)))
output = sha512(state + counter)  # per call

Manipulation resistance

Heavy mode requires simultaneously moving 32+ coins across Binance, Upbit, and Coinbase in the exact direction needed — estimated cost: billions of dollars. SuperHeavy additionally hides the target coins until optimization runs.


License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

coinrandom-1.1.0.tar.gz (16.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

coinrandom-1.1.0-py3-none-any.whl (17.8 kB view details)

Uploaded Python 3

File details

Details for the file coinrandom-1.1.0.tar.gz.

File metadata

  • Download URL: coinrandom-1.1.0.tar.gz
  • Upload date:
  • Size: 16.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for coinrandom-1.1.0.tar.gz
Algorithm Hash digest
SHA256 ce1c9395c5636c381a8c26028ab2c02956d505b6a576908f42596c4924e604a4
MD5 9d5b49e174c845f8ebe99ef539d613f5
BLAKE2b-256 88e954ff8a8f96c3e9a90844f4a585e3b485ae9e301888b87365308e55cd5091

See more details on using hashes here.

Provenance

The following attestation bundles were made for coinrandom-1.1.0.tar.gz:

Publisher: cd.yml on LETUED/coinrandom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file coinrandom-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: coinrandom-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for coinrandom-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bdc7e76148cce2b3eb506b5522b5a0c5f50d666d02da0c454bc7f1891aad7649
MD5 2a4caf1e35cddcbe863c74050d73e62b
BLAKE2b-256 d2ade2c319a930f821334e62d77007abdfea29b4799cb2b77386a9db70c82d3d

See more details on using hashes here.

Provenance

The following attestation bundles were made for coinrandom-1.1.0-py3-none-any.whl:

Publisher: cd.yml on LETUED/coinrandom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page